Cypress is a test automation tool for web applications that handles both end-to-end tests and component tests. Cypress component testing mounts a single component in isolation in a real browser, without starting the whole application. Its main strengths are live visual feedback while tests run, DOM snapshots when something fails and far more stable tests than emulation-based alternatives such as Jest.
Key Takeaways
- Cypress runs component tests in a real browser, which cuts down sharply on the flaky tests that unreliable DOM emulation produces in tools like Jest.
- A flipbook-style view shows a DOM snapshot before and after every test step, so finding the cause of a failure takes far less time.
- Test parallelization is a paid Cypress cloud feature, but teams can build it themselves, for example with a GitLab pipeline that spreads the suite across several runners.
- The Cypress Testing Library selects elements by label or test ID instead of brittle DOM paths, which makes tests more stable and closer to how users see the page.
What Cypress Is and What Teams Use It For
Cypress is a test automation tool built for web applications. It began as an end-to-end tool and was first pitched as a direct rival to Selenium, promising to be faster and more stable. Since late 2020 it also supports Cypress component testing, which lets you test a single UI component in a real browser without running the whole application.
The web focus is deliberate. Fewer native clients get built and more applications move to the browser, and Cypress was designed for exactly that world.
What sets Cypress apart from many alternatives is where the tests run. Cypress drives a real browser instead of emulating one. Tools such as Jest emulate the frontend, and that emulation gets shaky once the UI becomes complex. In practice you see it as huge timeouts: the element you are waiting for never shows up, or a button click simply goes nowhere.
Visual Feedback Changes How You Debug
While a test runs, Cypress shows you the interface. You watch what the tool is doing instead of reading a text message about a DOM node it could not find.
Other test runners in the Angular world, such as Karma or Jasmine, also show the application during a test, but they are slow. Cypress combines the speed of a test with that visual feedback. If a test cannot find a button, you see right next to the error what Cypress actually found on the page.
Dehla Sokenou singles out one feature: a kind of flipbook across the test steps. Hover over a step and you get a DOM snapshot from before and after it. Type text into a field, and the field is empty in the before snapshot and filled in the after snapshot. Click a delete button, and the element is there before and gone after.
“Cypress manages to combine the speed of a test with visual feedback. And that makes it very easy to track down bugs.”
(Dehla Sokenou)
Cypress Component Testing Puts the Test Pyramid Back on Its Base
Frontend teams have traditionally written lots of end-to-end tests and comparatively few unit or component tests. The result is a test pyramid standing on its tip. Component testing works directly against that.
A component test checks one component on its own, cut off from the rest of the application. The application does not need to be running. Cypress takes the existing code and mounts the component in isolation.
You isolate it with the usual tools of any component test framework: spies, mocks or an interceptor. The interceptor catches API calls, for example, and returns default values, so the component really can be tested as a single unit.
At first only React and Vue were supported, and Angular followed later. Stability was also an issue early on, even for React. Those teething problems are now considered solved.
End-to-End Tests and Component Tests in One Tool
Cypress covers both test levels and keeps them structurally separate. In the test code, the difference is small but clear.
An end-to-end test opens a URL with visit. A component test mounts the component directly instead. Both start with a describe block and use the familiar it structure, for example “it should delete” for a test case that checks whether clicking a button removes an element.
The file layout follows the same split. Component tests sit as spec files right next to the component, which is common practice in frontend code. End-to-end tests live in their own directory alongside the application.
You can move the end-to-end tests into a separate repository, but it comes at a cost: when the application changes, it is easy to forget the tests that live somewhere else. Same repository, different folder is usually the better choice.
Test-Driven Development in the Frontend Becomes Practical
Cypress works well for test-driven development in the frontend because the tooling makes it easy to write tests before the implementation. That tool support is what makes TDD hold up in day-to-day work.
The loop is concrete. You create an empty component, write a test and see that the expected elements are missing. Then you add them. Next you check, say, whether an input field is required, watch the test fail and add the property to the component.
The Cypress runner sits next to your IDE and reruns the test automatically every time the frontend changes. There is no play button to press. You start the runner once and see your progress as you go.
Why Cypress Is More Stable Than Jest, Even in the Pipeline
The biggest practical gain after moving from Jest to Cypress was a clear drop in flaky tests, the ones that pass one run and fail the next without any change to the code.
The migration went after the problem cases first: the long runners with high timeouts and the unstable tests. The result was that Cypress runs fast enough despite the real browser and produces noticeably fewer flaky tests. Otherwise, three tests that fail regularly can have you hitting the deploy button twenty times until it finally goes through.
Debugging in the pipeline benefits too. When a test fails, Cypress stores a DOM snapshot as a screenshot. That is how the team found out that some tests failed because toast messages were still covering other elements. A picture shows that at a glance. A text message does not.
How Many Tests Run, and How Fast
Tests run fast even though they use a real browser. Starting the runner takes a moment, and after that the actual execution is very quick.
In the project discussed, about 500 remaining Jest tests sit next to about 600 Cypress tests, so Cypress now has the majority. These frontend tests finish in under ten minutes, roughly as long as the backend tests.
Parallelization makes that possible. The frontend suite is split into smaller chunks, and each chunk runs on its own runner. Frontend and backend tests finish at about the same time, so packaging never has to wait for one side. If needed, more runners can be added.
Open Source with a Commercial Core, and Few Need It
Cypress is an open source project with a commercial company behind it. The open source version can be used with practically no restrictions.
A few features are reserved for the commercial version, such as test parallelization in the cloud, a management dashboard and flaky test management. You can build the parallelization yourself, though. In this case a GitLab pipeline splits the test suite and distributes it across several runners, no commercial cloud required.
A quick show of hands in the audience confirmed the pattern: many people use Cypress, and nobody raised a hand for the commercial version. For many teams the open source version is a good place to start, and the extra features can be bought or built later if needed.
Where Cypress Reaches Its Limits
Cypress is a tool for web applications, and that is also where its limits are. If you have native clients next to the web application and want to test them end to end together, Cypress is the wrong tool.
Multiple tabs are another weak spot. An application that works across several tabs can only be covered with workarounds, and in those cases Cypress often is not a good fit. For a Java backend, a different tool such as JUnit remains the right choice anyway. Use tools where they fit, and do not force them.
Then there is the pace of web development. Playwright is a serious alternative, and the field moves faster than anyone can keep track of. Nobody can promise that Cypress will still be the tool of choice tomorrow.
Tips for Getting Started
Two things help when you start with Cypress: a bit of configuration and the right helper library. Some things do not work straight out of the box, so it pays to look through the configuration options.
The clearer recommendation is the Testing Library for Cypress. With it you write tests from the user’s point of view instead of through DOM paths. You look for a button with a given test ID or label, or an input field with a given label.
That style reads more naturally, and the resulting tests are much more stable. Upgrading between versions is easy as long as you keep up. What you should avoid is letting updates pile up and skipping migration steps.
Frequently Asked Questions
Why Are Frontend Tests with an Emulated Browser Environment Considered Unstable?
Frontend emulation becomes unreliable with complex user interfaces: elements you’re looking for don’t appear, clicking a button has no effect, and this is compensated for with extremely long timeouts. Cypress, on the other hand, runs the tests in a real browser. During the described migration from Jest, the first issues addressed were precisely the long-running and unstable tests, and the number of flaky tests dropped significantly.
Why is the test pyramid often turned upside down in front-end development?
Because teams have traditionally written a large number of end-to-end tests and relatively few unit or component tests. Component testing counteracts this: A single component is mounted in isolation; the application does not need to be running for this. The usual methods are used for isolation, namely spies, mocks, or an interceptor that intercepts API calls and returns default values.
Can Test-Driven Development be implemented in practice in the frontend?
Yes, if the tools make it easier to write tests before implementation. The process is straightforward: build an empty component, write a test, identify the missing elements, and add them. Then, for example, you check whether an input field is required, see the test fail, and add the property. The runner runs alongside the IDE and restarts automatically with every change.
How do you figure out why a test fails only in the pipeline?
Through images rather than text messages. When an error occurs, Cypress saves a DOM snapshot as a screenshot. In one project, this revealed that tests were failing because toast notifications were still displayed over other elements and obscuring them. A simple message about a missing DOM node would not have revealed this cause.
Does testing in a real browser slow down the continuous integration pipeline?
No. The main time cost comes from the initial startup of the runner; the actual execution runs quickly. In the project described, there were about 500 remaining Jest tests and about 600 Cypress tests running side by side, and the frontend tests took less than ten minutes, roughly on par with the backend tests. This was made possible by distributing the suite across multiple runners.
Do you need the paid version for parallel test execution?
No. As of 2023, the commercial version reserved features such as cloud-based parallelization, a management dashboard, and flaky test management. In the case described, parallelization was implemented in-house: A GitLab pipeline split the test suite into smaller chunks and distributed them across multiple runners. A poll of the audience showed that many were using Cypress, but no one was using the commercial version.
Can Cypress also be used to test native clients or a Java backend?
No. The tool is designed for web applications. If you want to perform end-to-end testing of native clients alongside the web application, it’s better to use a different tool, and JUnit remains the appropriate choice for a Java backend. Even applications with multiple tabs can only be covered using workarounds. By 2023, Playwright had also become a serious alternative.
Why are tests that locate elements via DOM paths fragile?
DOM paths break as soon as the structure of the user interface changes. Instead, the Cypress Testing Library selects elements from the user’s perspective: a button via a test ID or a label, an input field via its label. This approach is more intuitive and results in more stable tests. A second tip for getting started: don’t neglect updates and don’t skip any migration steps.


