Skip to content

Cypress Test Architecture

As a suite grows past a handful of files, deliberate architecture decisions determine whether it stays maintainable or becomes a tangled liability. This lesson covers organizational patterns for a large, healthy Cypress suite.

Layering Your Test Suite

A well-architected suite mirrors the testing pyramid: many fast, focused component/unit-level tests, a moderate number of API-level tests validating backend contracts, and a smaller number of true, full end-to-end tests covering critical user journeys.

// Rough proportion in a healthy suite
// Many:   component tests (fast, isolated)
// Some:   API tests via cy.request() (fast, backend-focused)
// Few:    full E2E user-journey tests (slower, highest confidence)

This layering keeps the suite fast overall while still preserving genuine, full-stack confidence where it matters most.

A Scalable Folder Structure

cypress/
  e2e/
    auth/
    checkout/
    admin/
  component/
    Button.cy.jsx
    Form.cy.jsx
  support/
    commands/
      auth.js
      forms.js
    e2e.js
  fixtures/
  • Organize E2E specs by feature/domain area, not by page component.
  • Keep component tests colocated with their components, or in a mirrored component/ structure.
  • Split a growing commands.js into feature-specific files under a commands/ folder.
  • Group fixtures logically as the number of test data files grows.

Test Architecture Patterns Cheat Sheet

Common organizational patterns and when each one fits.

Pattern Best For
Feature-based spec folders Any suite beyond a handful of spec files
Custom commands (cy.login()) Cypress-idiomatic reuse; the recommended default
Page Object classes Teams migrating from Selenium, familiar with the pattern
Shared mountWithProviders helpers Component testing with common context needs
Layered test pyramid Balancing speed and confidence across a large suite

Page Objects vs. Custom Commands in Cypress

The Page Object pattern, common in Selenium-based suites, wraps a page's selectors and actions in a class. Cypress's own team generally recommends custom commands and simple utility functions instead, since Cypress's chaining model doesn't need the same encapsulation Page Objects were originally designed to provide.

// Page Object style (works, but less idiomatic in Cypress)
class LoginPage {
  visit() { cy.visit('/login'); }
  fillEmail(email) { cy.get('[data-cy="email"]').type(email); }
}

// More idiomatic Cypress: a custom command
Cypress.Commands.add('fillLoginForm', (email, password) => {
  cy.get('[data-cy="email"]').type(email);
  cy.get('[data-cy="password"]').type(password);
});

Both can work; most Cypress-native codebases favor custom commands and small utility functions over full Page Object classes.

A Consistent Shared Setup Strategy

Deciding, project-wide, how authentication, test data, and common assertions are set up (rather than letting each spec file reinvent its own approach) is one of the highest-leverage architectural decisions for keeping a growing suite consistent and maintainable.

  • Standardize on one authentication helper (cy.session() + a login command) used everywhere.
  • Standardize on one test data strategy (fixtures, factories, or API seeding) per data category.
  • Document these conventions so new contributors don't invent inconsistent alternatives.

Common Mistakes

  • Porting the full Page Object pattern directly from a Selenium background without adapting it to Cypress's idioms.
  • Letting every spec file invent its own ad hoc setup approach instead of a documented, shared convention.
  • Building an all-E2E suite with no component or API-level tests, resulting in a slow, expensive-to-maintain pyramid.
  • Organizing spec files by page/component instead of by feature, making a growing suite hard to navigate.

Key Takeaways

  • A healthy suite layers component, API, and E2E tests, mirroring the testing pyramid.
  • Cypress generally favors custom commands over full Page Object classes for reuse.
  • Organizing specs by feature/domain scales better than organizing by individual page component.
  • A documented, shared setup convention (auth, test data) keeps a growing suite consistent.

Pro Tip

Write down your project's testing conventions, folder structure, authentication approach, test data strategy, in a short internal document early, even a one-page guide dramatically reduces the inconsistency that naturally creeps into a Cypress suite as more contributors add tests over time.