【问题标题】:C# - Excluding unit tests from the release version of your projectC# - 从项目的发布版本中排除单元测试
【发布时间】:2010-09-10 01:18:26
【问题描述】:

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          【解决方案4】:

          在文件中使用编译器指令或创建单独项目的另一种替代方法是仅在项目中创建额外的 .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>
          

          【讨论】:

            【解决方案5】:

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

            【讨论】:

              【解决方案6】:

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

              相反的论点是:为什么要进行测试?为什么不交付测试?如果您与测试运行程序一起交付测试,您将获得与产品一起交付的某种程度的验收测试和自测。

              我已经多次听到这个论点并考虑过,但我个人仍然将测试保存在一个单独的项目中。

              【讨论】:

                【解决方案7】:

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

                是的,正如Gary 所说,它还迫使您通过公共方法测试行为,而不是玩弄类的内部结构

                【讨论】:

                • 它还迫使您通过公共方法测试行为,而不是玩弄类的内部结构。双倍奖金imo。
                • 我也推荐一个不同的文件夹结构。 ProjName\Code\SubPackage 和 ProjName\Tests\SubPackage.
                • 如果需要白盒测试怎么办?
                • 您可以使用 [InternalsVisibleTo] 属性让您的测试项目查看内部方法。
                【解决方案8】:

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

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

                【讨论】:

                  【解决方案9】:

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

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

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

                  【讨论】:

                    【解决方案10】:

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

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

                    [assembly: InternalsVisibleTo("UnitTestProjectName")]
                    

                    【讨论】:

                    • 也谢谢!这意味着我们可以停止为了测试而公开事情! :D
                    • 如果您对程序集进行强命名(如您所愿),那么您还需要将公钥长字符串添加到声明中。注意:强命名不能防止第三方链接到内部,因为它们仍然可以通过反射访问。
                    【解决方案11】:

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

                    【讨论】:

                      【解决方案12】:

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

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

                      【讨论】:

                        【解决方案13】:

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

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2010-10-12
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多