One of the most common challenges engineers face when dealing with shared components is reliability. Have you ever run into a situation where something you built suddenly stopped working after making what you thought was a "small update"? Today, I want to talk about how we ensure we're not breaking the UIs we're building.

Someone dealing with unwanted UI changes

A common solution to build more reliable UIs is to write automated tests and run them frequently, preferably on each iteration. This way, we ensure that our UI will behave as expected. In our React world, this is usually done by writing Jest tests or stories in Storybook (our preferred documentation tool). Interaction tests are run once the story finishes rendering and emulates the exact steps a user would take to interact with the component. They are great since they allow us to see the components in real-time, allowing for more efficient debugging.

Interaction testing with Storybook

We already know that our tests should validate the component's behaviour, but how can we validate the component's visual changes? How do we make sure the component receives the visual update we expected? More importantly, how do we know our changes didn't impact other components?

This is usually done by running regression tests. While this is usually fine when working with components that are used in only a few places, it gets tricky when components are reused multiple times in multiple pages. Running manual regression tests can be very time-consuming. This is why automated regression testing is key to enabling faster UI shipping. We adopted Chromatic to run these automated regression tests because -

  • It works in pairs with Storybook. 
  • It deploys our component stories as part of our CI pipeline and takes snapshots
  • It then finds and highlights any visual changes that were introduced in our latest code. 
  • It allows us to review our changes side by side and accept or reject them. While a review is pending, or if a change is rejected, Chromatic prevents us from merging any code, ensuring we're not breaking our UI.
UI changes highlighted in green

Another great feature of Chromatic that we're taking advantage of is called TurboSnap. It speeds up build time using a dependency graph and identifies component files that have changed, then intelligently snapshots only the stories associated with those changes. Our CI pipelines can sometimes feel slow since they take care of building, linting, testing, etc.. TurboSnap definitely helps us and provides a better developer experience by speeding up the Chromatic job.

We not only use Chromatic in our component library but also in our consuming apps built with React (maybe not all of them yet, but we're getting there). This way, when updating our libraries or third-party dependencies, we're also able to catch any unwanted changes before our code gets deployed anywhere. All of this, without having to run time-consuming manual regression tests.

Adopting our current testing strategy did not only mean adopting a new tool, it also required us to adopt a new process for reviewing changes. It was not easy at first, we needed to convince multiple teams to get on board with the approach. It was also not easy to set up either. It took several month to get a pro account for example. But in the end, it was all worth it. We are now building more reliable UIs that we can ship faster.

Author: Pierre Plantié