【问题标题】:How to unit test WinForms with Visual Studio 2013 Ultimate?如何使用 Visual Studio 2013 Ultimate 对 WinForms 进行单元测试?
【发布时间】:2014-04-10 21:59:59
【问题描述】:

我从工具 | 添加扩展和更新:NUnit 测试适配器、NUnit 测试生成器、用于 Visual Studio 2012 和 2013 的 xUnit.net 运行器、单元测试生成器。

似乎只有单元测试生成器给了我一个上下文菜单项,允许我右键单击表单的类构造函数和“生成单元测试”。但是,当我右键单击同一项目中普通旧类的方法时,不会出现该上下文菜单项。如果我尝试为按钮单击或文本框选择生成单元测试,也不会出现该上下文方法,包括如果我从表单设计器代码(例如this.button1.Click += new System.EventHandler(this.button1_Click);)内的任何地方尝试它。这是为什么呢?

此外,虽然“生成单元测试”让我可以选择 MSTest、NUnit 和 XUnit,但只有 MSTest 有效。其他两个选项会创建新的测试项目而不是测试类,并生成一个长错误消息框:

未找到与约束匹配的导出:

合同名称

NuGet.VisualStudio.IVsPackageInstallerServices

RequiredTypeIdentity

NuGet.VisualStudio.IVsPackageInstallerServices

最后,生成的骨架 MSTest 方法没有显示访问表单及其控件的明显方法。这篇文章http://www.steveandrews.me/blog/2008/02/05/testing-the-winforms-ui 的作者显然在 2008 年使用了不同的 Visual Studio,他写道,生成的方法包含有助于访问表单的代码:

`[TestMethod()]
[DeploymentItem("WindowsFormsApplication1.exe")]
public void InitializeComponentTest()
{
    Form1_Accessor target = new Form1_Accessor(); // TODO: Initialize to an appropriate value
    target.InitializeComponent();
    Assert.Inconclusive("A method that does not return a value cannot be verified.");
}`

现在,有了 Visual Studio 2013 Ultimate 和 MSTest,我得到的只是:

[TestMethod()] public void Form1Test() { throw new NotImplementedException(); }

我在其他地方读到,如果想测试文本框选择和按钮单击等内容,则应该使用 MVVM 模式,但我想知道是否有一种“正确”的方法可以从 Visual Studio 内部对经典 WinForms 进行单元测试. (我显然对这一切都不熟悉!)

谢谢

【问题讨论】:

  • 很遗憾,我别无选择。但是,我确实回答了我自己的一个问题。我注意到我的普通旧类没有被宣布为公开,所以我这样做了,现在出现了“生成单元测试”右键菜单项。这也是事件处理程序等的问题。他们是私人的。

标签: c# winforms unit-testing visual-studio-2013


【解决方案1】:

对私有方法进行单元测试是一种不好的做法,就像将类设为内部并使用InternalsVisibleTo 属性以便您可以对其进行测试一样。

基本上,如果您有一个私有方法,则该方法代表您的类的实现细节——该方法的作用与您的测试工作无关。您应该测试的是您的类的公共 API。

“好吧,我想测试一些深藏在私有方法中的逻辑,但是很难将数据传递到我的公共 API 中,这会触及我私有方法中的所有逻辑!”,你可能会说。这是对我刚刚给出的建议的普遍回应,并且有一个答案:

难以通过公共 API 测试的逻辑通常表明您的类设计不佳。您需要开始将该类分解为多个较小的类,并通过它们的公共 API 测试每个这些类。

现在,最后一件事:您正在尝试测试 Windows 窗体。 WinForms 是古老的,甚至没有草率地尝试引导您走上使用现代模式和实践的道路,例如关注点分离。这意味着您通常会将大量视图逻辑与业务逻辑混合在一起,这使得单元测试变得更加困难。您可以考虑开始实施 MVP 模式。

【讨论】:

  • 这是个好建议,我刚刚开始研究从 vb6 转换为 c# 的旧版 win-forms 应用程序。我们已经为新的东西实现了一个 MVC 类型的架构,但是经过考虑它会更适合做 MVP,无论哪种方式都产生了很大的不同。
【解决方案2】:

其中使用的Accessors 已被弃用,并且不包含在 VS2012 及以后的版本中。

你不能再访问私人了。

您可以做的是使您的类成为内部类并使用InternalsVisibleTo Attribute 使您的单元测试程序集能够访问它们。

【讨论】:

    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多