我可以使用 NUnit 和 NCrunch 通过预处理器指令测试多个构建配置吗?

Can I Use NUnit & NCrunch to Test Multiple Build Configurations with Preprocessor Directives?

我正在为 API 的一些软件编写一个包装器库,这些软件具有 API 的多个版本,并且多个平台之间的大量共享调用是同时但单独开发的。随着时间的推移,他们甚至一直在合并平台以使用相同的代码库,只是在不同的命名空间和 *.exe 构建下。

我通过编写一个代码库,然后通过构建配置使用预处理器指令和条件编译符号来选择性地使用某些代码进行构建。大约 90% 的代码实际上可以在版本和平台之间重用,所以这很有帮助。待测项目端一切正常

但是,我在使用 NUnit 和 NC运行ch 对该项目进行单元测试时遇到问题。我创建了相同的构建配置来加载正确的常量并为集成测试项目创建正确的构建文件夹。但是,我注意到两个奇怪的问题:

  1. NUnit 似乎忽略了集成测试项目中的预处理器指令。例如,在下面的示例中,无论配置如何(例如 BUILD_Bar_2015=true),第一行代码总是命中 (BUILD_Foov16=true),即使在 Visual Studio 中看起来是所需的行集(对应于当前配置变量)是唯一一个活动的:

    [TestFixture]
    public class FooBarIncApplicationTests
    {
       #if BUILD_Foov16
            public const string path = @"C:\Program Files (x86)\FooBarInc\FooV16\Foo.exe";
       #elif BUILD_Foov17
            public const string path = @"C:\Program Files (x86)\FooBarInc\FooV17\Foo.exe";
       #elif BUILD_Bar_2013
            public const string path = @"C:\Program Files (x86)\FooBarInc\Bar 2013\Bar.exe";
       #elif BUILD_Bar_2015
            public const string path = @"C:\Program Files (x86)\FooBarInc\Bar 2015\Bar.exe";
       #endif
    
       [Test]
       public void FooBarIncApplication_Initialize_New_Instance_Defaults()
       {
          using (FooBarIncApplication app = new FooBarIncApplication(path))
          {
          ...
          }
       }
    }
    
  2. 此外,我运行通过NC运行ch进行测试时,似乎只使用了第一个配置创建的build对应的*.dll列出(例如,它总是测试为 Foo.exe v16.

  3. 编译的 *.dll

在我看来,这两个问题是相关的。我想知道 NUnit and/or NC运行ch 是否无法处理这样的设置,或者是否有一种特殊的方式我应该处理这种独特的设置?

我更大的问题是#2,即 NC运行ch 似乎 运行ning NUnit 仅在从第一个配置构建的 *.dll 上,这使得无法测试任何其他配置。也许这是项目依赖性的问题? (上面示例中的路径是我通过 API 与之交互的程序,而不是我的 *.dll 项目。)

不确定是否对您有帮助。如果我理解正确的话,您想在测试用例中注入不同的 exe 路径,并让每个 exe 路径的测试用例 运行。您可以尝试为此使用 NUnits TestCase 属性。来自 NUnit 网站的示例:

   [TestCase(12,3,4)]
   [TestCase(12,2,6)]
   [TestCase(12,4,3)]
   public void DivideTest(int n, int d, int q)
   {
     Assert.AreEqual( q, n / d );
   }

基于此,您可以将测试重写为:

[TestCase(@"C:\Program Files (x86)\FooBarInc\FooV16\Foo.exe")]
[TestCase(@"C:\Program Files (x86)\FooBarInc\FooV17\Foo.exe")]
public void FooBarIncApplication_Initialize_New_Instance_Defaults(string path)
{
    using (FooBarIncApplicatio app = new FooBarIncApplicatio(path))
    {
    ...
    }
 }

基于此,测试用例将 运行 使用您的 exe 版本 16 和版本 17。额外的好处:您不必将 VS 配置切换到 运行 所有测试。

如果您仍想使用条件测试用例执行,您可以使用 CategorySystem.Diagnostics.Conditional 属性。请参阅此 Whosebug link 了解更多信息。

希望对您有所帮助。

好的,我找到问题所在了。如果您曾经为多个 DLL 构建配置测试 NCrunch,这值得了解!

当 NCrunch 运行时,生成的 *.dll 和确定(并单步执行)的代码覆盖率不受 Visual Studio 中指定的当前配置的影响。它始终由 Visual Studio 加载项目时的项目默认配置决定。这意味着为了更改配置以进行测试,您需要修改 *.csproj 文件。

例如,我有如下所示的 Foov16 和 Foov17 的配置定义。为了以 NCrunch 可以工作的方式将项目设置为 Foov17,必须在默认配置(第一个元素)中引用 Foov17 的配置:

<PropertyGroup>
   <Configuration Condition=" '$(Configuration)' == '' ">Debug-Foov17</Configuration>
   <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
   <ProjectGuid>{...}</ProjectGuid>
   <OutputType>Library</OutputType>
   <AppDesignerFolder>Properties</AppDesignerFolder>
   <RootNamespace>FooBarInc.API</RootNamespace>
   <AssemblyName>FooBarInc.API</AssemblyName>
   <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
   <FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-Foov16|AnyCPU'">
   <DebugSymbols>true</DebugSymbols>
   <OutputPath>bin\AnyCPU\Debug-Foov16\</OutputPath>
   <DefineConstants>TRACE;DEBUG;BUILD_Foov16</DefineConstants>
   <DebugType>full</DebugType>
   <PlatformTarget>AnyCPU</PlatformTarget>
   <ErrorReport>prompt</ErrorReport>
   <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   <DocumentationFile>bin\AnyCPU\Debug-Foov16\FooBarInc.API.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-Foov17|AnyCPU'">
   <DebugSymbols>true</DebugSymbols>
   <OutputPath>bin\AnyCPU\Debug-Foov17\</OutputPath>
   <DefineConstants>TRACE;DEBUG;BUILD_Foov17</DefineConstants>
   <DebugType>full</DebugType>
   <PlatformTarget>AnyCPU</PlatformTarget>
   <ErrorReport>prompt</ErrorReport
   <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   <DocumentationFile>bin\AnyCPU\Debug-Foov17\FooBarInc.API.XML</DocumentationFile>
</PropertyGroup>