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 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?
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?
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.
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 was created to solve 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. None of the children of that component are rendered. 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.
When you get started with Enzyme full rendering, there’s an additional requirement you’ll need. 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 more confidence that the code they write works the way it’s supposed to, and 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 it 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.