Nowadays in the ever changing “world of JavaScript and React” there are many libraries which could be used to test React components. It could be hard especially for newcomers to find out which library suits their problems best.
In generall test frameworks are expected to:
Furthermore when you test React app you also need some utilities to work with JSX, rendering or shallow rendering, component traversing or simulating user actions. This is job for React Test Utils or Enzyme.
In this blog I will focus on most used test runners to test React components (Karma, Jest and Mocha), it’s features and try to compare it.
Karma allows you to run your tests in real browsers. It is a great feature especially when your application is supposed to support multiple browers or legacy browsers. Furthermore you can run test remotly using webdriver or services like SauceLabs or BrowserStack. You can run your tests in multiple browsers with installing relevant launcher and just a few lines of configuration.
For example adding firefox browser to test configuration:
1 |
npm install karma-firefox-launcher --save-dev |
and inside configuration file:
1 2 3 4 5 |
module.exports = function(config) { config.set({ browsers : ['Chrome', 'Firefox'] }); }; |
It supports all major browsers including Phantom.js and can be also run inside Node.js using jsdom. Just to mention it is common to use Karma with other test runners like Mocha or Jest.
Some dev says that it’s worthless to run unit test suites against real browsers and you should write end to end tests instead. However e2e tests are expensive, take longer to run and mostly don’t cover each use case. I think Karma offers easy and fast solution to find compatibility bugs (if you fail, you will fail fast). It is definitely worth to try!
The big debates are whether to use Jest or Mocha. Both are great libraries, each has its own pros and cons. Alghough Jest is officially recommended by Facebook developers, it seems that Mocha stack is more popular (especially in combination with Enzyme).
The main difference is in (futuristic) Jest’s approach “auto mocking” – Jests developers decided to mock every dependency except tested unit. It is not a good or bad approach, it’s just different. In applications where you need to mock every dependency in most cases it can dramatically reduce boilerplate and ease writing tests. However when you test React you don’t exclusively need auto mocking while there are utilities (React Test Utils) which provides shallow rendering. Test utilities like Enzyme offers a lot of helpful methods to render, assert and traverse components, simulates clicks and other. Auto mocking is expensive and tests lasts mentionably longer what is (to be honest) really pain during development.
Next difference is that Jest uses Jasmine 2 as default for assertions, mocking and it also has its own mocking methods. On the other hand Mocha is more flexible and you can choose what you need and like. It can be used together with any other assertions or mock library (Chai, Sinon.JS, …).
Some claims that installation, setup and configuration of Jest tests is less complicated that Mocha. That could be true since Jest is all in one package and you need to setup for example assertion library when using Mocha. But the effort is minimal and this criteria definitely shouldn’t be deciding. In my personal experience I ran into trouble when first tried to setup Jest which auto mocks whole node_modules
. It didn’t run my tests and I must explicitely configure which modules not to mock which was more confusing than the whole Mocha setup.
The table below sumarizes several pros and cons of each:
Jest | Mocha | ||
---|---|---|---|
PROS | CONS | PROS | CONS |
Officially supported by React dev | Slower due to auto mocking | More popular in js community | No auto mocking or snapshot testing |
Auto mocking | Enforce to use jasmin * | Flexible (can be used with any assertion, mock, report library) | |
Snapshot testing | Poor documentation | Clear, simple API | |
Asynchronous code testing support | Asynchronous code testing support | ||
React native testing | Fast test run | ||
React native testing (in combination with Enzyme) |
* jasmine will be probably replaced in the future
To summarize thoughts above:
All mentioned libraries are very sophisticated and do a great job when are used right. Karma is a great tool which can be used independently from other test runners. There is no reason to not give it a chance! I would personally choose Mocha over Jest especially in combination with Enzyme. It is fast which is comfortable during development (and that’s what you do everyday). When you use it with live test watching is a great experience. It is also more flexible and can be used with awesome projects like Chai or Sinon.JS. On the other hand Jest has nice and promising ideas like auto mocking or snapshot testing. It is still evolving and will be nice to see the progress in the future. Both Jest and Mocha are great tools and it depends on your needs which one to use.
4 Comments
Eitan P
“Automocking is now disabled by default in Jest” (since Sept. 2016) – https://facebook.github.io/jest/blog/2016/09/01/jest-15.html#disabled-automocking
Greg K.
Karma + Mocha + Enzyme … and now enzyme-to-json* to get snapshoting! Now, if you area careful to leverage snapshots in places where there are lots of change (read: making tests brittle), you can have both the ability to leverage runner, assertion, mocking options and snapshots. Or, invest completely into the complete Jest package and trust that it’s slowness issues are being addressed**.
My concern is a point your raised in the Karma section and didn’t include in the PRO/CONS section. By leveraging Karma, I test against the browsers I support; using only Jest, I test against their virtual JavaScript environment (not real browsers). Can Karma drive Jest testing so that the Jest tests run against real browsers?
See:
* https://www.npmjs.com/package/enzyme-to-json
** Jest speed-up efforts: https://facebook.github.io/jest/blog/2016/03/11/javascript-unit-testing-performance.html#adding-everything-up && (See @eitan p in prior comment)
Stanislav Miklik
Currently it seems that running Jest on Karma won’t be possible in near future ( https://github.com/facebook/jest/issues/848 ). It seems that their philosophy is to run “fast” Jest (unit) tests against virtual JSDOM and to address browser specific issues via set of dedicated end-to-end tests.
Trevor Huey
In order to use enzyme-to-json, don’t you still have to use Jest? From what I understand, enzyme-to-json generates jest-compatible snapshots, however those snapshots are still intended to be run through Jest’s snapshot assertions.