在VS 2010中集成Silverlight单元测试?

7

我目前正在使用Silverlight单元测试框架,但我更喜欢直接在VS2010中运行测试。 我很想知道其他人使用的方法和工具。

我正在使用带有Prism和MVVM模式的Silverlight 4,并且我特别关注集成的Silverlight单元测试支持,以便我可以将其用于我的ViewModel单元测试。 我正在使用Unity进行依赖注入,并通过使用Moq for Silverlight来模拟调用我的WCF层中的调用来编写单元测试。 我目前甚至没有考虑集成测试,但即使在简单的单元测试中,测试单个ViewModel命令,对模拟服务层的服务请求可能需要大约50毫秒。 因此,对异步测试的支持对我很重要。

我在这里提出的问题与视图测试无关,过去我已经成功地使用System.Windows.Automation.Peers处理过视图测试,并且 - 尽管我还没有使用过它 - 现在可能可以更轻松地处理VS 2010 Feature Pack 2中的支持(从我所了解的情况来看,该支持似乎针对自动化/回放UI测试)。

我应该提到,我迄今为止查看和使用的产品的发现如下:

  • Silverlight单元测试框架-我目前正在使用这个,它非常棒,但是它的限制是(a)它没有与Visual Studio集成; (b)如果你不想运行所有测试,你只能使用简单的标签表达式过滤。
  • StatLight-非常好用。我目前正在使用它,并在以前的项目中针对Silverlight 3使用了自版本0.9。作为一个命令行工具,它可以与持续集成服务器集成 - 这肯定处理了另一个所需的场景。但是在开发过程中直接集成到Visual Studio是没有用的。
  • Silverlight的单元测试结果查看器(Visual Studio画廊上的Visual Studio扩展程序)-看起来很有前途,但它的限制是(a)当前无法找到位于解决方案文件夹中而不是在解决方案根目录下的项目; (b)通过StatLight运行给定程序集中的所有测试,似乎没有运行特定测试或一组测试的明显能力。
  • Einar Ingebrigtsen的Silverlight Unit Test Runner for ReSharper,后来成为Odin-领先于游戏(它最早出现在2008年),但是局限性在于似乎这个项目不再维护(最近的更新是2009年4月)。
  • AgUnit ReSharper插件(http://agunit.codeplex.com/)-最初看起来很好。下载它的源代码并构建最新的(修复错误的)版本以针对ReSharper 5.1工作后,我非常鼓舞人心。但不幸的是,它不能处理异步测试。这是线程的设计局限性,因此无论您是否尝试使用内置于Silverlight单元测试框架(Microsoft.Silverliht.Testing.SilverlightTest基类)中的异步支持,还是使用AutoResetEvent或任何其他内容都没有关系。该项目在CodePlex上的讨论论坛上协调员已经注意到了这一点。这是一个巨大的限制。
  • TestDriven.NET 3.0-乍一看似乎支持Silverlight 4.0测试,但限制(我怀疑)是Silverlight 4“程序集可移植性”(即在SL4和.NET 4之间可移植的5个依赖程序集)。当我尝试使用它进行简单的POC时,它肯定会导致我的VS 2010出现故障。

也许我错过了什么 - 我想知道社区中是否有更好的Silverlight单元测试方法?

5个回答

2

我使用Silverlight单元测试框架AgUnit和RX,配合模拟的IScheduler提供程序,使我的单元测试单线程运行 :)


有意思 - 我甚至没有考虑过使用 Rx,因为我不能在应用程序本身上使用它(在我工作的地方,它不在生产环境的批准技术列表上)。但事实证明,我可以潜在地仅针对单元测试使用 Rx,因为它们只会在开发工具和我们的构建服务器上执行。您的解决方案确实听起来非常优雅。您是否有任何示例代码,可以发布用于模拟 IScheduler,以便使您的单元测试单线程化? - Derek Novavi
谢谢。是的,这基本上是昨晚我得出的结论。希望我下一个项目能够商用 Rx,也许到时候我会采用你的想法!我仍然觉得 Microsoft 还没有为 Silverlight 提供更好的单元测试解决方案有点令人震惊,尽管 Silverlight 在 PDC 后的定位暗示着重于业务应用程序。最近似乎一直在 WP7 上全力以赴。既然 WP7 已经发布了,也许 Microsoft 最终会适当解决这个单元测试问题 :) - Derek Novavi
2
我也对Silverlight中的单元测试故事感到非常难过。Jetbrains应该介入 :) - Rob Fonseca-Ensor
很高兴不只有我一个人这样想 - 很难理解为什么更多的人没有对此大声疾呼。我同意 - JetBrains 应该接手这个问题,因为微软显然还没有表现出任何积极的迹象!不过我想在下周的 Silverlight Firestarter 活动中,ScottGu 有可能会在他的主题演讲中宣布一些相关消息 - 让我们拭目以待... - Derek Novavi

2

我是AgUnit插件的作者。

AgUnit阻止异步单元测试以加速测试运行。在底层,它使用与Silverlight Unit Test Framework测试运行器相同的代码,但如果您必须处理大量测试,则此运行器非常缓慢。我曾看到几千个测试之间几乎有半个小时和几分钟的差异。

话虽如此,如果您确实想进行异步测试,这是AgUnit的一个非常独立的部分。我会尝试创建一个禁用它的构建版本。将来,这将是一个配置选项或属性,我还没有决定。

如有任何问题或需求,请随时与我联系。


2

更新:

