Run unit tests only on Windows
Asked Answered
C

5

28

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?

Chico answered 1/5, 2014 at 15:21 Comment(0)
A
26

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

Alloy answered 1/5, 2014 at 15:27 Comment(1)
This is exactly the functionality I was looking for. Thanks.Chico
S
37

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

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

}

@DisabledOnOs(WINDOWS)
void notOnWindows() {
    // ...
}
Subterranean answered 28/3, 2018 at 5:28 Comment(1)
Thanks for updating with the new junit feature, nice to know.Chico
A
26

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

Alloy answered 1/5, 2014 at 15:27 Comment(1)
This is exactly the functionality I was looking for. Thanks.Chico
A
4

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).

Athamas answered 1/5, 2014 at 15:25 Comment(4)
@BrianAgnew using TestRules is the 2nd mechanism I have already described in my question. I will take a look at assumptions.Chico
I think it's perhaps more appropriate in this scenarioAthamas
@BrianAgnew Sorry I got a little grumpy. I just thought I saw you edit the assumption piece in.Alloy
No problem. It's a fast moving site!Athamas
U
3

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);
Unhair answered 5/2, 2020 at 16:53 Comment(0)
C
0

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.

Ceroplastics answered 1/5, 2014 at 15:42 Comment(2)
I suspect he needs to call the Windows code at some stage and as such needs a Windows compatible test. I take your point re. mocking though and I'm sure there would be use for it somewhereAthamas
Yes I did consider mocking but in this case I do really want to call though to the underlying implChico

© 2022 - 2024 — McMap. All rights reserved.