Testing React Applications with Karma, Jest or Mocha

Testing React Applications with Karma, Jest or Mocha

Posted by Martin Bielik | August 9, 2016 | javascript, react, testing

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:

  • provide test structure (Mocha, Jasmine, Jest)
  • run tests and display test results (Mocha, Jasmine, Jest, Karma)
  • make assertions (Chai, Jasmine)
  • support mocks, spies, stubs (Sinon.JS, Jasmine)
  • generate code coverage reports (Istanbul)

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

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:

and inside configuration file:

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!

Jest vs. Mocha

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:

  • Jest is recommended by Facebook to test React components however Mocha with Enzyme is widely popular
  • Jest is slower because its auto mocking feature
  • You don’t need auto mocking when you test React components
  • Mocha more flexible and it is expected to be used with other libriaries like Chai, Sinon.JS
  • Jasmine is all-in-one test library (runner, assertions, mocks)
  • Installation and setup is not the criteria for choosing the right test framework

Conclusion

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.

Blog Comments

“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

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)

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.

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.

Add a comment

*Please complete all fields correctly

Related Blogs

Posted by miklik | 08 September 2017
Why do I need one? Every programmer has its own coding style. It is polite to honour the style of the file I am editing but when I am starting…
Posted by miklik | 24 February 2017
Recently we were invited to help others to resolve compatibility issues between IOS and Android. They have started with React Native but have developed their application only for Android. And…
Posted by miklik | 19 December 2016
What do you want for christmas? We wanted a color picker for React Native but we could not find any. Therefore we made one for you. You can find it…