DEV Community

Jordan Powell for Cypress

Posted on

Cypress Best Practices

Organizing Tests, Logging In, Controlling State

  • Anti-Pattern: Sharing page objects, using your UI to log in, and not taking shortcuts.
  • Best Practice: Test specs in isolation, programmatically log into your application, and take control of your application's state.

Selecting Elements

  • Anti-Pattern: Using highly brittle selectors that are subject to change.
  • Best Practice: Use data-* attributes to provide context to your selectors and isolate them from CSS or JS changes
Selector Recommended Notes
cy.get('button').click() Never Worst - too generic, no context
cy.get('.btn.btn-large').click() Never Bad. Coupled to styling. Highly subject to change
cy.get('#main').click() Sparingly Better. But still coupled to styling or JS event listeners.
cy.get('[name=submission]').click() Sparingly Coupled to the name attribute which has HTML semantics.
cy.contains('Submit').click() Depends Much better. But still coupled to text content that may change.
cy.get('[data-cy=submit]').click() Always Best. Isolated from all changes.

Assigning Return Values

Visiting External Sites

  • Anti-Pattern: trying to visit or interact with sites or servers you do not control
  • Best Practice: Only test what you control. Try to avoid requiring a 3rd party server. When necessary, always use cy.request() to talk to 3rd party servers via their APIs.

Having tests rely on the state of previous tests

  • Anti-Pattern: Coupling multiple tests together
  • Best Practice: Tests should always be able to be run independently from one another and still pass.

Creating "tiny" tests with a single assertion

  • Anti-Pattern: Acting like you're writing unit tests.
  • Best Practice: Add multiple assertions and don't worry about it

Using after or afterEach hooks

  • Anti-Pattern: Using after or afterEach hooks to clean up state.
  • Best Practice: Clean up state before tests run.

Unnecessary Waiting

  • Anti-Pattern: Waiting for arbitrary time periods using cy.wait(Number)
  • Best Practice: Use route aliases or assertions to guard Cypress from proceeding until an explicit condition is met

Web Servers

  • Anti-Pattern: Trying to start a web server from within Cypress scripts with cy.exec() or cy.task().
  • Best Practice: Start a web server prior to running Cypress

Setting a global baseUrl

You can read our entire Best Practices Guide at https://docs.cypress.io/guides/references/best-practices

Discussion (0)