2008-09-17 83 views
22

您通常会如何分离您的代码库和相关的单元测试?我知道那些为单元测试创​​建单独项目的人,我个人觉得这些项目令人困惑,难以维护。另一方面,如果你在单个项目中混淆了代码和测试,那么最终会得到与你的单元测试框架(无论是NUnit,MbUnit还是其他)相关的二进制文件和你自己的二进制代码。C# - 不包括项目发布版本中的单元测试

这是很好调试,但一旦我建立一个发行版本,我真的不希望我的代码参考单元测试框架了。

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

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

回答

40

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

是的,作为Gary说,这也迫使你通过public方法测试的行为,而不是你的类的内脏

+3

这也迫使你通过公开的方法来测试行为,而不是玩你的课堂内部。双奖金IMO。 – 2008-09-17 10:46:49

+0

我会推荐一个不同的文件夹结构。 ProjName \ Code \ SubPackage和ProjName \ Tests \ SubPackage。 – Gishu 2008-09-17 11:16:58

1

我一直保持我的单元测试,在一个单独的项目,所以它编译打约它是自己的组装。

2

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

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

通过不运送该DLL从您的产品的运输版本中排除它。

3

我会推荐单元测试的单独项目(还有更多项目用于集成测试,功能测试等)。我曾尝试在同一个项目中混合使用代码和测试,发现它比将它们分离为单独的项目要少得多。

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

10

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

19

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

有一点要记住,如果你想用'internal'访问器来测试类和方法,那就是将以下行添加到AssemblyInfo中。cs文件为每个项目进行测试:

[assembly: InternalsVisibleTo("UnitTestProjectName")] 
0

我绝对同意其他人你应该分开你的生产代码的测试。如果你坚持不,但是,你应该定义一个名为TEST条件comiplation常数,包你所有的单元测试类的用

#if TEST 
#endif 

首先要保证测试代码不生产方案编制。一旦完成,您应该能够从生产部署中排除测试dll,或者甚至更好(但更高的维护),创建一个NAnt或MSBuild用于在没有引用测试dll的情况下编译的生产。

2

只要你的测试是在一个单独的项目中,测试可以引用代码库,但代码库永远不必引用测试。我必须问,维持两个项目有什么困惑?您可以将它们保留在组织的相同解决方案中。

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

0

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

相反的观点是:你为什么要考试?为什么不交付测试?如果您与测试运行人员一起交付测试,则您的产品随附一定级别的验收测试和自测。

我已经多次听到过这个说法并且考虑过了,但是我个人仍然在一个单独的项目中进行测试。

2

我把测试放在一个单独的项目中,但在相同的解决方案。当然,在大型解决方案中可能会有很多项目,但解决方案资源管理器足以将它们分开,如果您给出所有合理的名称,我并不认为这是一个问题。

6

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

与项目文件本身的一些魔法,你可以决定了:

  1. nunit.framework DLL是仅在调试版本参考,并
  2. 测试文件仅包含在调试版本

例.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> 
1

一件事还有待考虑到2005年之前的VisualStudio版本不允许从其他项目引用EXE程序集项目。因此,如果您正在VS.NET中处理遗留项目,您的选择是:

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

这三个条件编译是最不容易出错的。

0

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