Best practices for testing with Cypress
Tags: testing, cypress, webdev
Published: 2022-12-15 02:04:03

by [Isaac Okoro](https://blog.openreplay.com/authors/isaac-okoro)

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:

```javascript
// 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.



<h2>Open Source Session Replay</h2> 

_<a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a> is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data._

![OpenReplay](https://blog.openreplay.com/banner-blog_1oYPGT.png)

_Start enjoying your debugging experience - <a href="https://github.com/openreplay/openreplay" >start using OpenReplay for free</a>._





## 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:

```javascript
    // 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

```javascript
    cy.visit('http://localhost:3000/index.html')
```

to

```javascript
    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:

```javascript
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](https://docs.cypress.io/guides/references/best-practices#Unnecessary-Waiting).

> A TIP FROM THE EDITOR: For more on testing, do not miss our [Front-end testing: principles, levels, libraries, and automation](https://blog.openreplay.com/front-end-testing-principles-levels-libraries-and-automation) and [Testing Tools: Launchers And Structure Providers](https://blog.openreplay.com/testing-tools-launchers-and-structure-providers/) articles.



[![newsletter](https://blog.openreplay.com/newsletter_Z1P0UIP.png)](https://newsletter.openreplay.com/)