Back

Best practices for testing with Cypress

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 suite for developers. It can be self-hosted in minutes, giving you complete control over your customer data

OpenReplay Happy debugging! Try using OpenReplay today.

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.

newsletter