C# 您是将单元测试放在同一个项目中还是另一个项目中?

C# 您是将单元测试放在同一个项目中还是另一个项目中?,c#,unit-testing,C#,Unit Testing,为了方便起见,您是将单元测试放在同一个项目中,还是将它们放在单独的程序集中 如果您像我们一样将它们放在一个单独的程序集中,那么我们在解决方案中会有许多额外的项目。在编写代码时进行单元测试非常好,但是如何在没有所有这些额外程序集的情况下发布应用程序?在我看来,单元测试应该与生产代码放在一个单独的程序集中。以下是将单元测试放置在与生产代码相同的程序集中的几个缺点: 单元测试附带生产代码。产品代码附带的唯一内容是生产代码 单元测试会使组件不必要地膨胀 单元测试可以影响构建过程,如自动构建或连续构建 我

为了方便起见,您是将单元测试放在同一个项目中,还是将它们放在单独的程序集中


如果您像我们一样将它们放在一个单独的程序集中,那么我们在解决方案中会有许多额外的项目。在编写代码时进行单元测试非常好,但是如何在没有所有这些额外程序集的情况下发布应用程序?

在我看来,单元测试应该与生产代码放在一个单独的程序集中。以下是将单元测试放置在与生产代码相同的程序集中的几个缺点:

  • 单元测试附带生产代码。产品代码附带的唯一内容是生产代码
  • 单元测试会使组件不必要地膨胀
  • 单元测试可以影响构建过程,如自动构建或连续构建 我真的不知道有什么专业人士。有一个额外的项目(或10个)不是骗局

    编辑:有关制造和装运的更多信息

    我进一步建议,任何自动构建过程都将生产和单元测试放在不同的位置。理想情况下,只有在生成代码并将产品文件复制到单元测试目录中时,单元测试构建过程才会运行。这样做会导致实际的位被分离出来以便装运等。此外,此时在特定目录中的所有测试上运行自动单元测试是相当简单的

    总而言之,以下是bits和其他文件的日常构建、测试和发布的总体思路:

  • 生产构建运行,将生产文件放入特定的“生产”目录。
  • 仅构建生产项目
  • 将编译后的位和其他文件复制到“生产”目录中
  • 将bits和其他文件复制到发行候选目录中,也就是圣诞节发行目录“Release20081225”
  • 如果生产构建成功,单元测试构建将运行。
  • 将生产代码复制到“tests”目录
  • 将单元测试构建到“tests”目录
  • 运行单元测试
  • 向开发人员发送生成通知和单元测试结果
  • 当一个候选版本(如Release20081225)被接受时,发送这些位

  • 我的单元测试总是在一个单独的项目中进行。事实上,对于我的解决方案中的每个项目,都有一个单独的测试项目。测试代码不是应用程序代码,不应与之混合。将它们保存在单独的项目中的一个优点是——至少使用TestDriven.Net——我可以右键单击一个测试项目并运行该项目中的所有测试,只需单击一下即可测试整个应用程序代码库。

    单独的项目,但使用相同的解决方案。(我曾经为测试和生产代码开发过不同解决方案的产品——这太可怕了。你总是在这两者之间切换。)

    单独项目的原因如其他人所述。请注意,如果您使用的是数据驱动测试,那么如果您将测试包括在生产程序集中,那么最终可能会导致大量的膨胀


    如果需要访问生产代码的内部成员,请使用。

    I在同一项目和不同项目之间波动

    如果您要发布一个库,那么发布带有生产代码的测试代码是一个问题,否则我发现它通常不是问题(尽管在您尝试之前有很强的心理障碍)


    当把测试放在同一个项目中时,我发现在测试和它们测试的代码之间切换更容易,重构/移动它们也更容易。

    我把它们放在不同的项目中。作为我们的一般规则,程序集的名称反映了名称空间的名称。因此,如果有一个名为Company.Product.Feature.sln的项目,它的输出(程序集名称)为Company.Product.Feature.dll。测试项目为Company.Product.Feature.Tests.sln,生成Company.Product.Feature.Tests.dll

    最好将它们保存在单个解决方案中,并通过Configuration Manager控制输出。我们为每个主要分支(开发、集成、生产)提供了一个命名配置,以代替使用默认的调试和发布。设置好配置后,可以通过单击Configuration Manager中的“Build”复选框来包括或排除配置。(要获得配置管理器,右键单击解决方案并转到配置管理器。)注意,我发现VisualStudio中的CM有时有缺陷。有几次,我不得不进入项目和/或解决方案文件,以清理它创建的目标

    此外,如果您正在使用Team Build(我确信其他.NET构建工具也是一样的),则可以将该构建与命名配置相关联。这意味着,例如,如果您不为“生产”构建构建构建单元测试,构建项目也可以知道此设置,而不会构建它们,因为它们被标记为这样


    此外,我们还经常从构建机器上下载XCopy。该脚本将忽略从部署中复制名为*.Tests.Dll的任何内容。这很简单,但很有效。

    我不理解使用生产代码部署测试的常见反对意见。我在一个小型的microcap上领导了一个团队(从14人增加到130人)。我们有六个左右的Java应用程序,我们发现将测试部署到现场并在表现出异常行为的特定机器上执行它们是非常有价值的。现场出现随机问题,能够以零成本对神秘进行数千次单元测试是非常宝贵的,通常在几分钟内就能诊断出问题…包括安装问题、不稳定的RAM问题、特定于机器的问题、不稳定的网络问题等,等等。我认为在现场进行测试是非常有价值的。此外,随机问题会在随机时间出现,联合国也很高兴
    public static class Ext
    {
         [TestCase(1.1, Result = 1)]
         [TestCase(0.9, Result = 1)]
         public static int ToRoundedInt(this double d)
         {
             return (int) Math.Round(d);
         }
    }
    
      <ItemGroup Condition="'$(Configuration)' == 'Release'">
        <Compile Remove="**\*.Tests.cs" />
      </ItemGroup>
      <ItemGroup Condition="'$(Configuration)' != 'Release'">
        <PackageReference Include="nunit" Version="3.11.0" />
        <PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
      </ItemGroup>
    
    "material-icon-theme.files.associations": {
      "*.Tests.cs": "test-jsx",
      "*.Mocks.cs": "merlin",
      "*.Interface.cs": "yaml",
    }