Search code examples
javajunitnio

Explicitely use UnixPath or WindowsPath in JUnit test


I want to test a method with finds the longest, common subpath of two Paths (found here). As the program should run under Windows and Linux, I want to create tests with Linux paths and other tests with Windows paths.

The problem is, that the Windows tests only pass in a Windows environment and fail in a Linux environment. For the Linux tests it is the other way around.

I can mitigate the problem by checking the OS before doing the actual test. e.g.: org.junit.Assume.assumeTrue(isWindows()); But then the tests always pass in our Jenkins instance, which is run on Linux. Which is not ideal.


Solution

  • Write most of your test cases so that they work on both platforms. Windows Path handling is very tolerant to using Linux paths. If you carefully frame your test data so that you never convert a Path back to String your Linux Path tests should work on Windows because you can omit mentioning a Windows drive letter as a String value.

    For example try these tests on both platforms. Windows Path handling automatically deals with the wrong style of path separators internally but this is never exposed unless you convert Path back to String:

    @Test void testsCommonToAllPlatforms() {
      Assertions.assertEquals(Path.of("/a/b"), commonPath(Path.of("/a/b/c"), Path.of("/a/b/d")));
      Assertions.assertEquals(Path.of("a/b"),  commonPath(Path.of("a/b/c"),  Path.of("a/b/d")));
      Assertions.assertEquals(Path.of("/"),    commonPath(Path.of("/a/b/c"), Path.of("/d/e/f")));
      Assertions.assertEquals(        null,    commonPath(Path.of("a/b/c"),  Path.of("d/e/f")));
    }
    

    This will leave you to setup a few extra Windows specific tests (in additional to above) which could include drive letters, and you'll need access to a Windows build machine now and then to verify no regressions:

    @EnabledOnOs(OS.WINDOWS)
    @Test void testJustForWindows() {
      Assertions.assertEquals(Path.of("C:/Winnt"), commonPath(Path.of("C:/Winnt/System32"), Path.of("C:/Winnt/System64"))));
      Assertions.assertEquals(               null, commonPath(Path.of("C:/Winnt/System32"), Path.of("F:/Winnt/System32")));
    }