如何根据当前平台跳过 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。

【讨论】:

我想我可能不得不接受自定义的事实,但不完全确定项目的核心提交者是否会如此高兴:) _ 效果很好! 似乎不适用于 xunit.runner.visualstudio。其他人得到这个? 这是迄今为止我找到的最干净、最好的答案。 SkippableFact 的代码不够简洁并添加了依赖项,也不允许描述为什么跳过测试。 10 年前的好答案。在撰写本文时还没有。【参考方案3】:

现在有一个新选项。

添加 Nuget 包SkippableFact,它允许您使用[SkippableFact] 而不是[Fact],并且您可以在测试中使用Skip.&lt;xyz&gt; 在运行时动态跳过测试。

例子:

[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

如何在 Gitlab CI 中捕获结构化的 xUnit 测试输出?

使用Xunit来进行单元测试

跳过 R 中 M1mac 的测试

Xunit项目中的依赖注入