How to run the same Jest test suite across several platforms (Jest-Os-Detection plugin included)
tldr: we made this: jest-os-detection
At Doctolib, we write a some native code in order to make our web application interact with native software our users are using. We support both MacOS and Windows for this product. This native code, written in Node.js (packaged with PKG) and C++, follows the same hard rule as the rest of our codebase: untested code is unfinished code!
In order to have these tests executed on all the OS we support, we use Azure Devops. It allows us to run the same tests on both Windows and Mac machines. During development, these tests run on our own computers (mostly Mac but also Linux).
In most cases, this is fine. For unit tests, you can mock the system calls to simulate the responses, so no need to be OS specific. But in our case, we also have some End-to-End testing, and we even test the result of executing our software installer! So we have to test our usage of OS specific features (such as the Windows registry). This led us to a situation where we had to write specific tests for Windows or MacOS, all part of the same test suite, without having them failing 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 solve 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:
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:
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:
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:
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 only on the right OS.
Want to get access to more technical content? Feel free to subscribe to the docto-tech-life newsletter to read our weekly selection of tech posts!