如何根据当前平台跳过 xUnit 中的特定测试
Posted
技术标签:
【中文标题】如何根据当前平台跳过 xUnit 中的特定测试【英文标题】:How do I skip specific tests in xUnit based on current platform 【发布时间】:2011-05-24 04:59:41 【问题描述】: 我有一个在 Windows 上构建的程序集 我想在 Linux 的单声道上运行 xUnit 测试。但是,我发现虽然其中 400 个测试可以运行(按顺序),但某些测试要么挂起 xUnit 运行器,要么完全停止运行。
如果某些测试无法在 Linux 上运行,我不关心,某些测试与 DTC 和一些我们不需要在那里支持的非托管口香糖有关。 p>
然而,我想要的是对这些测试应用忽略,并在构建输出中正确标记测试被忽略的事实。
这个问题可以归结为我猜有很多可能的解决方案
如何通过控制台运行程序在 xUnit 中运行特定测试? (我还没有找到这方面的文档,也许我只是不够努力) 是否可以反过来说“这是一个程序集,不过请忽略这些特定测试” 建议在这些测试上设置一个属性是一种更好的方法,正式记录这些测试是特定于平台的 - 这可能吗?如果我能避免过多地修改原始代码,那就太好了,因为代码并不是我真正可以更改的,而且应用大量跨平台的黑客攻击可能不会太顺利。
【问题讨论】:
【参考方案1】:XUnit v2.0 现已推出。它直接支持可跳过的测试。使用:
[Fact (Skip = "specific reason")]
【讨论】:
如果您出于同样的原因需要对多个测试应用跳过,那么没有什么能阻止Skip
字符串成为常量。干燥,更容易被发现等。
请注意,这也适用于参数化测试[Theory (Skip = "reason")]
【参考方案2】:
我会避免外部化跳过测试(即,如果可能的话,一个配置/命令文件)。这在某种程度上不利于使测试易于运行和值得信赖。当其他人开始参与时,在代码中忽略测试是最安全的方法。
我可以看到很多选项,这里有两个涉及修改现有代码。
选项 1 - 最具侵入性的编译时平台检测
在 VS 解决方案中,定义另一个配置,该配置定义了预编译器标志 MONOWIN
(只是为了明确表示它是用于在 Windows 上编译以在 Mono 上使用的代码的标志)。
然后定义一个属性,在为 Mono 编译时将忽略该测试:
public class IgnoreOnMonoFactAttribute : FactAttribute
#if MONOWIN
public IgnoreOnMonoFactAttribute()
Skip = "Ignored on Mono";
#endif
实际上很难找到这种方法的任何优势,因为它涉及模拟原始解决方案并添加另一个需要支持的确认。
选项 2 - 有点侵入性 - 运行时平台检测
这里是与option1类似的解决方案,只是不需要单独配置:
public class IgnoreOnMonoFactAttribute : FactAttribute
public IgnoreOnMonoFactAttribute()
if(IsRunningOnMono())
Skip = "Ignored on Mono";
/// <summary>
/// Determine if runtime is Mono.
/// Taken from http://***.com/questions/721161
/// </summary>
/// <returns>True if being executed in Mono, false otherwise.</returns>
public static bool IsRunningOnMono()
return Type.GetType("Mono.Runtime") != null;
注 1
如果一个方法被标记为[Fact]
和[IgnoreOnMonoFact]
,xUnit runner 将运行两次。 (CodeRush 不这样做,在这种情况下,我假设 xUnit 是正确的)。这意味着任何测试方法都必须将[Fact]
替换为[IgnoreOnMonoFact]
注2
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.
【讨论】:
精美包装! 感谢这个伟大的包裹。遗憾的是,标准库中没有包含这样的基本功能。【参考方案4】:这将是对特征的理想使用,但不幸的是,命令行和 xml 项目文件都不支持基于特征的过滤。值得为此向 codeplex 站点添加一个问题。
【讨论】:
【参考方案5】:[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,这当然不是很好。
【讨论】:
【参考方案6】:现在在 1.8 中解决了这个问题 - 您可以过滤 Traits。看到这个issue log。
更新:Traits 适用于控制台运行程序,但不适用于 MSBuild,我已添加对此支持的功能请求。
【讨论】:
如果这个答案实际上包含更多信息,而不仅仅是一个链接和 Traits 提及,它将更加有用。具体链接失效了。以上是关于如何根据当前平台跳过 xUnit 中的特定测试的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Rider 中进行 xUnit 测试?我收到错误 CS0246