C# - 从项目的发布版本中排除单元测试

时间:2008-09-17 10:22:48

标签: c# .net unit-testing assemblies reference

您通常如何分离代码库和相关的单元测试?我知道有人为单元测试创​​建了一个单独的项目,我个人觉得这个项目令人困惑且难以维护。另一方面,如果将代码及其测试混合在一个项目中,最终会得到与单元测试框架相关的二进制文件(无论是NUnit,MbUnit还是其他任何东西)和你自己的二进制文件。

这适用于调试,但是一旦我构建发布版本,我真的不希望我的代码再引用单元测试框架

我找到的一个解决方案是将所有单元测试都包含在#if DEBUG - #endif指令中:当没有代码引用单元测试程序集时,编译器足够聪明,可以省略编译代码中的引用。

是否还有其他(可能更舒适)的选择来实现类似的目标?

13 个答案:

答案 0 :(得分:42)

我绝对主张将您的测试分离到单独的项目中。这是我认为的唯一方法。

是的,正如Gary所说,它也会迫使你通过公共方法测试行为而不是玩你班级内部的行为

答案 1 :(得分:20)

正如其他人指出的那样,一个单独的测试项目(针对每个正常项目)是一个很好的方法。我通常镜像命名空间并为每个普通类创建一个测试类,并在名称后附加'test'。如果您拥有可以在另一个项目中自动生成测试类和方法的Visual Studio Team System,则可直接在IDE中支持。

如果要使用“内部”访问器测试类和方法,需要记住的一件事是将以下行添加到要测试的每个项目的AssemblyInfo.cs文件中:

[assembly: InternalsVisibleTo("UnitTestProjectName")]

答案 2 :(得分:10)

v2之后的.Net框架有一个有用的功能,您可以使用InternalsVisibleTo属性标记一个程序集,该属性允许另一个组件访问该程序集。
一种装配隧道功能。

答案 3 :(得分:7)

在文件中使用编译器指令或创建单独项目的另一种方法是在项目中创建额外的.cs文件。

在项目文件本身中有一些魔力,你可以指示:

  1. nunit.framework DLL仅在调试版本中引用,
  2. 您的测试文件仅包含在调试版本中
  3. 示例.csproj摘录:

    <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
    
       ...
    
       <Reference Include="nunit.framework" Condition=" '$(Configuration)'=='Debug' ">
          <SpecificVersion>False</SpecificVersion>
          <HintPath>..\..\debug\nunit.framework.dll</HintPath>
       </Reference>
    
       ...
    
       <Compile Include="Test\ClassTest.cs" Condition=" '$(Configuration)'=='Debug' " />
    
       ...
    </Project>
    

答案 4 :(得分:3)

我建议单独的项目进行单元测试(还有更多项目用于集成测试,功能测试等)。我尝试在同一个项目中混合代码和测试,发现它比将它们分成单独的项目更难维护。

维护并行命名空间并对测试使用合理的命名约定(例如MyClass和MyClassTest)将帮助您保持代码库的可维护性。

答案 5 :(得分:2)

对于每个项目,都有一个相应的.Test项目,其中包含测试。

E.g。对于名为“Acme.BillingSystem.Utils”的程序集,会有一个名为“Acme.BillingSystem.Utils.Test”的测试程序集。

不发货,请将其从产品的发货版本中排除。

答案 6 :(得分:2)

只要您的测试位于单独的项目中,测试就可以引用代码库,但代码库从不必参考测试。我不得不问,维护两个项目有什么困惑?您可以将它们保存在相同的组织解决方案中。

当然,复杂的部分是企业在解决方案中有55个项目,其中60%是测试。算你自己幸运。

答案 7 :(得分:2)

我将测试放在一个单独的项目中但是在同一个解决方案中。当然,在大型解决方案中可能会有很多项目,但解决方案资源管理器在分离它们方面已经足够好了,如果你给出了所有合理的名称,我真的不认为这是一个问题。

答案 8 :(得分:1)

我总是将我的单元测试保存在一个单独的项目中,以便编译成自己的程序集。

答案 9 :(得分:1)

尚未考虑的一件事是2005年之前的VisualStudio版本不允许从其他项目引用EXE组装项目。因此,如果您正在使用VS.NET中的遗留项目,那么您的选项将是:

  • 将单元测试放在同一个项目中,并使用条件编译将它们从发布版本中排除。
  • 将所有内容移动到dll程序集,这样您的exe就只是一个入口点。
  • 通过在文本编辑器中黑客攻击项目文件来规避IDE。

三个条件编译中最容易出错。

答案 10 :(得分:0)

我绝对同意其他人的意见,你应该将测试与生产代码分开。但是,如果你坚持不这样做,你应该定义一个名为TEST的条件编辑常量,并用

包装所有的单元测试类。
#if TEST
#endif

首先确保测试代码不在生产场景中编译。完成后,您应该能够从生产部署中排除测试dll,或者甚至更好(但更高的维护),为生产创建一个NAnt或MSBuild,在没有引用测试dll的情况下进行编译。

答案 11 :(得分:0)

我总是创建一个单独编译的独立Acme.Stuff.Test项目。

相反的论点是:你为什么要把测试拿出来?为什么不提供测试?如果您将测试与测试运行器一起交付,则您需要对产品进行一定程度的验收测试和自检。

我已经听过几次这个论点并考虑过它,但我个人仍然在一个单独的项目中进行测试。

答案 12 :(得分:0)

如果 #if(DEBUG)标签允许使用干净的“发布”版本,为什么还需要一个单独的测试项目。 nunit LibarryA / B的例子(是的,我知道它的一个例子)这样做。目前正在与场景搏斗。曾经使用过一个单独的项目,但这似乎可以提高生产力。还是hummin和hawin。