如何仅在特定操作系统上 运行 时 运行 特定单元测试?

How to run specific unit tests only when running on a specific operating system?

给出以下示例助手

public static class RuntimeHelper
{
    public static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
    public static bool IsMac => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
    public static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
}

有几个问题

示例实现可能是

public sealed class RuntimeHelperTests
{
    // IF RUNNING ON WINDOWS

    [Fact]
    public void TheOSShouldBeWindows()
    {
        Assert.True(RuntimeHelper.IsWindows);
    }

    [Fact]
    public void TheOSShouldNotBeLinux()
    {
        Assert.False(RuntimeHelper.IsLinux);
    }

    [Fact]
    public void TheOSShouldNotBeMac()
    {
        Assert.False(RuntimeHelper.IsMac);
    }

    // DO THIS FOR THE OTHER OPERATING SYSTEMS TOO
}

但这些测试仅在 运行 在 Windows 机器上通过...

我们可以在逻辑中写很多层。对此没有实际上限。然而,无论我们写多少层,外面总是有一层,它必须与现实世界交互(例如监视器、网络、OS、文件系统、IO 设备,...)

最后一层永远无法真正进行单元测试,这是野兽的天性,因为它的依赖项是外部资源。所有其他层(即不是最后一层)都可以测试,因为它们的相邻层可以被模拟。

在您的情况下,RuntimeInformation 是您无法模拟的现实世界依赖项。这是 static 在测试中的主要问题之一。

一般来说,建议是将业务逻辑与外部依赖项分开,这样您就可以测试业务逻辑,同时将外部依赖项包装在它自己的一个很好的可模拟层中。 Here is an answer of mine elaborating on exactly that.

但是,在您的情况下,没有真正的业务逻辑。您的 RuntimeHelper 已经抽象的包装器。

RuntimeHelper编写测试没有意义。

如果你使 RuntimeHelper 实例化而不是静态的(我强烈建议这样做),那么你将能够通过注入模拟 RuntimeHelper 来对依赖于 RuntimeHelper 的 类 进行单元测试=13=] 这可以 假装 就像你在任何特定的 OS,即使你不是。

How to run specific unit tests only when running on a specific operating system?

你问错了问题。与其在实际不同的 OS 上为 运行ning 编写不同的测试,不如编写相同的(行为)测试,但在每个测试中设置模拟的 RuntimeHelper 来声明你在另一个 OS.

工作

例如:

[Fact]
public void FilePathService_returns_correct_linux_path()
{
    var mockedRuntimeHelper = new MockedRuntimeHelper(OS.Linux);
    var filePathService = new FilePathService(mockedRuntimeHelper);

    var result = filePathService.GetConfigurationFolder();

    result.Should().Be("/path/to/config");
}

[Fact]
public void FilePathService_returns_correct_windows_path()
{
    var mockedRuntimeHelper = new MockedRuntimeHelper(OS.Windows);
    var filePathService = new FilePathService(mockedRuntimeHelper);

    var result = filePathService.GetConfigurationFolder();

    result.Should().Be(@"C:\path\to\config");
}

[Fact]
public void FilePathService_returns_correct_mac_path()
{
    var mockedRuntimeHelper = new MockedRuntimeHelper(OS.Mac);
    var filePathService = new FilePathService(mockedRuntimeHelper);

    var result = filePathService.GetConfigurationFolder();

    result.Should().Be(@"whatever a Mac path is, I don't know");
}

这使您能够在 any OS.

上测试所有三种行为 运行ning

在所有 OS 上测试您的代码仍然是个好主意,只是为了确保您的 运行 时间没有奇怪的边缘情况,但这与想要编写仅应 运行 特定 OSes.

的特定单元测试