Wrapito: a testing philosophy as a tool

Sergio Peris Perez
Mercadona Tech
Published in
5 min readFeb 9, 2022

Does your team have a testing philosophy?

A few years ago, in the Enzyme era, before Testing Library even existed, we started to notice that we had some problems testing our frontend apps.

By then, we felt we had a gap between the component tests, using Enzyme, and the e2e tests, using Cypress. We didn’t like the existing options to test user interactions and side effects.

First, we explored filling that gap by overusing Cypress. As you might have experienced, Cypress tests tend to be slower, harder to write, and harder to maintain.

Later, we tried to fill that gap by writing tests with Enzyme. But we noticed that it made us have much more boilerplate in the setup or arrange step.

That’s why we started working on what we now call Wrapito.

What is Wrapito?

Wrapito is a library that helps test side effects such as user interactions and network responses. The goal is to get the most confidence possible from easy to write and semantic tests.

For more details about our testing philosophy, check As a frontend developer I do outside-in TDD by default from my colleague, Alex.

Facts about Wrapito

  • ̶S̶e̶l̶l̶i̶n̶g̶ ̶l̶e̶c̶h̶u̶g̶a̶s̶ testing side effects since 2018
  • Checking that our 15 frontend apps let us deliver 8000+ orders per day
  • Giving confidence to 14 Frontend Engineers from MercadonaTech
  • Using it in thousands of tests
  • Used during the migration from Enzyme to Testing Library
  • React evolved from classes to functions to hooks, but our tests kept working

Why do we find it helpful?

We found that the outside-in approach is what has given us more value when it comes to testing side effects caused by user interactions. A backend colleague, Jponzvan, has written about His vision about outside-in testing as a Backend Developer. As frontends from MercadonaTech, we agree on most of the benefits he mentions.

Testing from the outside gives us more confidence. Instead of testing small separated parts of our code, we test the app as if the user is using it.

We test behavior, not code.

Testing side effects: changes in the UI

This is the only side effect that the user is aware of. There are two possible ways of causing this kind of side effects:

  • By the user interacting with the app
  • By communicating through the network

Let’s imagine we have a login on the home page.

Login from the home page

It waves the user when the login succeeds and warns the user when it fails.

Login succeeds and login fails

What are the side effects we would want to test?

The user gets a wave or gets warned, depending on whether the login succeeds or not

Testing side effects: network communication

It isn’t something the user will notice, but we still need to test it. Otherwise, we won’t know whether our app communicates well with other systems or not.

For this purpose, wrapito has extended jest so that tests checking this can be more semantic.

Let’s continue with the example of the login form that we used in the last section. Imagine we can also do a login from the checkout page.

Login from the checkout page

Now, whenever a user does the login, we call an endpoint to store the user’s data and the place where they did the login.

What are the side effects we would want to test?

After a successful login, we send information about the place

Writing semantic tests

The public API is composable and extensible. The only method that should be the last is the mount one. The order doesn’t matter except for the mount.

Different projects using Wrapito might have different opinions about what is semantic. That’s why one can extend Wrapito and add new methods that make more sense for a given context.

In order to make the previous examples more semantic, we can add withLogin and withFailingLogin methods.

Extending Wrapito by adding withLogin and withFailingLogin methods

Now, we can update our previous examples as follows:

Using Wrapito after extending its API

Recap

Our tests don’t know anything about components, external libraries, or abstractions. These are implementation details and have information about how the code is. Instead, we like to talk about how the user gets its value or how our app communicates with other systems.

Did you notice we didn’t mention redux or react-router about external libraries? We use them and other libraries in our projects. But it isn’t present in our tests because users don’t get value from it.

It doesn’t mean we don’t test our components. We do test them. But, we like to do so in the Design System libraries that we share across the different teams.

Disclaimer

This is what has worked for us and is part of our learning of the last years, but it might not work for you or your team.

As we created it to help us, it only works if you use the same stack as we do. The goal is to end up making it as agnostic as possible in the future. But, for now, for UI changes, it needs React and Fetch for network communication needs.

We would like to hear about your testing philosophy and how it has helped your team. Let me know by leaving a comment or DM me on LinkedIn.

Btw, we are hiring Senior Backend Engineers and Backend Engineers. We also have many other open roles in both Valencia and our new Tech Hub in Madrid.

--

--