C# 单元测试和代码位于同一文件夹中:从编译的二进制文件中删除测试

Mik*_*ain 4 .net c# unit-testing intermediate-language roslyn

我已阅读“您将单元测试放在同一个项目还是另一个项目中吗?”的答案。当时(大约 10 年前)的共识是将单元测试放在与正在测试的代码不同的项目中。给出的主要原因是避免部署非生产代码,这是相当合理的。

从那时起,事情发生了很大变化,至少对于基于 JavaScript 的项目来说,在代码旁边进行测试是常态,而且实际上大多数人认为这是非常可取的。但我不会在这里讨论优点,因为这不是这个问题的目的。

假设我们对 C# 想要同样的东西,但仍然避免将测试代码部署到产品中,那么我们是否可以在 IL 级别编织一些编译后魔法,以在构建过程中从二进制文件中删除测试?例如,我们可以使用该[TestFixture]属性搜索并销毁二进制文件中的所有类吗?

我们可以利用 Roslyn 的某些功能来实现同样的目的吗?

或者,我们还可以采取其他方法吗?

Nig*_*888 6

一种选择是使用MSBuild 条件从最终构建中排除测试文件。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFrameworks>netstandard2.0</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup>
    <Compile Condition=" '$(Configuration)' == 'Release' " Remove="Test\**\*.cs" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

这一切都可以通过使用 glob 的单个语句来完成,这比必须#if DEBUG在每个测试文件中放置一个语句更简单。

当然,这意味着您需要在测试后再次构建才能应用条件编译,这实际上意味着模式中应用的更改Release未经测试。由于未测试浮点舍入错误和其他编译器优化,因此您可能会错过测试中的一些重要内容。

注意:与 JavaScript 中的情况不同,.NET 中非常希望将测试代码与生产代码分开,这样您就不必在部署之前重新编译,从而有效地否定您可能已完成的任何测试。