It is still possible to run unit tests in NodeJs.
To illustrate the idea, let us take a look at the Cliqz extension, whose source code is open (Github link: cliqz-oss/browser-core). In comparison other extensions that I have seen so far, the code base is quite large.
In other words, it is not a toy example, but a realistic use case. The drawback, of course, is that due to the complexity, it is harder to understand how the test setup works (how mocking works, the integration into the build system, etc).
To get an idea how tests look like, here is one example:
To explain the details of how the mocking works is hard because you would need to dive deep into the build system. From a high level perspective, you will notice that in the test it uses a function called describeModule
, which does all the mocking of dependencies.
In the implementation of describeModule
, you can see that it uses systemjs to dynamically load ES modules. That trick makes it possible to run the unit tests with NodeJs.
My priorities are (highest to lowest):
- Algorithms, "business logic", e.g. parsing input data - no APIs needed - just JavaScript
For these kind of tests, the unit test infrastructure described above is the preferred way. For local development, NodeJs is used to run the tests.
- Internal logic - e.g. background scripts interacting with settings, etc.
This is not so different. The idea is still that you can mock dependencies and then do classical unit tests.
It might require some work to allow dependencies to be replaced. As mentioned, as the code base in this example has to run in different environments (e.g., Firefox, Chrome, Edge, ReactNative), platform APIs have to be abstracted (that includes also browser APIs).
- UI interactions - I can live without this, but would be nice to test
For testing the UI, there are additional integration tests. I do not want to go into details, but there are examples in the code.
What is important is that the integration tests are not executed with NodeJs, but they require a real browser environment (e.g., Firefox, Chrome). In addition, a local HTTP server is started which can be used to mock API calls.
As a side-note, linters are extremely useful and in comparison easy to setup. Also consider using a typed language (TypeScript), especially when the project becomes bigger and more people are working on it.
You will still need tests, as static analysis will not be able to find logical bugs. However, it helps to eliminate certain types of simple bugs like typos and the overhead (fixing linter errors or adding type annotations) is not very high.