Skip to main content

Search...

Cypress

Cypress instead of Selenium: Why real browser testing is more stable, how component testing saves the test pyramid and where the tool's limits lie.

8 min read
Cover for Cypress

Cypress is a test automation tool for web applications that covers both end-to-end testing and component testing. Component testing mounts individual components in isolation in the real browser without launching the entire application. The core advantages are visual real-time feedback during test execution, DOM snapshots in the event of errors and significantly more stable tests compared to emulation-based alternatives such as Jest.

Key Takeaways

  • Cypress executes component tests in the real browser, which significantly reduces flaky tests caused by faulty DOM emulation, such as occurs with Jest.
  • Cypress’ visual flipbook feature shows a DOM snapshot before and after the action for each test step, massively reducing debugging time.
  • Test parallelization, a paid cloud feature from Cypress, can also be implemented in-house, for example via GitLab pipelines with multiple runners.
  • The Cypress Testing Library makes it possible to select elements via labels and test IDs instead of fragile DOM paths, which makes testing more stable and user-oriented.

What is Cypress and what is it used for?

Cypress is a test automation tool for web applications. It started out as an end-to-end tool and initially positioned itself as a direct competitor to Selenium, with the promise of being faster and more stable.

The focus on the web is no coincidence. There are fewer and fewer native clients and more and more web applications, and Cypress is built precisely for this world. At the end of 2020, a second application area was added: Component Testing.

The decisive technical difference to many alternatives lies in the execution. Cypress tests in the real browser instead of emulating a browser environment. Tools such as Jest emulate the front end, and this emulation becomes unstable with complex interfaces. In practice, this manifests itself in extremely long timeouts because the elements you are looking for do not appear or a button click comes to nothing.

Why visual feedback changes debugging

Cypress provides a visible image of the interface during test execution. You can see directly what the tool is currently doing and not just a text message about a DOM node not being found.

Other test environments in the Angular environment, such as Karma or Jasmine, also show the application during testing, but are slow. Cypress combines the speed of a test with visual feedback. If a test fails to find a button, you can see next to it what Cypress recognizes on the surface.

Dehla Sokenou highlights one feature in particular: a kind of flip book over the test steps. You move the mouse over a single step and see a DOM snapshot before and after. If you enter text in a field, it is empty in the before snapshot and filled in the after snapshot. If you press a delete button, the element is there before and gone after.

Cypress manages to combine the speed of testing with visual feedback. And that makes it very easy to troubleshoot.

Dehla Sokenou

Component Testing turns the test pyramid right side up again

Traditionally, a large number of end-to-end tests are written in the frontend and comparatively few unit or component tests. This means that the test pyramid is often upside down. Component testing counteracts precisely this effect.

With component testing, you test an individual component separately from the rest of the application. The application does not have to be running for this. Cypress takes the existing code and mounts the respective component in isolation.

Isolation works using the usual means of component testing frameworks. You can use spies, mocks or an interceptor. The interceptor intercepts API calls, for example, and returns default values so that the component can really be tested as a single artifact.

Support was initially limited to React and Vue, Angular was added later. Stability was also a problem at the beginning, even for React. These teething troubles are now considered to have been eliminated.

End-to-end and component testing in the same tool

Cypress covers both test levels and separates them cleanly in terms of structure. The practical difference in the test code is small, but clear.

In end-to-end testing, you navigate to a URL with a visit. In component testing, you mount the component directly instead. Both variants start with a describe for the description and use the typical it structure, such as “it should delete” for a test case that checks the deletion of an element by clicking a button.

The storage also follows this separation. Component tests are stored as spec files directly next to the component, a common standard in the frontend. End-to-end testing is stored in a separate directory parallel to the application.

It is technically possible to outsource the end-to-end tests to a separate repository, but this has one disadvantage: if the application changes, it is easy to forget to adapt the outsourced tests. Same repository, different location is therefore usually the better choice.

Test-driven development in the frontend becomes tangible

Cypress is suitable for test-driven development in the frontend because the tool support makes it easier to write tests before implementation. It is precisely this support that is the prerequisite for TDD to work in everyday life.

The process is concrete. You build an empty component, write a test and see that the expected elements are missing. Then you add the elements. In the next step, you check whether an input field is a mandatory field, for example, the test fails and you add the property to the component.

The Cypress Runner runs alongside the IDE and automatically restarts the test every time a change is made to the frontend. You don’t have to press a play button first, just start the runner once and see how far you have got.

More stable than its predecessors, even in the pipeline

The biggest practical gain after switching from Jest to Cypress is significantly fewer flaky tests. Flaky tests are the indicators that sometimes pass and sometimes fail without changing anything in the code.

During the migration, the problem cases were specifically addressed first: the long runners with high timeouts and the unstable tests. The result: Cypress runs fast enough despite the real browser and produces noticeably fewer indicators. Three regularly failing tests can otherwise lead to you pressing the button twenty times during deployment until it runs through.

Debugging in the pipeline also benefits. In the event of an error, Cypress saves a DOM snapshot as a screenshot. This revealed that some tests failed because toasts were still on top of other elements and obscured them. An image shows this immediately, a plain text message does not.

How many tests are running, and how fast?

The speed of the test execution is high, although testing is carried out in the real browser. The one-time start-up of the Runner takes a while, the actual execution then runs very quickly.

In the aforementioned project, the ratio is around 500 to 600 tests in comparison between remaining Jest tests and Cypress tests, although there are now more Cypress tests. These front-end tests run for less than ten minutes, about the same time as the back-end tests.

This is made possible by parallelization. The frontend test suite is split into smaller chunks, each chunk running on its own runner. This means that frontend and backend tests are completed at roughly the same time, so that packaging does not have to wait for either side. Additional runners can be added if required.

Open source with a commercial core, but rarely used

Cypress is an open source project with a commercial company behind it. The open source version can be used practically without restrictions.

Some functions are reserved for the commercial version, such as test parallelization via the cloud as well as a management dashboard and flaky test management. However, parallelization can be mapped yourself, in this case via a GitLab pipeline that splits the test suite and distributes it across several runners. The commercial cloud is not needed for this.

A small survey of the audience confirmed the pattern: many people use Cypress, no one registered for the commercial version. For many teams, the open source version is a good starting point, and the additional features can be booked or built as required.

Where Cypress reaches its limits

Cypress is a tool for web applications, and that is exactly where its limits lie. If you have native clients in addition to the web application that you want to test end-to-end together, Cypress is the wrong tool.

Multitabbing is also a tight squeeze. An application with several tabs can only be covered with workarounds, and in such cases Cypress is often not suitable. For a backend in Java, another tool such as JUnit is the right choice anyway. Tools should be used appropriately, not forced.

Then there is the speed of web development. Playwright is a serious alternative, and the field is changing faster than you can sift through everything. Whether Cypress will still be the tool of choice tomorrow cannot be guaranteed.

Tips for getting started

Anyone starting with Cypress should bear two things in mind: a little configuration and the right help library. Some things don’t work straight out of the box, so it’s worth taking a look at the configuration options.

The clearer recommendation concerns the Testing Library for Cypress. You can use it to write tests from the user’s perspective instead of via DOM paths. You are looking for a button with a specific test ID or with a specific label, or an input field with a specific label.

This way of writing is more intuitive and the resulting tests are much more stable. Migration between versions is easy as long as you keep doing it. What you should avoid: Leaving updates for a long time and skipping migration steps.

Share this page

Related Posts