Introducing React Testing Library And Its Automation Capabilities

This library took aim at a few fundamental flaws in the traditional way of integration testing JavaScript applications and really changed the game when it comes to automated testing.

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the The newline Guide to Modernizing an Enterprise React App course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to Modernizing an Enterprise React App, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The newline Guide to Modernizing an Enterprise React App
  • [00:00 - 00:31] Much like how the introduction of React hooks changed how we develop modern React applications today, the release of Kent C. Dodd's React Testing Library in 2018 forever altered how integration testing of modern JavaScript frameworks is approached. This lesson will explore why React Testing Library was created to help us better understand the testing problems it aims to solve, while continuing to give Dev's confidence and quick feedback in the functionality of the apps that they're building.

    [00:32 - 00:49] Before we get to the details of React Testing Library, let's take a minute to define automated unit testing and integration testing and the differences between the two. They're used interchangeably often enough in conversation, but there are subtle distinctions worth pointing out.

    [00:50 - 01:15] So unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules, together with associated control data, usage procedure, and operating procedures are tested to determine whether they are working as expected. Integration testing, however, shows that the major subsystems that make up the project work and play well with each other.

    [01:16 - 01:28] Some describe it really as just an extension of the unit testing that's described above. Integration tests just test how entire subsystems honor their contracts instead of just individual components.

    [01:29 - 01:44] The biggest difference between the two is the scope of the tests. Unit tests focus on isolating testing of individual pieces of an app, while integration testing focuses on two or more components working together as they were intended to.

    [01:45 - 01:57] As I said in this introduction, automated testing is no longer and nice to have , especially when it comes to large, long-lived enterprise applications. It is a requirement.

    [01:58 - 02:11] But not all tests are created equal, and as we'll see shortly, some can inspire more confidence in our app than others. Let's talk a little bit about the downfall of enzyme and the rise of React Testing Library.

    [02:12 - 02:25] At the advent of React, a combination of just and enzyme quickly became the standard testing library pair for automated unit and integration testing. And it really worked well enough at the time.

    [02:26 - 02:49] When hooks were introduced to the world, enzyme wasn't prepared to handle them, which frustrated developers who were used to relying on automated tests to give them confidence that as they added onto apps, they didn't break existing functionality. This lapse in coverage gave an up-and-coming testing library a chance to step in and fill the void. That was React Testing Library.

    [02:50 - 03:03] So what makes React Testing Library different? Well, Kent C. Dodd's built React Testing Library to solve a fundamental flaw he saw with the whole of automated unit testing in the JavaScript world.

    [03:04 - 03:22] Up until then, unit testing frameworks like enzyme relied heavily on the implementation details present in individual components. This relying on underlying details made the tests brittle, prone to requiring rewrites when components were refactored, and generally just a pain to maintain .

    [03:23 - 03:37] And here's the biggest kicker. Even with these unit tests, guaranteeing that functions fired or events were triggered, it didn't guarantee that the components working together were doing what they should when a user interacted with the app.

    [03:38 - 03:51] Kent posted on Twitter back in 2015 a meme that still makes me smile every time I see it, and it very accurately shows the problem with relying purely on unit tests. And here it is.

    [03:52 - 04:08] This is a good example of what unit testers would see if our app was a human body. Kent, however, saw things a little differently, and the React Testing Library site itself sums up his views very succinctly.

    [04:09 - 04:24] You want to write maintainable tests for your React components. As a part of this goal, you want your tests to avoid including implementation details of your components, and rather focus on making your tests give you the confidence for which they are intended.

    [04:25 - 04:46] As part of this, you want your test base to be maintainable in the long run, so refactors of your components changes to implementation, but not functionality, don't break your tests and slow you and your team down. And so, React Testing Library was born with an aim to encourage better testing practices by following this guiding principle.

    [04:47 - 04:54] The more tests resemble the way your software is used, the more confidence they can give you. Makes sense, right?

    [04:55 - 05:07] So what does this actually mean in practice? It means less dealing with rendered instances of components, and more working with actual DOM nodes, less worrying about if a function was fired, or if a Redux subscription was called.

    [05:08 - 05:30] More focus on if a button click in the DOM made something happen. Less time spent thinking about the underlying implementation details that the end user is completely unaware of, and frankly doesn't care about anyway, and more time spent refactoring and writing code without having to update old tests because functionality remained intact.

    [05:31 - 06:01] RTL's style of integration testing is much more akin to how end-to-end tests tend to work, just within a smaller scope. Instead of running through a whole user flow from start to finish, like a traditional E2E test, RTL encourages mostly writing integration tests to test components closer to the way that a user will interact with them, which allows the tests to give more confidence the application will work as expected when a real user uses it.

    [06:02 - 06:10] Here are a few more React Testing Library facts. React Testing Library is not a test runner or a testing framework.

    [06:11 - 06:26] It is a light utility function on top of React DOM and React DOM test utils libraries. It's also not specific to a testing framework, although just as recommended, nor is it restricted to just testing React applications.

    [06:27 - 06:40] There's actually testing library implementations for many JavaScript frameworks , including view, angular, native, spelt, and more. Just check out the documentation I've linked to to get started with any of these other flavors.

    [06:41 - 06:48] Here's the bottom line. Using React Testing Library means more time writing code and less time fixing tests.

    [06:49 - 07:08] So let me get this straight. With just an enzyme, if a component's code is refactored, say a function was added or renamed, even though overall functionality remained the same, the associated test file will most likely break and need fixing, because enzyme is concerned with testing the implementation details.

    [07:09 - 07:27] If, however, just and React Testing Library are used and that same components underlying functions are changed, but the functionality remains intact, the tests would most likely not break or need some minor fixes to work again. Hmm.

    [07:28 - 07:37] Less time spent fixing tests and more time spent writing code. As a developer who enjoys building new things, that sounds pretty good to me.

    [07:38 - 07:45] Ready to get hardware handlers set up to use RTL and just stir-write our tests? Me too.