我已经决定使用StatLight作为我的持续集成服务器,但我正在寻找一种解决方案,使我能够在开发过程中直接在VS2010中运行异步Silverlight单元测试。

受Rob Fonseca-Ensor在本页面上的建议(请参见他的单独答案)的启发,我再次审视了这个问题。这让我找到了一个非Rx解决方案来解决使用AgUnit运行异步Silverlight单元测试的问题。

我认为我将使用的解决方案 - 至少是现在 - 是以下组合:

  • Silverlight单元测试框架
  • ReSharper 5.1
  • AgUnit ReSharper插件
  • [Mock async pattern]

我的ViewModels注入了专门的服务类,这些类提供了我(自动生成的)WCF服务引用类的抽象。为了帮助提供对WCF服务方法的访问,我的专门服务类还依赖于另一个常见的类,该类包装了async模式。对于我的单元测试,我已经使用Moq模拟了我的WCF服务引用类和我的专门服务类 - 但我没有考虑模拟我的async模式包装器类。

所以我决定也模拟我的async模式包装器类。这样做的吸引力在于,我认为我可能会能够在所有模拟中使用Rx和模拟的IScheduler(如Rob在他的答案中建议的那样),同时使我的真实类不包含任何对Rx的引用(这是一个要求,因为对于我正在工作的地方的这个项目,我需要将Rx排除在部署到生产环境的任何代码之外)。然而,一旦我模拟了包装器类,我意识到我甚至不需要Rx,而且还有一个更简单的解决方案 - 我应该真正看看它。它非常微不足道 - 我所需要做的就是模拟包装器类并确保它调用回调操作上的Invoke而不是调用BeginInvoke。这最终防止了在AgUnit中运行单元测试时在浏览器会话中正常工作的回调进入黑洞。(如果允许回调在使用AgUnit时进入黑洞,这当然将阻止单个测试正确完成,并可能导致超时或更糟糕的是测试结果的错误阳性。)

在没有任何后续答案提供更好建议的情况下,这似乎是我处理这种情况的最简单方法 - 允许我的异步单元测试在AgUnit中运行,而无需在我的生产代码中使用Rx。

对于任何其他不受公司强制限制的人部署使用Rx(仍然是DevLabs项目)到生产的代码,我认为Rob的解决方案绝对值得一看。


你有没有任何链接可以提供逐步指南来实现Silverlight应用程序的单元测试?我在谷歌上搜索后没有找到任何相关信息。 - shanavascet

0

你读过最近发布的 Visual Studio 2010 功能包2 吗?目前只对 MSDN 订阅者开放,且只支持某些版本的 VS2010(高级版、终极版和测试专业版)。

这里是一个快速概述:链接


谢谢你的指引。恰巧我正在使用VS2010专业版,所以我认为这对我不适用。但是,我确实已经了解了Feature Pack 2。所有关于它的介绍都倾向于特别提到UI测试,因此我认为它对我提出的问题没有任何帮助(正如我在问题中提到的,我只关心ViewModel测试,而不是View测试)。但如果有证据证明我错了,我会很高兴接受。您对Feature Pack 2如何帮助我直接在VS2010中运行异步ViewModel单元测试有什么具体的评论吗? - Derek Novavi

0
我通常在VS.NET中创建普通的单元测试项目,在引用中添加我的Silverlight程序集并编写单元测试类。
所以一切都可以开箱即用。这种解决方案有什么问题吗?

是的,我也看到其他人谈论使用这个解决方案。但除了纯粹主义者认为你的测试将在“完整”的.NET CLR而不是CoreCLR上运行你的Silverlight代码之外,这个解决方案是否限制了你可以在SL代码中引用的参考文献?如果您从非SL项目引用SL程序集,则会受到SL4的“程序集可移植性”功能的限制。在我的情况下,我的ViewModels引用Prism程序集。我很想知道您正在编写哪些部分的SL应用程序测试。 - Derek Novavi
你可能使用MVVM模式,所以在单元测试中测试的是ViewModel,它主要涉及数据访问、业务规则和INotifyPropertyChanged对象。在这种情况下使用的CLR层(特定于SL或完整的.NET)非常薄,并且已经由微软自己进行了充分的测试。 - Lex Lavnikov
是的,我确实使用MVVM - 我主要关注测试ViewModels(尽管还有其他类也需要测试,包括针对Views的健全性测试)。而且,ViewModels中使用的CLR非常薄。但我的观点是,ViewModels使用的引用不一定总是限于组件可移植性下允许的5个CLR程序集。Prism程序集的引用就是一个例子。即使不使用Prism,您也可能会使用System.Windows.dll中的ICommand。正如我所说,我很想知道您使用这种方法成功测试了什么? - Derek Novavi
5个CLR dlls + 无限数量的使用这些精美dlls(如Prism核心dlls)的dlls。但是我必须说,我们不使用Prism(我们使用更轻量级和更好的Caliburn.Micro版本),所以我的假设可能是错误的。 - Lex Lavnikov
有趣的是,直接或间接地在代码中引用超过5个允许的程序集并不会导致单元测试失败。问题更多地是来自那些程序集最终被调用的内容。因此,如果想要的话,可以使用常规(完整CLR)单元测试项目测试使用ICommand或DelegateCommand的代码。只有当做了一些愚蠢的事情(例如从ViewModel直接调用MessageBox.Show而不是注入消息服务依赖项)时,单元测试才会真正崩溃。 - Derek Novavi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接