Best practices for testing with Cypress
The importance of writing tests for your application should not be underestimated. Yes, writing tests can be more demanding than it seems and might seem insignificant sometimes, but they are crucial for maintaining a bug-free application.
Cypress is a Javascript-based front-end testing tool. It is a user-friendly application for developers that runs in the browser and aids QA engineers and developers with test automation.
Best practices are professional procedures that are widely accepted as being correct or most effective. When best practices are appropriately adhered to during application testing, it results in high-performing application software that delights developers and customers by working as intended.
This article will cover some best practices to use when testing applications with Cypress. As much as the practices covered in this article are Cypress oriented, they can still be applied to any testing platform. The following sections will cover some widely accepted procedures that should be followed when using Cypress for software testing.
Selecting elements with data-*
attributes to provide context
Data attributes are single-value descriptors for data points or data objects. When testing applications with Cypress, you will use selectors for elements in every test you write. A good idea to save resources and hassles is to make sure you create selectors that can withstand changes. These changes can come from modifications made to Javascript behavior or CSS styles during development.
The best way to avoid these issues is to use custom data-*
attributes that are resilient to change and clearly describe their purpose. Some examples are shown in the code block below:
// Do this
cy.get('[data-cy="button"]');
cy.get('[data-test-id="image"]');
// Avoid doing this
cy.get('image'); // This is too generic
cy.get('#button'); // This can be modified by JS or CSS
As you can see from the above example, you should avoid using ids, tags, class names, or other generic identifiers when writing tests for your applications.
Avoid testing 3rd party servers that you don’t control and use cy.request
when you want to do so
There are lots of reasons why you might want to visit or involve 3rd party servers when writing tests for your application. Some of the reasons might include the following:
- Testing OAuth login when your app uses a different supplier.
- Examining your email to check whether a “forgotten password” email was issued by your server.
It is, however, not recommended that you use your UI to visit a 3rd party site when running tests and some reasons for that include the following:
-
It takes a long time and makes your tests take longer.
-
The content of the third-party website may have been updated or changed.
-
There can be problems with the 3rd party servers beyond your control.
Now, there might be occasions when your application might need to interact with 3rd party servers. On those occasions, it is recommended that you use the cy.request
command to programmatically interact with those servers.
Session Replay for Developers
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.
Setting a Base URL
Globally setting a base URL in your Cypress configuration file is another best practice when testing your applications with Cypress. Not only does it help your tests run more efficiently, but it also makes it simpler to swap the test suite between various contexts, such as a development site and a live website. An example of this is shown below:
// cypress.config.js
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3000'
}
})
By setting the base URL in your config file, you can shorten the URLs in your tests from
cy.visit('http://localhost:3000/index.html')
to
cy.visit('index.html')
When you are ready to switch to the production site, changing the base URL from one location is easier. An added benefit is that adding a base URL saves some time during Cypress test startup.
Avoid using cy.wait
with a number
Using the cy.wait
command with a fixed number is a typical Cypress error. You often want to wait for an element to appear or a network request to complete before moving on, so you do this. Use cy.wait
with a number to make sure that commands have completed running to stop unpredictable failures.
This has the drawback of making you wait longer than is required. If you set cy.wait
to wait for a network request for 5000 milliseconds, but the request only takes 500 milliseconds, you have unnecessarily extended the execution speed of your tests by 4500 milliseconds.
Using cy.wait
is also unnecessary because, on many occasions, you will be making that request with the cy.request
command, and the cy.request
command will not resolve until it receives a response. Instead of using cy.wait
with a number, use it with an alias to guarantee that the condition you are waiting on is satisfied. This example is shown in the code block below:
cy.request('GET', '/users', [{ name: 'Maggy' }, { name: 'Joan' }]).as(
'getUsers'
)
cy.wait('@getUsers') // <--- wait explicitly for the request to finish
In the above example, we made a GET
request, and instead of using cy.wait
with a number, we explicitly waited for the request to pass using an alias.
Conclusion
This article has looked at some best practices to follow when using Cypress for running tests to avoid having brittle tests in your application. You can find more best practices by visiting Cypress Best Practices Guide here.
A TIP FROM THE EDITOR: For more on testing, do not miss our Front-end testing: principles, levels, libraries, and automation and Testing Tools: Launchers And Structure Providers articles.