Question

I have a class that makes native Windows API calls through JNA. How can I write JUnit tests that will execute on a Windows development machine but will be ignored on a Unix build server?

I can easily get the host OS using System.getProperty("os.name")

I can write guard blocks in my tests:

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

This extra boiler plate code is not ideal.

Alternatively I have created a JUnit rule that only runs the test method on 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");
    }
  }

And this can be enforced by adding this annotated field to my test class:

@Rule public WindowsOnlyRule runTestOnlyOnWindows = new WindowsOnlyRule();

Both these mechanisms are deficient in my opinion in that on a Unix machine they will silently pass. It would be nicer if they could be marked somehow at execution time with something similar to @Ignore

Does anybody have an alternative suggestion?

Was it helpful?

Solution 2

Have you looked into assumptions? In the before method you can do this:

@Before
public void windowsOnly() {
    org.junit.Assume.assumeTrue(isWindows());
}

Documentation: http://junit.sourceforge.net/javadoc/org/junit/Assume.html

OTHER TIPS

In Junit5, There are options for configuring or run the test for specific Operating System.

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

}

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

Have you looked at JUnit assumptions ?

useful for stating assumptions about the conditions in which a test is meaningful. A failed assumption does not mean the code is broken, but that the test provides no useful information. The default JUnit runner treats tests with failing assumptions as ignored

(which seems to meet your criteria for ignoring these tests).

If you use Apache Commons Lang's SystemUtils: In your @Before method, or inside tests that you don't want to run on Win, you can add:

Assume.assumeTrue(SystemUtils.IS_OS_WINDOWS);

Presumably you do not need to actually call the Windows API as part of the junit test; you only care that the class which is the target of the unit test calls what it thinks is a the windows API.

Consider mocking the windows api calls as part of the unit tests.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top