Conference talks

Testing React Applications Like an Engineer

React Summit—June 17, 2025

Published August 7, 2025 (Updated August 7, 2025)

Talk: https://gitnation.com/contents/testing-react-applications-like-an-engineer

Code: https://github.com/AustinShelby/testing-react-applications-like-an-engineer

Slides: https://docs.google.com/presentation/d/1TEi-2g8kE8HcshRnryjTdILUSbYvUQXk4Ws42aNzTno/edit?usp=sharing

Just a few days ago, I had the pleasure of presenting this talk at the React Summit conference. The core idea? To approach software testing with the same rigor and precision as NASA engineers testing the Mars rover. We can learn a lot from their methodical approach to prevent unexpected errors in our own applications. My goal is to help you rethink how you test React applications with Playwright, focusing on practical solutions to common challenges.

Testing is seen as an afterthought

Often, testing in software development feels like an optional extra, something we get to only if time allows. We're bombarded with diagrams like the "test pyramid," each with its own opinion on the perfect ratio of unit, integration, and end-to-end tests. But in today's world of Next.js and complex React components, this rigid classification can be more confusing than helpful.

Consider a single React component that handles user authentication, redirects, and renders forms. Should we unit test it? Should it be an integration test? I argue it doesn't really matter. Instead of getting bogged down in test categories, we should focus on the user. Most applications have a primary goal: to get a user to sign up or make a purchase. Our testing strategy should align with these crucial user journeys.

Writing test cases feels tedious and challenging

Writing effective test cases can feel like a chore. Vague descriptions like "works" simply aren't enough. We need test cases that are precise, descriptive, and easily understandable by both technical and non-technical team members. This is where the principles of Behavior-Driven Development (BDD) come in handy, even if you don't use all the formal tools.

A well-written test case should read like a beautifully crafted user story. For instance, instead of just "register user," consider: "Register user with valid credentials and redirect to home page". This level of detail makes the intent clear.

Tools like Playwright's test.step allow us to annotate our tests with these descriptive steps, making test reports a fantastic way to document application functionality for everyone on the team.

Unstructured tests are hard to maintain

Imagine trying to quickly understand what a test does if it's a jumbled mess of code. We need a repeatable formula that makes our tests easy to read and write. The pattern I advocate for is Arrange, Act, Assert (AAA).

Here's how it works:

  • Arrange: Set up the test environment. This might involve resetting the database, seeding test data, or establishing authenticated sessions.

  • Act: Perform the actions the user would take. This includes navigating to pages, interacting with elements like input fields and buttons, and submitting forms.

  • Assert: Verify the expected outcomes. Check for correct states, element content, and even URL changes.

By applying the AAA pattern, our tests become incredibly clear.

TDD feels like a waste of time

The idea of Test-Driven Development (TDD) often evokes groans from developers. It can feel like an unnecessary overhead. However, I believe TDD is an incredibly powerful tool, especially when it comes to debugging complex issues.

When a bug report comes in, don't just jump into the code. Instead, use TDD:

  1. Reproduce the bug locally: Write a failing test that explicitly demonstrates the bug.

  2. Fix the bug: Make the necessary code changes until your newly written test passes.

  3. Deploy with confidence: With dedicated tests safeguarding against regressions, you can be sure the bug is fixed and you can deploy with confidence.

Key Takeaways

To recap, here are the main takeaways from my talk:

  • Focus on the User: Forget rigid test categories. Prioritize testing the most crucial user flows that drive your business goals.

  • Clear Test Cases: Write descriptive test cases that read like user stories. Use a shared language that both product and technical teams can understand. Annotate your tests with these descriptions to create living documentation of your application's functionality.

  • Structured Tests with AAA: Organize your tests using the Arrange, Act, Assert pattern. This makes them easy to write, read, and understand at a glance.

  • Embrace TDD for Debugging: Use Test-Driven Development as a powerful tool to solve complex problems. Reproduce bugs with failing tests, fix the issue, and then deploy with the confidence that your new test acts as a safeguard.

By adopting these engineering-minded approaches, you can build more robust, reliable, and maintainable React applications.


Austin Shelby

Austin Shelby

I am a product engineer, instructor, and public speaker with over half a decade of hands-on experience in the entire software development process. I am passionate about building high-performing web applications and sharing what I have learned along the way.