102
  • 我有一个在 Windows 上构建的程序集
  • 我想在 Linux 的单声道上运行 xUnit 测试。

但是,我发现虽然其中 400 个测试可以(按顺序)运行,但某些测试要么挂起 xUnit 运行器,要么完全停止运行。

不在乎某些测试是否无法在 Linux 上运行,某些测试与 DTC 和一些我们不需要在那里支持的非托管口香糖有关。

然而,我想要的是对这些测试应用忽略,并在构建输出中正确标记测试被忽略的事实。

这个问题可以归结为我猜有很多可能的解决方案

  • 如何通过控制台运行器在 xUnit 中运行特定测试?(我还没有找到这方面的文档,也许我只是不够努力)
  • 是否可以反过来说“这是一个程序集,尽管请忽略这些特定测试”
  • 建议在这些测试上设置一个属性是一种更好的方法,正式记录这些测试是特定于平台的——这可能吗?

如果我可以避免过多地修改原始代码,那将是伟大的,因为代码并不是我真正可以更改的,并且应用大量跨平台黑客可能不会太顺利。

4

6 回答 6

192

XUnit v2.0 现在可用。它直接支持可跳过的测试。采用:

[Fact (Skip = "specific reason")]
于 2016-06-21T07:36:18.837 回答
56

我会避免外部化跳过测试(即,如果可能的话,一个配置/命令文件)。这在某种程度上不利于使测试易于运行和值得信赖。当其他人开始参与时,在代码中忽略测试是最安全的方法。

我可以看到许多选项,这里有两个涉及修改现有代码。

选项 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://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;
    }
}

注1

如果用[Fact]和标记,xUnit runner 将运行一个方法两次[IgnoreOnMonoFact]。(CodeRush 不这样做,在这种情况下,我假设 xUnit 是正确的)。这意味着任何测试方法都必须[Fact]替换为[IgnoreOnMonoFact]

笔记2

CodeRush 测试运行程序仍然运行[IgnoreOnMonoFact]测试,但它确实忽略了[Fact(Skip="reason")]测试。我认为这是由于 CodeRush 反映了 xUnit 而不是在 xUnit 库的帮助下实际运行它。这适用于 xUnit 跑步者。

于 2010-12-12T13:44:45.370 回答
49

现在有一个新的选择。

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

例子:

[SkippableFact]
public void SomeTestForWindowsOnly()
{
    Skip.IfNot(Environment.IsWindows);

    // Test Windows only functionality.
}
于 2016-03-08T15:31:56.593 回答
2

这将是特征的理想使用,但不幸的是,命令行和 xml 项目文件都不支持基于特征的过滤。值得为此向 codeplex 站点添加一个问题。

于 2010-12-14T09:27:59.683 回答
2

[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,这当然不是很好。

于 2022-01-06T21:52:52.640 回答
-1

现在在 1.8 中解决了这个问题 - 您可以过滤 Traits。请参阅此问题日志

更新:Traits 适用于控制台运行程序,但不适用于 MSBuild,我已为此支持添加了功能请求。

于 2012-02-23T23:37:56.233 回答