at logo

Why you should be UI testing with Cypress

Automated UI testing is on the rise, automating the functional testing of your application is like having a bundle of manual testers prodding and poking at your application making sure it works the way you said it would.

My previous experience of automated UI testing was with Selenium and Xpath, yes I know xpath, it was horrible to code and the tests were flakey and hard to implement on a modern single page application.

Often these tests are done after the bulk of development has been done as an extra safety net to catch any braking changes, and they work.

There are a few problems with selenium though, its c# or Java and its likely your frontend developers don't know either of these languages, possibly these tests are the responsibility of the test team and the feedback loop to triaging issues and fixing is slow. Selenium tests are slow, cypress tests are javascript and ran with your app, cypress can also test as the app is rendered making them very fast.

Along comes Cypress off the back of the release of Puppeteer a node library with an api to control a headless chrome browser, Cypress allows you to write UI tests in javascript using a familiar api like jquery of old or css selectors to access elements, but with built support for the asynchronous nature of a modern single page application, making the barrier and speed to writing automated UI tests very low.

Importantly this enables your developers to write these tests themselves with the ability to run them locally quickly and easily providing a feedback loop that also aids the development process.


Cypress is built on top of mocha and existing and popular javascript testing framework that most front end developers should be familiar with.

it("contains type", () => {



  cy.get(".todo-list li").should("have.length", 2);

Tests look like normal unit tests, it almost looks too easy, thats because cypress has built in flake resistance, it will wait on state changes, elements being enabled or animations finishing, no need to tell cypress it has to wait.

The test above will visit the url, wait for page load and check the text 'type' is found, the test will fail if it cannot find 'type', theres no need to assert.

it("types email", () => {

Here we are testing we can type in an email, the get method finds elements by selector and will automatically retry until it finds the element or fail the test.

it("todo items", () => {
  cy.get(".todo-list li").should("have.length", 2);

We can use assertions to check we have the correct amount of items in our list.

The tests are simple to write and there's no funny wait conditions or hacks to write them reliably as cypress handles this for us.

Cypress has built in support for mocking and intercepting api calls to return predefined fixtures.

There is also the ability to record screenshots and video of your test runs which you may want to publish as part of you build/deployment process.



Cypress also comes with a nice gui allowing you to view in great detail your test run and also debug them right in the browser.

Here you can see a test run with detailed output of the cypress commands called and xhr calls made, you can navigate back through a test run and see what the UI was at that time allowing you to debug any issues. Theres also a handy select item feature which will output a get selector to yous use in your test.

You can of course run cypress headless as part of your CI/CD process.

Eco system

There is also a rich eco system of plugins available, allowing you to write your tests in BDD, output a rich test report, automatically test your apps accessibility using axe or even run visual regression testing.

There's now no excuses not to be doing automated UI testing, and in most cases will be more helpful in eliminating bugs than traditional unit testing depending on the nature of your application.

Happy testing.
Site published