17 tips and best practices for Cypress

Frederik Vantroys
3 min readAug 18, 2023

--

Cypress is a JavaScript-based end-to-end testing framework designed to help developers write and run tests for their web applications. Unlike many other testing solutions, Cypress runs directly in the browser, ensuring more consistent and reliable testing.

Below are 17 tips and best practices:

1: The Cypress team maintains the Real World App (RWA) , a full-stack sample application that demonstrates best practices and scalable strategies with Cypress in practical and realistic scenarios. The RWA achieves full code coverage with end-to-end testing for multiple browsers and device sizes, but also includes visual regression testing, API testing, unit testing and runs them all in an efficient CI pipeline. The app is bundled with everything you need, you just need to clone the repository and start testing.

2: Avoid using fixed timeouts: instead of relying on cy.wait(1000), try Cypress’s built-in ability to re-execute commands until they succeed. For example, use cy.get(‘selector’).should(‘be.visible’) to make an element visible.

3: Use custom commands sparingly: While it’s tempting to abstract complex flows into custom commands, overusing them can make your tests harder to read. Only abstract recurring and complex actions.

4: Group related tests: Use describe and context to group related tests together. This improves readability and organizes your test suite.

5: Use beforeEach and afterEach wisely: set up and break down operations can be placed in beforeEach and afterEach hooks. This ensures that each test case is independent and can be run in any order.

6: Keep tests atomic and independent: Each test should be able to run independently without depending on other tests. This makes it easier to identify problems when they arise.

7 : Use data attributes for selectors: Instead of relying on CSS classes or other attributes that may change due to visual updates, use data* attributes to select elements. For example, data-cy=”submit-button” .

8 : Handling Single Page Application (SPA) Transitions: When navigating within SPAs, use cy.url() or cy.hash() to ensure that the application is done navigating.

9: Avoid conditional tests: Your tests must be deterministic. Avoid writing tests such as “if this element is present, do this…”. If you find yourself doing this, consider if there’s a way to make the environment or setup more predictable.

10 : Clean State: Clean up any state that might be changed during your tests. These can be users, settings or database entries. You can do this using the beforeEach and afterEach hooks .

11: Network Processing: Use cy.server() and cy.route() (or cy.intercept() in newer versions) to stop and spy on network requests. This gives you more control over the behavior and timing of network interactions.

12: Using Aliases: Use .as() to create aliases for elements, routes, or fixtures. This improves readability and enables reusability.

13: Individual Configuration: Use cypress.json for global configurations and environment variables for sensitive or dynamic data.

14: Limit the use of global variables: While it may be tempting to use global variables in your tests, it can lead to unpredictable testing behavior. Instead, use context (this) or Cypress’s built-in .as() command to share state between hooks and tests.

15: Parallel Execution: As your test suite grows, consider using Cypress’s ability to run tests in parallel to speed up execution time. This can be especially beneficial when integrating with CI/CD pipelines.

16 : Check the imperfection of tests: Even with the best practices, end-to-end tests can sometimes be unstable. Monitor test deviations and if a test fails intermittently for no apparent reason, consider reviewing its logic or possibly marking it for manual testing.

17: Stay tuned for updates: Cypress is an actively maintained and evolving tool. Regularly check their documentation and updates to take advantage of new features or improvements.

--

--

Frederik Vantroys

I am a functional analyst with a heart for the Agile methodology. My technical background helps me to analyze, but does not prevent me from dreaming.