Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
Level up your automation testing skills with our comprehensive Cypress Testing tutorial. Don't miss out on the opportunity to master this powerful tool.
Join the DZone community and get the full member experience.
Join For FreeCypress is an open-source, full-featured, and easy-to-use end-to-end testing framework for web application testing. Cypress is a relatively new player in the automation testing space and has been gaining a lot of traction lately, as evidenced by the number of Forks (2.2K) and Stars (36.6K) for the project.
Unlike Selenium, Cypress is preferred by front-end developers and automation testers who are well-versed in JavaScript. However, Cypress is slowly catching up with Selenium, and the six-month download trend comparison of Cypress and Selenium indicates that the war between the two frameworks will continue to intensify in the coming months.
If you're a developer looking to automate the testing of your application, this Cypress testing tutorial walks through the basics of Cypress, how to use it for end-to-end testing, and more.
What Is Cypress?
Cypress is a renowned end-to-end testing framework that enables front-end developers and test automation engineers to perform Web and API testing. Since it is a JavaScript-based test automation framework, it is widely preferred by the developer community. Cypress is a testing tool that is targeted toward developers and QA engineers. It uses a unique DOM manipulation technique and operates directly in the browser. It supports various browser versions of Google Chrome, Mozilla Firefox, Microsoft Edge(Chromium-based), and Electron.
The Rise of Cypress Framework
Cypress is a comparatively new testing platform that aims to overcome the challenges of automated front-end testing for applications built with React and AngularJS. It's a quick, easy, and reliable tool for testing these applications by running them in their actual browser environments. Since Cypress executes tests on a real browser instance, you wouldn't need to download browser drivers, unlike Selenium.
Check out The State of JS 2021 Cypress testing data on the basis of developer Satisfaction, Interest, Usage, and Awareness.
Satisfaction: Since 2019, Cypress has shown a slight dip in the level of satisfaction for developers. Cypress shows a dip from 93% in 2019 to 92% in 2021.
Interest: The interest shown by the developers for using the Cypress testing framework also showed a fall from 76% in 2019 to 72% in 2021.
Usage: The State of JS 2021 survey shows a significant rise in terms of usage from 26% in 2019 to 43% in 2021.
Awareness: As per the State of JS 2021 survey, there is a significant rise in the awareness of the Cypress framework amongst the developers from 63% in 2019 to 83% in 2021.
Under the Experience Over Time section of the State of JS 2021 survey, it also shows:
For 2019: Around 28.5% of developers have shown interest in using Cypress for their testing needs. The lack of awareness of the Cypress framework is at an all-time high, i.e., 36.9%. Along with this, only 23.9% of developers would like to use Cypress again in the future.
For 2020: The developer interest in using the Cypress testing framework has shown a slight increase as compared to the previous year and now represents 29.9%. There is a significant decrease in the lack of awareness for the Cypress testing framework, and is now at 26.2% only. Along with this, the percentage of developers and testers who would like to use Cypress again has significantly increased from 23.9% to 32.9%.
For 2021: The developer's interest in using the Cypress testing framework is stagnant for this year. The awareness of the Cypress framework among the developers and testers has significantly increased over the past three years. Along with this, the percentage of developers and testers who would like to use Cypress again is at an all-time high of 39.1%.
Why Cypress?
Modern Tool
Cypress is a Javascript-based automation tool that runs in the browser and on Node.js. It is based on Mocha and Chai and is written in Javascript. This makes Cypress fast and reliable for testing almost every website, not only those written in Javascript.
Fast to Setup
Cypress has no additional requirements for a standard installation. You do not need any libraries, testing engines, servers, drivers, or wrappers. Cypress doesn't require configuration or additional choices to be made.
Fast to Implement and Debug
By providing a Domain Specific Language that is not pure JavaScript, Cypress makes it easier for JS developers in the automated testing community to start using the framework. It is also an approachable tool for experienced QA engineers who are already working with other testing frameworks.
The debugging process in Cypress is streamlined and simple. With native access to every single object, you can easily analyze errors within your application. You can debug your application directly with Chrome DevTools while the tests are being executed in the browser.
Fast to Execute
Cypress provides a fast, easy, and reliable way to test your application. It automatically waits for the DOM to be loaded, so you don't have to implement additional waits or set up explicit or implicit waits. Cypress follows everything that happens in your application synchronously—it knows when the page is being loaded and when elements send events.
Features of Cypress Testing
- Cypress gives the ability to capture snapshots during a test run. Hovering over a command in the Command Log displays an event summary that describes each event in a test step.
- Cypress enables easy debugging from the Developer Tools. Errors are displayed, and stack traces are available for each error.
- Cypress ensures that synchronization techniques like sleep and wait are unnecessary in test cases. Instead, it waits for actions and checks before proceeding ahead.
- Cypress ensures the characteristics of the functions, timers, and server responses. This is critical from a unit testing point of view.
- Cypress can capture a screenshot of the browser window on failure by default. It also records a video of your entire test suite execution running from its command-line interface.
- Because of its architectural design, Cypress provides quick, steady, and dependable test execution results compared to other tools in automation.
- Cypress has a good error logging message that describes why our script failed.
- Cypress has an easy-to-use API and requires no configuration to start with.
- Cypress supports only JavaScript, which makes it a preferred choice for developers as well. However, this adds to the learning curve for testers or developers who aren't familiar with JavaScript.
Cypress Drawbacks
- Requires compulsory installation of NPM packages as it is limited to JavaScript only.
- Does not support multiple tabs while running tests.
- Does not supports a very broad range of browsers like Selenium WebDriver does.
- Sole reliance on JavaScript multiplies syntax complexities.
- Cypress community is not that large, and there are not many Cypress experts who can help you out with complex issues.
Cypress Architecture
Cypress tests run inside the browser, allowing Cypress to modify the browser's behavior by listening to the incoming network requests and altering them on the fly. In addition, cypress tests have a lower flakiness rate than Selenium tests since Cypress does not use WebDriver. Instead, spies and stubs can be used at run time to control the behavior of functions and times. Now, let's look at Cypress architecture.
Cypress executes on a NodeJS server that invokes the tested browser (one of the iFrames on the page) for running Cypress tests, which are encapsulated in another iFrame. This can be accomplished by running both the Cypress and NodeJS processes on the same session, thereby allowing Cypress to mock JavaScript global objects. In addition, NodeJS's running process also acts as a proxy that helps intercept HTTP requests, helping Cypress mock these requests during testing.
As of the time of writing, Cypress supports Chrome-family browsers (including Electron and Chromium-based Microsoft Edge) and Firefox.
Selenium's architecture uses the WebDriver component to communicate with the Browser Driver, which then interacts with the actual browser. The WebDriver routes communications between all its components, making sure that information can flow back to the WebDriver from the actual browser. Developers will need different Browser Drivers for different types of browsers.
On the other hand, Cypress executes tests inside the browser, making it possible to test code in real-time as it runs in the browser. Cypress runs on a server process, which makes it possible for Cypress to execute code in the same run loop as the application. Cypress, the test runner created by Facebook, is able to respond to application events in real time because it constantly communicates with the server process. This also allows Cypress to interact with OS components for tasks outside of the browser, such as taking screenshots.
Browsers Supported by Cypress
Cypress supports the following browsers:
- Chrome
- Chrome Beta
- Chrome Canary
- Chromium
- Edge
- Edge Beta
- Edge Canary
- Edge Dev
- Electron
- Firefox
- Firefox Developer Edition
- Firefox Nightly
Supported Browser Versions
- Chrome 64 and above
- Edge 79 and above
- Firefox 86 and above
Supported Cypress Versions
With the newer versions of Cypress releasing, to gain the most from recent improvements and bug fixes, it is recommended that your test scripts use the latest version. The .latest format defines the Cypress versions, ensuring that your test scripts always use the latest minor version.
Selenium vs. Cypress: A Detailed Comparison
Features | Selenium | Cypress |
---|---|---|
Programming Languages | Python, C#, Java, Python, Ruby, JavaScript | JavaScript |
Browser Support | Chrome, Firefox, Internet Explorer, Microsoft Edge, Safari | Brave, Chrome, Edge, Firefox, Electron |
Test Frameworks | PyUnit, JUnit, TestNG, JBehave, Behave, Gauge, Specflow, NUnit, Robot, and more. | Mocha JS |
Test Setup | Selenium Grid Server and browser drivers have to be installed in the test machine. Setup is different for a cloud-based Selenium Grid, where only browser drivers have to be installed on the test machine. | Node JS, Mocha JS, and Cypress have to be installed on the test machine. |
Area of Testing | Unit testing, security testing, and integration testing. | Unit testing, security testing, and integration testing |
Integrations | Wide range of integration options – CI/CD tools, reporting tools, and more. | Limited integration support with CI/CD tools when compared to Selenium. |
Driver Dependencies | An appropriate browser driver has to be installed so that the test script can talk to the corresponding web browser. | No driver dependency. |
Parallel Testing | Supported | Supported |
Multi-Tabs | Supported | Not Supported |
Multiple Browser Instances | Supported | Not Supported |
Execution Speed | Slow | Fast as Cypress scripts are executed within the browser. |
Time Travel | Not Supported | Supported |
Real-time Reloads | Not Supported | Tests are reloaded when any change is made in the test implementation. |
Automatic Waiting | Not Supported | No requirement to add waits or sleep in the tests. Cypress automatically waits for commands and assertions before moving to the next instruction. |
Default Screenshots and Videos | Not available by default, the developer has to write code to achieve the same. | Available by default. |
Network Traffic Control | Not Supported | No network lag as tests are executed within the browser. You can control, stub, and test edge cases without any involvement of the server. |
Access to Elements Outside the DOM | Access only to the elements in the DOM. | A unique DOM manipulation technique helps Cypress in getting access to DOM elements, timers, service workers, and more. |
Documentation and Community | Mature Community with multiple points of support. Average Documentation. | Growing Community, Excellent Documentation. |
Remote Execution | Supported. Cloud-based Selenium Grid from LambdaTest can be used to expedite cross-browser testing and automation testing. | Not Supported |
Spies, Stubs, and Clocks | Not Available | Cypress lets you control the behavior of functions, timers, and server responses with ease. |
Mobile Testing | Mobile Testing with Appium | Not Supported |
Test Flakiness | Tests can be flaky. | With Cypress, tests are expected to be non-flaky. |
Cypress Learning: Best Practices
After working with Cypress UI testing, here are some of the best practices you should use to avoid anti-patterns in your Cypress automation tests:
1. Login Programmatically
To test most of the functionalities, a user needs to be logged in.
- Anti-Pattern: Not sharing shortcuts and using the UI to log in.
- Best Practice: Test your code in isolation, programmatically log into the application and take control of various states in the application.
A very common mistake made by testers is that they often log in to a web page that requires authentication and then redirect to the page that needs testing. But the problem with this approach is that it uses your application UI for authentication, and after the authentication is done, it redirects to the page you want.
The way to deal with this would be to log in programmatically. To sign in programmatically, we need to use the Cypress request command cy.request(). This command makes HTTP requests outside of the browser and can bypass CORS restrictions and other security measures.
2. Using Best-suited Selectors
All tests we write should include selectors for elements. CSS classes may change or be removed, so we must use resilient selectors that can accommodate those changes.
- Anti-Pattern: Using selectors that are highly brittle and subject to change.
- Best Practice: Use data-cy attributes to provide context to selectors and keep them isolated from changes in CSS or JavaScript.
The Selector Playground follows these best practices automatically. It prefers elements with data-cy data-test when determining a unique selector because it has the highest priority. We should use data-cy to keep consistency.
When to use cy.contains()?
When you need to select an element with the text present on the page, you can use cy.contains(). However, you must ensure that the selected text always exists.
3. Assigning Commands Return Values
Cypress does not run synchronously, meaning that the return value of any command cannot be assigned to a variable.
- Anti-Pattern: You cannot assign the return value of a command to a variable declared with const, let, or var.
- Best Practice: Closures allow you to store what commands yield.
Do not assign the return values of any Cypress command. Enqueueing commands make them asynchronous, so there is no guarantee that the behavior of the tests will be the same if they depend on the return values.
If you've worked with JavaScript enough, then you're probably familiar with JavaScript promises and how to work with them. You can access the value yielded by Cypress commands using the .then() command.
4. Having Tests Independent of Each Other
- Anti-Pattern: Making tests dependent on each other or coupling multiple tests.
- Best Practice: Tests should always be able to run independently from one another and still pass. Cypress enables developers to run their tests in parallel, which can save time.
The approach to testing your code depends on the previous state of the application. For example, the step of .should("contain," "Hello World") depends on the previous step of clicking the button, and this also depends on the previous state of typing in the input. These steps obviously depend on each other and fail completely in isolation.
5. Avoiding Small Tests With Single Assertion
Cypress is different from running unit tests, which only run a single event at a time, resetting the state between each one.
- Anti-Pattern: A single assertion for an element can be used to create many tests.
- Best Practice: Adding multiple assertions in the same test.
Adding multiple assertions to a single test is much faster than creating multiple tests; therefore, you should not be afraid to add multiple assertions to a single test.
6. Using After or AfterEach Hooks
- Anti-Pattern: To clean up the state by using after or afterEach hooks.
- Best Practice: Clean up state before running the tests.
It is a good idea to wait until after your test ends to write your state clean-up code. This will help you avoid introducing unnecessary failing tests and will speed up your testing performance.
Who Uses Cypress Testing Framework?
Automated testing is an essential part of modern software delivery practices. The need for stable test automation tools has also increased with the increasing demand for quick time-to-market and stable products. Cypress has successfully established its place among other testing frameworks in web automation and end-to-end UI test automation.
Cypress addresses the pain points faced by developers and QA engineers when testing modern applications, such as synchronization issues and the inconsistency of tests due to elements that are not visible or available. As a result, Cypress, a JavaScript-based end-to-end testing framework, is the go-to choice for many front-end developers and test automation engineers for writing automated web tests.
Being an open-source framework, Cypress serves as a lifeline to many freelancer web developers and web testers.
Published at DZone with permission of Sarah Elson. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments