DEV Community

Cover image for Cypress assertions. What to use: cy.should() or expect()?
Daniil
Daniil

Posted on • Edited on

Cypress assertions. What to use: cy.should() or expect()?

Intro

Before we talked about aliases and storing values in hybrid web automation frameworks. Now, let's touch another topic and understand in what cases we should use Chai assertions should() and expect().

In Cypress, you have two main ways to perform assertions:

  • Cypress built-in assertions
cy.wrap($element).should('be.visible')
Enter fullscreen mode Exit fullscreen mode
  • Chai assertions
expect($element).to.be.visible
Enter fullscreen mode Exit fullscreen mode

Each method has its own advantages and drawbacks. Let’s break them down.

Cypress assertions

cy.wrap($element).should('be.visible')

Enter fullscreen mode Exit fullscreen mode

Pros:

  • Automatic retries: Cypress will keep retrying the assertion until the element meets the expected condition or the test times out.
  • Better handling of asynchronous behavior: Since Cypress is designed to work with asynchronous operations, should() ensures the assertion runs only when the element is available.
  • Chainable: You can chain Cypress commands with .should() directly, making your code more readable.
  • Works well with Cypress commands: Since Cypress commands are asynchronous, using .should() ensures that Cypress waits for the command to complete before making assertions.

Cons:

  • More verbose: Requires wrapping elements with cy.wrap(), which can make the code slightly longer.
  • Slightly different debugging: Since Cypress retries automatically, it might not immediately fail, making debugging take a bit longer.

Example Usage:

cy.get('.button').should('be.visible');
cy.wrap($element).should('be.visible');
Enter fullscreen mode Exit fullscreen mode

Chai assertions

expect($element).to.be.visible
Enter fullscreen mode Exit fullscreen mode

Pros:

  • Simple and direct: Less code needed, making it more concise.
  • Works well with synchronous operations: If you already have a reference to an element and don’t need Cypress’s automatic retries, expect() works well.

Cons:

  • No automatic retry: If the element isn’t immediately visible, the assertion fails instantly instead of waiting for it to appear.
  • Doesn’t work well with Cypress commands: Since Cypress commands are asynchronous, trying to use expect() directly on a Cypress command might lead to timing issues.
  • Less reliable in UI tests: Since UI elements might take time to appear due to animations, rendering delays, or network requests, lack of retries can lead to flaky tests.

Example Usage:

cy.get('.button').then(($btn) => {
  expect($btn).to.be.visible; // Fails instantly if not visible
});
Enter fullscreen mode Exit fullscreen mode

Which one is better?

Use cy.should() as the default assertion method in Cypress tests because:

  • Cypress automatically retries the assertion.
  • It works seamlessly with Cypress’s asynchronous nature.
  • It reduces flaky tests by waiting for the condition to be met.

When to use expect():

  • If you’re asserting a pure JavaScript object instead of a Cypress-wrapped element.
  • When checking values inside a .then() block (e.g., API responses, calculations, etc.).

Example of correct expect() usage:

cy.request('/api/users/1').then((response) => {
  expect(response.status).to.eq(200);
});
Enter fullscreen mode Exit fullscreen mode

Best practice: Stick to one for consistency

For better code consistency, maintainability, and readability, use Cypress assertions .should() in most cases.
However, allow expect() only when dealing with non-Cypress elements (e.g., API responses, custom JavaScript objects).

Final Recommendation

  1. Use cy.should() for UI-related assertions.
  2. Use expect() only for non-Cypress elements (API responses, variables).
  3. Don’t mix both styles for the same purpose to keep the framework clean and maintainable.

P.S.

I have used the same approach in my working web automation hybrid framework and it works so well and performance increased.🚀

Top comments (0)