Why and how we migrated from Mocha to Jest as our client-side test runner

Photo by 🇸🇮 Janko Ferlič on Unsplash

Building reliable and scalable services and applications takes skills and dedication, and we have always had the best intention when choosing technologies, libraries, and frameworks. However, technologies move rather quickly, and we have to decide whether to allocate resources to improve existing features and services or build new systems on things we’ve already made. The underlying principle applies to us as well at Harry’s. This is a story of how we identified issues with one of the libraries we use for testing (Mocha), why we thought it was critical to replace it, how we chose its replacement, and the steps we took to migrate over successfully.

What is Mocha.js? ☕️

Mocha.js is an excellent testing framework created for Node programs (later supported browser testing). It’s robust, mature, flexible, and offers lots of great features (if you’re interested in learning more, please check out Mocha’s official website). For those reasons, we decided to use Mocha to write all of our front-end unit and integration tests many years ago.

Why was Mocha not a great fit anymore? 😢

Kent C. Dodds famously (https://twitter.com/kentcdodds/status/960723172591992832) coined a term called “The Testing Trophy”, through which he described the four pillars of client-side testing: static testing, unit testing, integration testing, and end to end testing. Each testing strategy requires a unique approach and resources (time and money).

Artwork created by Kent C. Dodds
  • An end-to-end test is the most reliable, but it takes the longest, and because the test requires making an actual network request, the platform needs to be powerful enough. As a result, it costs money to run.
  • An integration test is excellent, but we don’t gain enough confidence because we mock most components making network requests.
  • A unit test is terrific in its own right, but it doesn’t test a system as a whole, so it is pretty limiting.
  • A static test is mainly for catching typo and type errors.

We could use all of the above and write as many tests as possible in an ideal world, but it’s not realistic. So we have to make a trade-off.

But how?

  1. Write robust integration tests (don’t test implementation details)
  2. Mock, but very little (we don’t want to charge the credit card on every test)
  3. Write tests that resemble how your users would use your platform.

You might be wondering, could there be a library we could use that would help us achieve all three?

Yes, we are introducing React Testing Library (https://testing-library.com/docs/react-testing-library).

It’s a testing library created by Kent (you guessed right), which offers a simple set of APIs for querying DOM elements/nodes. So we could quickly write assertions around the behaviors of our application instead of testing code implementations.

I will let Kent explain why it’s incredible to write tests with RTL https://kentcdodds.com/blog/introducing-the-react-testing-library.

At this point, we are convinced that RTL is the right tool for us. Just one problem left. Mocha (Aha, we are back talking about Mocha now, glad you stuck around). Mocha is great, but it’s so flexible that we had to find and install many packages to support all client-side testing needs. That was the case with RTL as well. So after many hours of trying with no avail, we just decided to replace Mocha altogether.

With what?

We naturally picked Jest since it’s one of the most popular javascript test runners for client-side and server-side testing (node APIs). The migration process was pretty straightforward as well. And The fact that the Jest team provided a specific section on migrating from Mocha to Jest (https://jestjs.io/docs/migration-guide) made it 100% better. Overall it took us a little over 20 days to migrate around 4k tests. (If you are interested to hear more stories on mocha migration, here is Kent again on how he convinced his team at Paypal to migrate from Mocha to Jest https://kentcdodds.com/blog/migrating-to-jest).

In the end, we are pretty happy about the result. With Jest being our test runner, all that was remaining was to write/update tests by using RTL.

We are pleased that you stayed till the end; we hope you enjoyed reading this article as much as we enjoyed writing it.




The engineering blog of Harry's

Recommended from Medium

The useEffect hook is just a function that takes two parameters

How to store multiple fetch requests in a single javascript array to use globally

JavaScript Projects

Getting Started with Electron, Typescript, React and Webpack

What is Node.js and why you need it?

Multi Language in React Native Application for beginners

360° IT Check #36 — How You Can Help Ukraine and Ukrainians Meaningfully

Reactjs Vs. Angular: Which Development Tool Should Your Software Development Partner Use?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Xifeng Jin

Xifeng Jin

More from Medium

Reimagining FrontEnd for an International ScaleUp @ Lenskart.com

Keys to efficient i18n

Cleaning up business logic with state machines

A state diagram describing five states and the transitions between them. The states are “Awaiting assembly” (which transitions to “Awaiting packing” when the order is assembled), “Awaiting packing” (which transitions to “Awaiting courier” when the order is packed), “Awaiting courier” (which transitions to “Dispatched” when the order is handed to the courier, or to “Awaiting packing” when the address is changed), “Dispatched” (which never transitions to any other state), and “Cancelled”.