如何在解决方案中的 Visual Studio 中运行所有 NUnit 测试






3.93/5 (6投票s)
一篇关于在构建后始终运行所有 NUnit 测试的文章。
引言
NUnit 是一款出色的软件,它极大地提高了全球 .NET 代码的质量。
但是,我认为它存在一个小可用性问题,即当您想从 Visual Studio 运行解决方案中的所有测试时,您必须手动设置一个 NUnit 项目文件才能做到这一点。这可能很麻烦,尤其是当您向解决方案添加或删除项目时。
在进行测试驱动开发时,我们通常遵循以下步骤:
- 编写一些代码。
- 编译。
- 运行所有测试。
理想情况下,我们希望第三步在第二步之后自动发生,如下所示:
- 编写一些代码。
- 编译并自动运行所有测试。
我编写了这个插件来实现这一点。当一个项目被构建时,它会检查该项目是否引用了“nunit.framework”。如果是,那么我们假设这是一个包含单元测试的测试项目,并且会记住构建的 DLL 路径。在完整构建完成后,将创建一个包含这些路径的 NUnit 项目文件。任何现有的 NUnit GUI 进程都会被终止,然后使用创建的项目文件启动一个新的 NUnit GUI 进程。新进程将运行测试。
这种方法具有以下优点:
- 您只需按 Ctrl+Shift+B 即可编译您的项目并运行任何单元测试。
- 测试是使用为 nunit.framework 设计的 GUI 测试运行程序运行的。这意味着您拥有完整的源代码、代码的单元测试以及庞大的社区支持。
- 无需自己处理 NUnit 项目文件。
- 无需为具有相同功能的商业插件付费(但可能存在错误!),因为您没有源代码。
一个限制是您的项目文件夹必须位于同一个根目录下,即,您可以在“c:\”驱动器或“d:\”驱动器上分别拥有解决方案,但不能在同一个解决方案中同时混合“c:\”和“d:\”驱动器。这是 NUnit 项目的一个普遍限制。
背景
有关 NUnit 的更多信息,您可以阅读 NUnit 文档。
有关 Visual Studio 可扩展性的更多信息,您可以查看 LineCounter 项目,或我在此网站上的文章“Improving Code Auto Completion in C#”。
安装
将演示文件解压到某个文件夹。将“Jonno Nunit Helper.AddIn”文件移动到“your path\My Documents\Visual Studio 2008\Addins”文件夹。打开文件并更改以下行,使其指向 Jonno.AddIns.NunitHelper.dll 文件的位置。
<Assembly>C:\JonnoTest\Jonno.AddIns.NunitHelper.dll</Assembly>
如果您正在运行源代码,那么“Jonno Nunit helper.AddIn”文件可能不存在。将其添加到插件项目中,确保将其链接到插件文件夹中的版本,而不是添加它。
如果您想运行单元测试,您需要 Nunit 2.5 和 Rhino Mocks 3.6。我只在 Visual Studio 2008 上测试过。我大部分时间都在 C# 项目上进行了测试,但也遇到了 VB.NET 项目。我认为该插件对这两种语言都同样有效,没有理由不这样。
Using the Code
Connect
类处理我们需要的 Visual Studio 事件。我们需要在 OnConnection
方法中挂钩到我们需要的构建事件,即 OnBuildBegin
、OnBuildDone
和 OnBuildProjConfigDone
,如下所示:
var events = this.ApplicationObject.Events as Events2;
if (events == null)
{
return;
}
this.BuildEvents = events.BuildEvents;
this.BuildEvents.OnBuildBegin += this.OnBuildBegin;
this.BuildEvents.OnBuildDone += this.OnBuildDone;
this.BuildEvents.OnBuildProjConfigDone += this.OnBuildProjConfigDone;
当然,我们需要在 OnDisconnection
方法中取消挂钩这些事件。
if (this.BuildEvents != null)
{
this.BuildEvents.OnBuildBegin -= this.OnBuildBegin;
this.BuildEvents.OnBuildDone -= this.OnBuildDone;
this.BuildEvents.OnBuildProjConfigDone -= this.OnBuildProjConfigDone;
}
OnBuildBegin
方法然后简单地初始化一个我们感兴趣的项目路径的新列表。
this.NunitProjectNames = new List<string>();
OnBuildProjConfigDone
方法在每个项目构建完成后运行。如果构建不成功,我们会取消整个构建。如果成功,我们会使用名称找到刚刚构建的项目。
var projects = this.ApplicationObject.Solution.Projects;
foreach (Project project in projects)
{
if (builtName == project.Name)
{
return (VSProject2)project.Object;
}
}
然后我们检查引用,看是否设置了对“nunit.framework”的引用。如果是,我们使用项目的输出路径(使用“bin\Debug”的默认值)构造构建的 DLL 的路径,并将其存储在列表中。
foreach (Reference reference in envProject.References)
{
if (reference.Name != "nunit.framework")
{
continue;
}
var fullName = envProject.Project.FullName;
var outPutPath = "bin"
+ System.IO.Path.DirectorySeparatorChar
+ projectConfig
+ System.IO.Path.DirectorySeparatorChar;
foreach (Configuration s in envProject.Project.ConfigurationManager)
{
if (s.ConfigurationName != projectConfig)
{
continue;
}
outPutPath = s.Properties.Item("OutputPath").Value.ToString();
break;
}
this.NunitProjectNames.Add(this.Logic.GetBuiltAssemblysPath(fullName, outPutPath));
break;
}
OnBuildDone
方法在构建成功完成后运行。它调用创建 NUnit 项目文件的逻辑,并终止/启动 NUnit 进程。
以上大部分逻辑已放入 Logic
类中,该类还负责任何字符串操作。
ConcreteProcess
类通过调用框架 System.Diagnostics
类来处理终止或启动 NUnit 进程的实际工作。
关注点
上面概述的代码存在一个问题,即如果我们启动一个测试项目来调试一个测试,将会出现两个 NUnit GUI 实例!为了解决这个问题,我还必须添加 Debug.Start
命令的处理程序,该命令会删除构建事件的处理程序,从而禁用该代码。然后,当您退出调试模式时,构建事件会重新连接。
历史
- 2009 年 9 月 22 日:初始版本。