Today’s web applications are more complicated than ever. Libraries like React have opened up a whole new world of application complexity and functionality. As an experienced developer, you know that it’s important to test every part of your web application.
You probably already have a plan for testing your server’s code. That’s great! But it’s just as important that you to test your application’s UI, too. If you’re like me, the loads of different testing options for UI testing is overwhelming.
Tools like Jest, Mocha and Enzyme all aim to provide real gains in testing your application. But they can be difficult to tell apart. How do you know which tools are worth your time, and which ones will just slow you down?
In this post, we’re going to look at two popular JavaScript testing tools, Jest and Enzyme. We’ll examine what makes them similar and what differentiates them. We’ll discuss the areas where they’re most useful, and even how they can work together.
Jest and Enzyme: How Are They Similar?
Both Jest and Enzyme provide powerful tools for testing React UIs. Each is a unit testing tool that empowers you to ensure that the user interface of your web application looks and behaves as expected. Both are actively developed and easily installed using Node Package Manager.
Each has a thriving community of developers who can help out someone new to the library if they find themselves in a tight spot.
Jest and Enzyme: How Are They Different?
To get the most obvious difference out of the way, Jest and Enzyme serve slightly different purposes. Jest is a fully-featured testing framework. That means that it doesn’t just help you test React components.
Jest provides a test-running script that will run all your tests, as well as an entire assertion library. Jest works great with React, but it’s not limited just to React. If you’re building your web application entirely in JavaScript, for instance using NodeJS to build your server, Jest allows you test your whole application with one test library.
Enzyme serves a different purpose. Instead of serving as a full testing library, Enzyme is a library that makes testing React components specifically easier. It integrates with many full testing libraries, including Jest. If you’re using React in your application, it might make sense to use Enzyme and Jest together to automatically test your UI.
Jest Compares Snapshots
While Jest works as a fully-featured test library, it does have some integrated tools specifically for testing React UIs. These tools obviously work well with the rest of the Jest features to create robust tests for web UIs. The primary way that Jest does this is through the use of snapshots.
A Jest snapshot is a saved fragment of HTML generated by your application. Developers generate these snapshots before writing tests by rendering components and saving their HTML using special Jest snapshot syntax. Snapshots are human-readable, and exist within the normal code base.
Then, whenever Jest runs tests, it compares the output of rendering a component with the saved snapshot HTML. If they’re the same, the test passes. If not, Jest raises a test failure and you have some work to do.
A jest snapshot is the HTML output of the component that you’re testing. For instance, if you have a component that renders a link to Testim, and it’s supposed to have a class of external, you’d create that component inside your test file. Then Jest would render that component to HTML, similarly to how it would be rendered by React.
Then, to make test runs faster, it saves that component HTML to a snapshot file. That link might generate a snapshot file that looks something like this:
exports[`the components match 1`] = `<a className="external" href="http://www.testim.io">Go Check Out Testim!</a>`;
Jest manages all the snapshots for your project, and can quickly grab the HTML it needs to make sure that your components are behaving as expected.
Then, Jest’s assertion library allows you to make assertions about the component you render. For instance, you might load the snapshot above, and compare it to the snapshot rendered during your test run, like so:
test("the components match", () => { const renderedComponent = (<LinkComponent className="external" to="http://www.testim.io">Check Out Testim!</LinkComponent>); expect(renderedComponent).toMatchSnapshot(); });
Jest manages the component snapshots based off the name of the test, which is the first parameter to the test function. If instead, you wanted to validate that the rendered component has properties you expect, you could render the component and make assertions about the attributes it possesses. For instance:
test("has the right class", () => { const renderedComponent = (<LinkComponent className="external" to="http://www.testim.io">Check out Testim!</LinkComponent>); expect(renderedComponent).toHaveClass("external"); });
Enzyme Provides an API to Examine React Components
Using snapshots to test UI components is a useful method, but it has some real drawbacks. For starters, saving HTML snapshots leads to lots of noisy code inside your code base that doesn’t provide much value. If you have a component which might exist in three different states, you need to save three different snapshots of that component for the test of each state.
Even though just one line might have changed, you’ll need to repeat the snapshot three times. A second drawback is that a failing snapshot fails once across the entire component. If you have a component that spans ten lines, but just one failure message, it can be difficult to determine where the test is actually failing.
Enzyme solves these problems. Instead of comparing entire snapshots of a rendered component, Enzyme renders the component in memory, then provides a series of APIs to examine the component’s properties.
Enzyme Shallow Rendering
The first API that Enzyme provides is the Shallow Rendering API. Shallow rendering is one way that Enzyme keeps tests simpler than Jest. When you shallow-render a component with Enzyme, you render only that component. Enzyme doesn’t render any of the children of that component.
This is a useful restriction that ensures that you aren’t testing too much in one test. With Jest, you need to have the entire component, including children, saved inside a snapshot. As previously noted, if changes to parameters change how your components render, you’ll need to have a snapshot for each version.
Enzyme’s shallow rendering does away with all of that. Instead, you render only the component you’re testing, and none of the children. Then, you can use functions like find() and findWhere() to find elements within the component.
From there, you write assertions about those elements. Your testing library (like Jest!) examines those assertions, and hopefully finds all of them to be true.
Enzyme Full Rendering
At first glance, full rendering with Enzyme looks a lot like shallow rendering. Much of the API is similar. However, full rendering renders an entire web page in memory. This means that instead of a single component, you’re able to test the behavior of the entire page.
This kind of functionality is useful for integration testing, where you test multiple components and how they work together. Full rendering doesn’t exist in opposition to shallow rendering, but is instead a complement to the value of testing individual components.
Before you start tests with Enzyme full rendering, you’ll need to fulfill an additional requirement. Shallow rendering works right in memory, but full rendering requires a library that behaves like a browser. The recommended library is JSDOM.
Getting started with JSDOM is easy, but it’s an extra step you should know about before you dive in.
Jest and Enzyme: How Can They Work Together?
Like we noted before, Enzyme needs a testing library to provide a foundation for the tests it generates. Many people choose to use Jest and Enzyme together to test their React web applications. They use Jest as a test runner and assertion library, then use Enzyme to build the tests for their UI.
This results in slimmer, cleaner testing code that’s also easier to debug when a test breaks. Developers which use these tools together find them to be a powerful combination that makes testing UIs simple. Experienced developers then hook these tests into an automated testing framework that runs these tests on each commit to source code.
Using all of these tools in concert means developers find bugs faster. This is a significant step toward software maturity for teams writing complicated applications. Developers have confidence their code works the way it should. They’re confident it doesn’t introduce bugs.
QA engineers are able to focus on testing more complicated cases, instead of looking for regressions in the UI. Customers are happier because software comes faster, and works the way it’s supposed to when it launches.
In the end, using tools like Jest and Enzyme for what they’re best at makes all of your software better. Even though the software we write grows more complex by the day, that doesn’t mean it needs to be harder to write. We just need to use the right tools to manage that complexity.
This post was written by Eric Boersma. Eric is a software developer and development manager who’s done everything from IT security in pharmaceuticals to writing intelligence software for the US government to building international development teams for non-profits. He loves to talk about the things he’s learned along the way, and he enjoys listening to and learning from others as well.