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

时间:2020-03-05 18:58:30  来源:igfitidea点击:

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

这对于调试很好,但是一旦我构建了发行版本,我真的不希望我的代码再引用单元测试框架。

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

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

解决方案

回答

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

是的,正如加里所说,它也迫使我们通过公共方法测试行为,而不是玩弄课堂的内幕。

回答

我一直将单元测试放在一个单独的项目中,以便将其编译为自己的程序集。

回答

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

例如。对于名为" Acme.BillingSystem.Utils"的程序集,将有一个名为" Acme.BillingSystem.Utils.Test"的测试程序集。

通过不运送该dll,将其从产品的运送版本中排除。

回答

我会建议一个单独的项目进行单元测试(还有更多的项目进行集成测试,功能测试等)。我曾尝试在同一项目中混合使用代码和测试,但发现与将它们分成单独的项目相比,它的可维护性要差得多。

维护并行名称空间以及对测试使用明智的命名约定(例如MyClass和MyClassTest)将有助于我们保持代码库的可维护性。

回答

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

回答

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

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

[assembly: InternalsVisibleTo("UnitTestProjectName")]

回答

我绝对同意其他所有人的观点,即应该将测试与生产代码分开。但是,如果我们坚持不这样做,则应定义一个称为TEST的条件组合常数,并使用

#if TEST
#endif

首先要确保测试代码不会在生产方案中编译。完成此操作后,我们应该能够从生产部署中排除测试dll,或者甚至更好(但需要更高的维护),创建用于生产的NAnt或者MSBuild,而无需参考测试dll进行编译。

回答

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

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

回答

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

相反的说法是:为什么要取消测试?为什么不提供测试?如果我们将测试与测试运行程序一起交付,则产品会提供一定程度的验收测试和自测。

我已经听到过几次这种说法,并对此进行了思考,但我个人仍然将测试保存在一个单独的项目中。

回答

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

回答

在文件中使用编译器指令或者创建单独的项目的另一种选择是,仅在项目中创建其他.cs文件。

在项目文件本身具有一些魔力的情况下,我们可以指示:

  • 仅在调试版本中引用nunit.framework DLL,并且
  • 测试文件仅包含在调试版本中

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

回答

还需要考虑的一件事是2005年之前的VisualStudio版本不允许从其他项目中引用EXE程序集项目。因此,如果我们在VS.NET中处理旧项目,则可以选择:

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

在这三个条件编译中,最不容易出错。

回答

如果#if(DEBUG)标记允许使用干净的"发行"版本,那么为什么需要一个单独的项目进行测试。 nunit LibarryA / B示例(是的,我知道它的示例)可以做到这一点。目前正在与方案进行角力。曾经使用过一个单独的项目,但这似乎可以提高生产力。仍然是胡敏(Hummin)和哈温(Hawin)。