DEV Community

loading...
Cover image for How to run the same Jest test suite across several platforms
Doctolib Engineering

How to run the same Jest test suite across several platforms

Quentin Ménoret
Engineering Manager @Doctolib – Mostly writing about TypeScript / JavaScript
Updated on ・3 min read

tldr: use this: jest-os-detection

The context

If you are writing a Desktop application, you probably need to test your software on several platforms. You'll probably end up with OS specific tests part of the same test suite. But you probably don't want them to fail when running on the wrong platform!

There are different approaches to solve this issue. I'll describe a few here, and explain how we decided to tackle this problem here at Doctolib.

First solution: divide the tests

One simple way to solve this problem would be to have different test suites. One global running on all hosts, one specific for Windows, and one for MacOS. That works fine. We do have a specific test suite for the installer tests for instance. But you'll end up with the same architecture duplicated. Supporting Mac and Windows you would end up with three folders:

tests/
tests-windows/
tests-macos/
Enter fullscreen mode Exit fullscreen mode

It works, but we would lose the ability to group tests in the way we want: per feature. This is why we decided to go another way.

A bit better: using if statements

You could also just deactivate your tests based on if statements. If you want your test to run only on windows you could write something like:

if (os === 'win32') {
  it('executes on windows', () => {})
} else if (os === 'darwin') {
   it('executes on mac', () => {})
}
Enter fullscreen mode Exit fullscreen mode

A bit better indeed, but that's a lot of boilerplate. Also, the test won't appear in your test results. The worst case would be if you had to encapsulate all files in your test file this way: jest would just crash because it refuses to run on a file containing no tests.

Ideally: Dynamically skipping the tests

The proper solution (at least in our use case) is to dynamically skip the tests based on the OS. In order to achieve that, you will have to write something like:

itOnWindows = os === 'win32' ? it : it.skip
describeOnMac = os === 'darwin' ? describe : describe.skip

itOnWindows('only executed on windows', () => {})
describeOnMac('only executed on mac', () => {})
Enter fullscreen mode Exit fullscreen mode

That's already better right? Your test report will contain the test as skipped on mac and it will run on Windows. And this time, jest won't crash if all your test file is skipped!

Now let's reduce the boilerplate a bit.

Jest OS detection

Obviously, if you want to apply this to any OS, and to every possible exported method from Jest, this is going to be tedious and result in a lot of redundant code. Luckily, we did that for you.

All you have to do is to install jest-os-detection and add it to your configuration (follow the readme instructions), then you will be able to write code such as:

// You can use skipXXX or onXXX on the method exported by jest:
// describe, it and test
describe.skipLinux('skipped on Linux', () => {
  it.onWindows('executed on Windows', () => {})
  test.onMac('executed on Mac Os', () => {})
})

// You can even chain statements!
it.skipMac.skipLinux('skipped on Mac and Linux', () => {})
Enter fullscreen mode Exit fullscreen mode

Most of the functions from Jest are supported. You can just append skipWindows or onWindows (or any other platform) to the jest call, and we will make sure to forward it onto the right OS. We also support TypeScript (check the readme for the specific setup).

It's clearly only a syntactic sugar, but it helps make the code more readable. Since it could be useful to others, we thought we would publish it on npm.


Originaly published on Medium (long version).

Discussion (0)