如何仅在特定操作系统上 运行 时 运行 特定单元测试?
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);
}
有几个问题
- 我是否应该对这些字段进行单元测试? (这可能是基于意见)
- 有没有办法根据 OS 创建单元测试?
示例实现可能是
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.
的特定单元测试
给出以下示例助手
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);
}
有几个问题
- 我是否应该对这些字段进行单元测试? (这可能是基于意见)
- 有没有办法根据 OS 创建单元测试?
示例实现可能是
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.
的特定单元测试