仅在Windows上运行单元测试

25

我有一个类,通过JNA调用本地 Windows API。如何编写 JUnit 测试,在 Windows 开发机上执行但在 Unix 构建服务器上被忽略?

我可以使用 System.getProperty("os.name") 轻松获取主机操作系统。

我可以在我的测试中编写守卫块:

@Test public void testSomeWindowsAPICall() throws Exception {
  if (isWindows()) {
    // do tests...
  }
}

这些额外的样板代码并不理想。

或者,我创建了一个 JUnit 规则,只在 Windows 上运行测试方法:

  public class WindowsOnlyRule implements TestRule {
    @Override
    public Statement apply(final Statement base, final Description description) {
      return new Statement() {
        @Override
        public void evaluate() throws Throwable {
          if (isWindows()) {
            base.evaluate();
          }
        }
      };
    }

    private boolean isWindows() {
      return System.getProperty("os.name").startsWith("Windows");
    }
  }

通过将这个带注释的字段添加到我的测试类中,就可以实现此功能:

@Rule public WindowsOnlyRule runTestOnlyOnWindows = new WindowsOnlyRule();

在我看来,这两种机制都存在缺陷,因为在Unix机器上它们将默默地进行。如果能够在执行时用类似于@Ignore的方式标记它们,那将会更好。

是否有其他替代建议?

5个回答

33

在Junit5中,有针对特定操作系统配置或运行测试的选项。

@EnabledOnOs({ LINUX, MAC })
void onLinuxOrMac() {

}

@DisabledOnOs(WINDOWS)
void notOnWindows() {
    // ...
}

感谢您更新了新的JUnit功能,很高兴知道。 - darrenmc

25

这正是我正在寻找的功能。谢谢。 - darrenmc

4
你看过JUnit的假设语句吗?
这对于陈述测试有意义的条件非常有用。失败的假设并不意味着代码出现了问题,而是测试没有提供有用的信息。默认的JUnit运行器将带有失败假设的测试视为被忽略的测试(这似乎符合您忽略这些测试的标准)。

@BrianAgnew使用TestRules是我在问题中已经描述的第二种机制。我会看一下假设。 - darrenmc
我认为在这种情况下,这可能更加合适。 - Brian Agnew
@BrianAgnew 对不起,我有点暴躁。我只是觉得我看到你编辑了假设部分。 - jgitter
没问题。这是一个快节奏的网站! - Brian Agnew

3
如果您使用 Apache Commons Lang 的 SystemUtils:
在您的 @Before 方法中,或是在您不想在 Windows 上运行的测试内部,您可以添加以下内容:
Assume.assumeTrue(SystemUtils.IS_OS_WINDOWS);

0

假定您在JUnit测试中实际上不需要调用Windows API;您只需要关心作为单元测试目标的类是否调用了其认为是Windows API的内容。

考虑将Windows API调用模拟为单元测试的一部分。


我怀疑他需要在某个阶段调用Windows代码,因此需要进行兼容性测试。不过,我理解你的观点,关于模拟测试肯定有其用处。 - Brian Agnew
是的,我确实考虑过模拟,但在这种情况下,我真的想调用底层实现。 - darrenmc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接