Cypress best practices
Edit on GitHubFollow these best practices to write robust, maintainable, and efficient Cypress tests. For more information, see official Cypress best practices guide.
General recommendations
- Avoid chaining multiple commands in a single statement, because it makes debugging difficult.
- Use Cypress commands, such as
cy.get()andcy.contains(), effectively—they provide built-in retries. - Use custom scenarios for repeated user flows, such as registration or checkout.
- Use custom commands for repeated sequences and abstract actions, such as
closeAllFlashMessagesorrunConsoleCommand. - Store test data in \cypress/fixtures
and load it by using Cypress fixtures. - Avoid assigning Cypress commands to
const,let, orvar. Use aliases or closures instead, because Cypress commands are asynchronous. - Test only the functionality you control. Do not test third-party services.
- Use environment-specific configuration files to manage different environments.
Organizing tests
- Structure tests by feature or user story.
- Create reusable utility functions for setup, teardown, and common actions.
- Use the
before,beforeEach,afterEach, andafterhooks wisely for state management.
Avoiding anti-patterns
- Avoid testing implementation details—focus on application behavior.
- Avoid using
cy.pause()outside of debugging sessions. - Avoid
cy.wait()with arbitrary time periods. Usecy.intercept()orcy.get()with assertions instead.
Visiting external sites
Avoid visiting external sites directly. Mock network requests instead, to remove external dependencies and speed up your tests.
Using the after and afterEach hooks
Use the after and afterEach hooks sparingly. These hooks run even if tests fail, which can mask issues.
Setting a global baseUrl
Set baseUrl in the Cypress configuration to simplify your test code:
// cypress.config.ts
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:8484',
},
})
Specs best practices
- Independence: each spec is independent of the others.
- Autonomy: each spec runs independently.
- Order: each spec runs in any order.
- Environment: each spec runs in any environment.
- Tests: each spec can contain multiple tests.
- Assertions: each test can have multiple assertions.
Classes best practices
- Single responsibility principle: each class has one responsibility.
- Encapsulation: hide the internal state and require interaction through object methods.
- Reusability: design classes so they work in different contexts.
Why Cypress boilerplate uses TypeScript
TypeScript is a superset of JavaScript that adds static typing, providing the following benefits:
- Static typing: catches type errors at compile time, which reduces runtime errors.
- Enhanced IDE support: improves autocompletion, navigation, and refactoring.
- Improved code quality: enforces type checks and produces more predictable code.
Page object best practices
Page objects encapsulate page structure and UI interactions, to improve reusability and maintainability.
-
Abstract page usage: create an abstract page class for common functionality.
-
Getter functions: use getter functions to locate elements, for example:
const loginForm = 'form[name="loginForm"]' getEmailField = (): Cypress.Chainable => { return cy.get(loginForm).find('#loginForm_email') } -
Action functions: create atomic functions for actions, for example:
selectFirstBusinessAddressAvailableForShipping = (): void => { this.getShippingAddressDropdown().click() cy.get('[id*="company_business_unit_address"]').first().click() }
Follow these principles for page objects:
- Atomic functions: give each function a single purpose.
- Reuse functions: reuse common functions across page objects.
- Encapsulation: keep page structure details hidden from test scripts.
Reusing the API for setup
Minimize testing steps and speed up your tests by reusing the API for setup. For example, create orders through the API to save time, and test order placement through the UI only once. This approach provides the following benefits:
- Speeds up tests by avoiding redundant UI operations.
- Ensures state consistency through the API before running UI tests.
Thank you!
For submitting the form