我正在为一些具有多个API版本的软件编写一个API包装器库,并且在多个平台之间进行大量共享调用,这些调用是同时开发的,但是是分开的。随着时间的推移,他们甚至已经合并了平台以使用相同的代码库,只是在不同的命名空间和& * .exe构建。
我这样做是通过编写一个代码库,然后通过构建配置使用预处理程序指令和条件编译符号来选择性地使用某些代码来构建。大约90%的代码可以在版本和平台之间重复使用,因此这很有用。所有这些都在被测项目结束时工作正常。
但是,我在使用NUnit& NCrunch对该项目进行单元测试。我创建了相同的构建配置来加载正确的常量并为Integration Test项目创建正确的构建文件夹。但是,我注意到两个奇怪的问题:
NUnit似乎忽略了Integration Test项目中的预处理程序指令。例如,在下面的示例中,无论配置如何(即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))
{
...
}
}
}
此外,似乎当我通过NCrunch运行测试时,它只使用与列出的第一个配置创建的构建相对应的* .dll(例如,它总是测试为Foo编译的* .dll .exe v16。
在我看来,这两个问题是相关的。我想知道NUnit和/或NCrunch是否无法处理这样的设置,或者是否有一种特殊方式我应该处理这种独特的设置?
我的更大问题是#2,这是NCrunch似乎只在第一个配置构建的* .dll上运行NUnit,这使得无法测试任何其他配置。也许这是项目依赖性的问题? (上面示例中的路径是通过API与我交互的程序,但不是我的* .dll项目。)
答案 0 :(得分:1)
当NCrunch运行时,生成的* .dll和确定的代码覆盖率(并逐步执行)不受Visual Studio中指定的当前配置的影响。它总是由Visual Studio加载项目时的项目默认配置决定。这意味着为了更改测试配置,您需要修改* .csproj文件。
例如,我有Foov16和Foov17的配置定义,如下所示。为了将项目设置为Foov17,使NCrunch工作,必须在默认配置(第一个元素)中引用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>
答案 1 :(得分:0)
不确定这对你有帮助吗?如果我理解正确,你想在测试用例中注入不同的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配置即可运行所有测试。
如果您仍想使用条件测试用例执行,则可以使用Category
或System.Diagnostics.Conditional
属性。有关其他信息,请参阅此stackoverflow link。
希望有所帮助。