Introduction to Cypress Automation Testing
Why is Regression testing important?
“A good programmer is someone who always looks both ways before crossing a one-way street” – Doug Linder.
One of the most effective ways to “look both ways” as a programmer is to implement automated testing. This can come in the form of integration tests, end to end tests, or unit tests (there are other types but these are the most common).
Unit tests are for testing low level parts of an application like methods or functions. They can be very helpful for catching bugs early on because they are so focused on individual modules of code. Unfortunately this means they might not catch every error because they don’t cast as broad of a net as other testing types. A simple way to think of unit tests is testing that a unit has the proper output for a given input. For example, if you created a calculator application, a single unit test might test the add function to make sure 2+2=4. Some popular JavaScript unit testing frameworks are Jest, Storybook and Cypress (Cypress can be used for all 3 types of testing, while Storybook is mostly used for unit/integration testing).
Integration Testing involves testing of multiple combined modules. Examples of this would be a UI component made up of methods, styling and component code. Another example could be an endpoint. The main advantage of integration testing is that it tests how various modules interact. The individual modules might work fine individually during testing but the interaction between modules might cause bugs. Integration testing is closer to how your actual application works but is still narrow enough in scope that you can identify the root cause of bugs.
Last is end to end testing. E2E testing is exactly what it sounds like. It tests the entire app from front to back just like an actual user would. Because E2E casts such a broad net it has the potential to find a wider variety of bugs than more focused testing like unit and integration. This also comes with the disadvantage of not always knowing what caused the bug. The problem could be anywhere in your tech stack (UI, an endpoint or any modules in between). When investigating an E2E test it takes a bit more work to figure out what exactly caused the failure.
The differences between different types of testing can be a bit subjective. One person’s idea of a unit test might overlap with another person’s idea of an integration test. Now that you have an overview of the most common automated testing types I will give a detailed overview of a tool that has grown a lot in popularity recently.
What is Cypress?
Cypress is an all in one, end to end testing framework meaning you do not need any other frameworks or libraries for it to work (there are however plenty of helpful libraries you can add). Remember, end to end tests handle the application’s workflow from the beginning to the end and test everything at once mimicking as if someone is actually using the application (you can use Cypress for the other types of tests as well from unit testing to integration testing with stubbing, more on that later.) Cypress is open source, written in JavaScript, and all the code runs in the browser itself. You can use Cypress to test any framework or website. It uses Chrome by default but with an option to use Firefox. It is most comparable to Selenium and Puppeteer.
Why Cypress?
One of Cypress’s coolest features is that it takes snapshots at each step and you can hover your mouse over each stage to see what happened. These snapshots are not just images. When you select a snapshot in your test history, the page itself reverts to its previous dom tree. This means you can interact with the page and more easily find out exactly what went wrong. In addition to snapshots, Cypress includes a video feature which optionally stores a video of your tests being carried out. This feature is especially useful when included in your CI/CD pipeline.
When testing a full stack app, you’re usually waiting for requests to finish and DOM elements to load before your test assertions can be made. Thankfully with Cypress you usually do not need to write any logic and wait for elements to show up. In most cases, Cypress will automatically wait for an element to show up. The most common example is the cy.get() command. If I use cy.get(‘#some-id’) cypress will wait for this element to show before performing an assertion or continuing in the code.
One of the areas I have been using Cypress the most is accessibility. Cypress does not include specific accessibility features natively. It does however support 3rd party plugins like cypress-axe which replicates the full axe feature set. This plugin makes tricky tests like color contrast significantly easier. Simpler tests like checking for an aria-label can be done with native Cypress commands.
Below is a list of the different arguments that can be used for axe from the axe API:
One last feature of Cypress is called stubbing. Stubbing is essentially mocking requests and responses. As shown in the image below cy.route() takes in a set of parameters to shape your http response or request.
Stubbing can have a number of benefits. A mocked response can be much faster than actual communication with a server. It also alleviates the need for seeding your database and is useful for recreating server errors and special conditions that may otherwise be difficult to recreate. You can even choose the amount of server delay.
Overall, I’ve found Cypress to be an incredibly useful and easy to pick up tool for end to end testing. Most of my needs have been covered by just a few built-in commands and when I’ve needed more, the support for third party packages has been sufficient. That being said, Cypress does have its shortcomings. Occasionally, parts of the app do not load quickly enough and the tests fail due to insufficient default wait time. Cypress then times out while it waits for the element to show up. Another inconsistency I have run into while using Cypress is keyboard behavior. Simulated keypresses frequently don’t work and tabbing through elements can be challenging. Despite these faults, I would still recommend Cypress to anyone who needs end to end testing for their app.
Sources:
https://applitools.com/blog/41-awesome-quotes-about-software-testing/
https://www.valentinog.com/blog/jest/
https://jondot.medium.com/how-to-test-a-full-react-app-using-nothing-but-storybook-15f4c584e30a
Also read: Visual Regression Testing with WebdriverIO
Author
ALEX KITE
Alex Kite is a Software Engineer at Crest Data specializing in React and JavaScript. Before Crest, Alex was a Front End Engineer at an early stage startup. He has a degree in Systems Engineering from University of Illinois at Urbana-Champaign and graduated from App Academy in San Francisco. In his free time he enjoys skiing and fantasy football.