Testing a React Application: The Modern Approach

Testing a React Application: The Modern Approach

The first article in a series where I go over how to do modern-day testing on a React app. In this post, I cover my perspective on effective tests.

Introduction

Testing is a fundamental part of development. Testing a react application is no different. Once an application grows to a certain size it becomes one of the only ways you can have confidence that a change you make will not affect previous functionalities. The keyword here is confidence.

A test is only good if it can make sure that an interaction a user expects, remains the same

Me or something

A test’s main focus should be centered around what the end-user expects. This means any and all implementation details should remain irrelevant. A user does not care about the names of variables or functions, only that when they click a button it does the expected behavior.

sticky notes with errors Photo by David Travis on Unsplash

With that being said, this is the first article in a series where I’ll go over how to perform modern testing on a React application. I’ll first go over our terminology and tools, following articles will go over how to create E2E tests and unit tests taking into account the selected tools.

Terminology

Although everyone has a different definition of what different types of tests are and what they cover, I figured I would give my own personal definition for future reference:

What is a unit test?

A unit test is a testing method for an isolated and individual piece of code, a unit. In the context of React, this more than likely refers to testing our components in isolation and any associated functions.

What is an end-to-end (E2E) test?

Testing the functionality of an application under the most production-like circumstances. In our case, this means compiling, building, and running the app inside a browser-like environment and going through different user flows.

Testing a React app: The Tools

I put a heavy emphasis on end-to-end testing. This will most resemble how the user is interacting with the application and will, again, instill the most amount of confidence. My framework of choice here is Cypress.

Unit tests will be taken care of with Vitest(yes, not Jest).

And finally, since our concern isn’t with the backend or API but with the front-end and the respective user interactions then a mocking library will be vital. MSW has us covered here.

End-to-end Testing a React App: Cypress

Here is a video directly from their landing page giving a brief introduction:

Cypress is a tool I can’t speak more highly of. As weird as it sounds it makes testing fun. The visual test runner makes it so easy to develop the tests as it can select elements and help you create selectors as you go. It comes with amazing Typescript support out of the box. The website documentation is on point. I’ll stop gushing about it now. 😢

Unit Testing a React app: Vitest 🌽

The yin to our Cypress yang. Vitest will cover everything that isn’t feasible to do for end-to-end testing. Although integration testing is vital it does have the downside that it can be considerably slower than unit testing.

Although it’s become a bit of a meme to say something is blazing fast 🚀. In this case, it completely holds true.

stopwatch Photo by Saffu on Unsplash

Much like Cypress, this comes with out-of-the-box Typescript support, Chai built-in assertions, instant watch mode, and DOM mocking!

Not to mention it can be overkill if we want to test specific edge cases for functions or transformations that we have inside our codebase.

We will be using this to test our React components, hooks, and utility functions in isolation. This is to make sure we cover our edge cases in the process.

Mocking our tests: MSW 🎭

Although not directly related to our tests this is still a vital component. MSW will make our tests consistent and avoid coupling our tests to backend cleanup and APIs. These can be more important down the line with end-to-end testing or separate backend-only testing.

I prefer MSW in most cases because we can mock our edges cases in a more declarative manner.

Conclusion

Hope you enjoyed this brief introduction. If you’re interested to learn more about testing consider following me or bookmarking this article! This is just the first part of the series.

In future articles, I’ll go over everything from setup to building tests to implementing this process in your pipeline to getting accurate code coverage reports.

More content at Relatable Code

If you liked this feel free to connect with me on LinkedIn or Twitter

Check out my free developer roadmap and weekly tech industry news in my newsletter.