但是,我发现虽然其中 400 个测试可以(按顺序)运行,但某些测试要么挂起 xUnit 运行程序,要么完全关闭它。
我不关心如果某些测试无法在Linux上运行,某些测试与DTC和一些我们不需要在那里支持的非托管guph有关。
然而,我真正想要的是对这些测试应用忽略,并在构建输出中正确标记测试被忽略的事实。
这个问题可以归结为我猜有一些可能的解决方案
如果我可以避免过多修改原始代码,那就太棒了,因为代码并不是我真正可以更改的,并且应用大量跨平台黑客可能不会太顺利。
XUnit v2.0 现已推出。它直接支持可跳过的测试。用途:
[Fact (Skip = "specific reason")]
我会避免外部化跳过测试(即配置/命令文件,如果可能的话)。这在某种程度上不利于使测试易于运行且值得信赖。当其他人开始参与时,在代码中忽略测试是最安全的方法。
我可以看到很多选项,这里有两个涉及修改现有代码。
在 VS 解决方案中,定义另一个配置来定义预编译器标志
MONOWIN
(只是为了明确表示它是一个标志,表示它用于在 Windows 上编译以在 Mono 上使用的代码)。
然后定义一个属性,该属性将使测试在为 Mono 编译时被忽略:
public class IgnoreOnMonoFactAttribute : FactAttribute {
#if MONOWIN
public IgnoreOnMonoFactAttribute() {
Skip = "Ignored on Mono";
}
#endif
}
实际上很难找到这种方法的任何优点,因为它涉及到对原始解决方案的模拟,并添加了另一个需要支持的确认。
这里有一个与选项1类似的解决方案,只不过不需要单独配置:
public class IgnoreOnMonoFactAttribute : FactAttribute {
public IgnoreOnMonoFactAttribute() {
if(IsRunningOnMono()) {
Skip = "Ignored on Mono";
}
}
/// <summary>
/// Determine if runtime is Mono.
/// Taken from http://stackoverflow.com/questions/721161
/// </summary>
/// <returns>True if being executed in Mono, false otherwise.</returns>
public static bool IsRunningOnMono() {
return Type.GetType("Mono.Runtime") != null;
}
}
[Fact]
和
[IgnoreOnMonoFact]
,则xUnit 运行程序将运行该方法两次。 (CodeRush 不会这样做,在这种情况下我假设 xUnit 是正确的)。这意味着任何测试方法都必须将
[Fact]
替换为 [IgnoreOnMonoFact]
CodeRush 测试运行程序仍然运行
[IgnoreOnMonoFact]
测试,但它确实忽略了 [Fact(Skip="reason")]
测试。我认为这是由于 CodeRush 反映了 xUnit,而不是在 xUnit 库的帮助下实际运行它。这与 xUnit runner 配合得很好。
现在有新选项了。
添加 Nuget 包 SkippableFact,它允许您使用
[SkippableFact]
代替 [Fact]
,并且您可以在测试中使用 Skip.<xyz>
在运行时动态跳过测试。
示例:
[SkippableFact]
public void SomeTestForWindowsOnly()
{
Skip.IfNot(Environment.IsWindows);
// Test Windows only functionality.
}
[Fact(Skip="reason")]
有效,但我更喜欢使用特征
[Fact, Trait("type","unit")]
public void MyUnitTest(){
// given
// when
// then
}
[Fact, Trait("type","http")]
public void MyHttpIntegrationTest(){
// given
// when do things over HTTP
// then
}
用法
dotnet test --filter type=unit
这可以防止我们的构建意外运行开发人员忘记跳过的集成测试,例如
[Fact(Skip="Integration")]
,但是它确实需要单元测试通过添加正确的特征来“选择加入”CI,这无疑不是很好。
多米尼克的解决方案通过以下代码对我有用:
[SkippableFact]
public void Get_WhenCall_ReturnsString()
{
// Arrange
Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
// Act
// Assert
}
添加到之前有关 SkippableFact 的答案:请注意,每个测试仍然是构造的 - 构造函数正在运行。
如果基类构造函数中有耗时的代码,另一种方法是将特定于环境的测试用例收集在合适的文件中,并在构造函数中运行环境检查:
if (!SupportsTemporalQueries())
throw new SkipException("This test class only runs in environments support temporal queries");
这可以大大加快测试运行速度。在我们的系统中,我们要么扩展“通用”基测试类(在所有环境中运行),要么扩展特定于环境的基测试类。我发现这比管道或其他解决方案中的过滤更容易维护。
这个问题现已在 1.8 中解决 - 您可以根据特征进行过滤。请参阅此问题日志。
更新:特征适用于控制台运行程序,但不适用于 MSBuild,我添加了此支持的功能请求。