JavaScript unit testing with Jest

 
jest pic.png
 

If you haven’t heard of Jest already, then let me introduce you to the JavaScript unit testing framework from Facebook, which has gained popularity very quickly and is already the main unit testing JavaScript framework for UI component frameworks like React. Jest hails itself as the complete and easy to set-up JavaScript testing solution, and provides game-changing testing features such as snapshot testing and the interactive watch mode. Jest also handles integration testing with a powerful mocking library, but does not replace the more-expensive functional tests on the browser.

The snapshot testing feature is perhaps at the core of the framework’s utility. It makes sure your UI does not change unexpectedly by taking serializable snapshots of UI components and comparing them against previous snapshots. UI components are generally responsible for producing some DOM output to be rendered, so Jest simply ensures that the resulting output looks as expected. Writing tests that do this is easy in Jest, and allows you to cover more components with tests in the same amount of time. You just need to set up data or mock objects for the component inputs. You can then use the snapshot files, which live in a folder next to the tests that generated them, to check regressions when files change, with the interactive watch mode.

Jest can also be used to manage the changes in behavior of your application, by comparing outputs of not just UI components, but any other state-changing functionality. For example, if you are using Redux (or something similar) to control your application state, you can have Jest compare the resulting state of your entire app. Comparing results of top-level components gives you coverage similar to integration tests, since you can compare snapshots of large component trees that demonstrate components working together correctly. You can use Jest for anything that produces a structured response like analyzing API responses, or calls to any service or function.

Developers are happier using Jest for unit or integration testing because changes to components are easier to deal with in the test code. Being a Facebook framework means that there is a ton of support for it, and integrating it with existing JavaScript testing stacks (like converting from Mocha) is not difficult. It uses the Jasmine BDD testing framework under the hood, which is nice because Jasmine supports globals, assertions, spies, and mocks. Jest test results are displayed with easily readable diffs between snapshots, which make it easy to understand regressions. Code coverage reports are easy to generate, and show coverage statistics on files, code statements, branches, functions, and even code lines. Jest also improves the performance of tests in big projects by implementing a clever parallel testing mechanism that uses multiple workers to run tests.

But, of course, Jest is not without some limitations. For instance, State snapshots are not great at dealing with code side-effects. The work-around for this is to use spies in Jest to intercept function calls and trigger side-effects. You can then inspect the output snapshots per the usual method. Jest tests are also not made to be run on the browser, so your End-to-End testing will need to be covered by another testing framework; probably something that uses Selenium, such as WebdriverIO.

Well, there you have it. Start writing easy JavaScript unit tests that compare snapshot outputs today!

Jeff Poyzner