0
0
Cypresstesting~15 mins

Preserving state between tests in Cypress - Deep Dive

Choose your learning style9 modes available
Overview - Preserving state between tests
What is it?
Preserving state between tests means keeping certain data or conditions unchanged as you run multiple tests in a row. In Cypress, this often involves saving things like cookies, local storage, or session information so tests can continue smoothly without starting fresh each time. This helps tests run faster and behave more like a real user session. Without preserving state, each test would start from scratch, making tests slower and less realistic.
Why it matters
Without preserving state, tests would have to log in or set up the same data repeatedly, wasting time and making tests fragile. This slows down development and can cause false failures if setup steps fail. Preserving state makes tests more efficient and reliable, reflecting how users actually interact with the app over time. It also helps catch bugs that happen only when state carries over, improving software quality.
Where it fits
Before learning this, you should understand basic Cypress test writing and how tests run independently. After this, you can learn about advanced test organization, custom commands, and continuous integration setups that rely on stable test states.
Mental Model
Core Idea
Preserving state between tests means saving and restoring key data so tests can share context and run faster without repeating setup.
Think of it like...
It's like keeping your place in a book when you take breaks; you don't start reading from the first page every time, but pick up where you left off.
┌───────────────┐     ┌───────────────┐     ┌───────────────┐
│   Test 1      │ --> │ Save State    │ --> │   Test 2      │
│ (login, setup)│     │ (cookies, LS) │     │ (uses saved)  │
└───────────────┘     └───────────────┘     └───────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding test isolation basics
🤔
Concept: Tests run independently by default, starting fresh each time.
In Cypress, each test starts with a clean browser state. This means cookies, local storage, and session data are cleared before every test. This isolation ensures tests don't affect each other but can cause repeated setup steps like logging in.
Result
Tests run independently but may repeat the same setup actions, making tests slower.
Understanding test isolation helps you see why preserving state is needed to avoid redundant work.
2
FoundationCommon types of state to preserve
🤔
Concept: State includes cookies, local storage, session storage, and sometimes server data.
Cookies store login sessions, local storage holds user preferences, and session storage keeps temporary data. Preserving these between tests means saving them after one test and restoring before the next.
Result
Knowing what state to preserve guides how to keep tests connected.
Recognizing different state types helps target what to save for smooth test flows.
3
IntermediateUsing Cypress commands to save cookies
🤔Before reading on: do you think Cypress automatically keeps cookies between tests? Commit to yes or no.
Concept: Cypress clears cookies by default, so you must explicitly save and restore them.
You can use Cypress commands like cy.getCookies() to read cookies and cy.setCookie() to restore them. Typically, you save cookies after login and restore them before tests that need the user logged in.
Result
Tests can share login state without repeating login steps.
Knowing how to manually save and restore cookies prevents unnecessary logins and speeds up tests.
4
IntermediatePreserving local storage between tests
🤔Before reading on: do you think local storage persists automatically across Cypress tests? Commit to yes or no.
Concept: Local storage is cleared between tests unless you save and restore it manually.
You can save local storage data to a variable or file after a test and restore it before the next test using cy.window().then(win => win.localStorage). This keeps user preferences or tokens available.
Result
Tests can continue with the same local storage data, avoiding repeated setup.
Understanding local storage preservation helps maintain app state that cookies alone can't cover.
5
IntermediateUsing Cypress built-in preserve options
🤔Before reading on: do you think Cypress has built-in ways to preserve cookies automatically? Commit to yes or no.
Concept: Cypress offers configuration options to preserve cookies automatically between tests.
In Cypress configuration or support files, you can use Cypress.Cookies.preserveOnce() or Cypress.Cookies.defaults() to keep specific cookies across tests. This reduces manual save/restore code.
Result
Tests run faster and cleaner with less code to manage state.
Leveraging built-in preservation simplifies test code and reduces errors.
6
AdvancedCustom commands for state preservation
🤔Before reading on: do you think creating custom Cypress commands can help manage state preservation? Commit to yes or no.
Concept: Custom commands encapsulate state saving and restoring logic for reuse.
You can write Cypress.Commands.add() to create commands like saveSession() and restoreSession() that handle cookies and local storage together. This makes tests cleaner and easier to maintain.
Result
Tests become more readable and consistent in preserving state.
Using custom commands abstracts complexity and promotes reuse across many tests.
7
ExpertPitfalls and surprises in state preservation
🤔Before reading on: do you think preserving state can cause flaky tests? Commit to yes or no.
Concept: Preserving state can introduce hidden dependencies and flaky tests if not managed carefully.
If tests rely too much on preserved state, failures in one test can cascade to others. Also, some state like session tokens may expire, causing unexpected failures. Proper cleanup and selective preservation are key.
Result
Tests may fail unpredictably if state preservation is misused.
Knowing the risks helps design tests that balance speed with reliability.
Under the Hood
Cypress runs each test in a fresh browser context by default, clearing cookies, local storage, and session storage. To preserve state, Cypress allows intercepting these clear actions by saving data after a test and restoring it before the next. Internally, Cypress commands interact with the browser's storage APIs to read and write this data. The preservation can be automatic for cookies via configuration or manual for other storage types.
Why designed this way?
Test isolation prevents tests from affecting each other, ensuring reliability and easier debugging. However, this strict isolation can slow tests and cause redundant setup. Cypress balances this by allowing explicit state preservation, giving developers control to optimize speed without losing test independence. Alternatives like always sharing state risk hidden dependencies and flaky tests.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Test Runner   │       │ Browser       │       │ Storage APIs  │
│ (Cypress)     │       │ Context       │       │ (Cookies, LS) │
└──────┬────────┘       └──────┬────────┘       └──────┬────────┘
       │                       │                       │
       │ run test              │                       │
       │---------------------> │                       │
       │                       │ clear storage         │
       │                       │---------------------> │
       │                       │                       │
       │ save state             │                       │
       │ <---------------------│                       │
       │                       │                       │
       │ restore state          │                       │
       │---------------------> │                       │
       │                       │ set storage           │
       │                       │---------------------> │
Myth Busters - 4 Common Misconceptions
Quick: Does Cypress keep cookies automatically between tests? Commit to yes or no.
Common Belief:Cypress automatically keeps cookies and local storage between tests.
Tap to reveal reality
Reality:Cypress clears cookies and local storage between tests by default to ensure isolation.
Why it matters:Assuming automatic preservation leads to tests failing unexpectedly because the session or data is lost.
Quick: Can preserving all state between tests make tests more reliable? Commit to yes or no.
Common Belief:Preserving all state between tests always makes tests more reliable and faster.
Tap to reveal reality
Reality:Preserving too much state can cause tests to depend on each other, making failures cascade and tests flaky.
Why it matters:Over-preserving state hides bugs and makes debugging harder, reducing test trustworthiness.
Quick: Is local storage the same as cookies in how Cypress handles them? Commit to yes or no.
Common Belief:Local storage and cookies behave the same and are preserved the same way in Cypress.
Tap to reveal reality
Reality:Cookies can be preserved automatically with Cypress commands, but local storage must be saved and restored manually.
Why it matters:Confusing these leads to incomplete state preservation and test failures.
Quick: Does preserving state mean tests can never fail independently? Commit to yes or no.
Common Belief:If you preserve state, tests lose independence and always fail together.
Tap to reveal reality
Reality:Properly managed state preservation keeps tests independent by resetting state when needed and isolating failures.
Why it matters:Misunderstanding this can cause developers to avoid preservation and write slower, repetitive tests.
Expert Zone
1
Preserving only essential cookies and storage keys reduces risk of hidden dependencies and flaky tests.
2
Session expiration or token invalidation can silently break tests relying on preserved state, requiring periodic full resets.
3
Custom commands for state preservation should include error handling to recover gracefully from corrupted or missing state.
When NOT to use
Avoid preserving state when tests must verify fresh user flows or when testing logout and session expiration behaviors. Instead, write fully independent tests with fresh setups or use API calls to set state quickly.
Production Patterns
In real projects, teams use before() hooks to log in once and preserve session cookies for all tests in a suite. They combine this with custom commands to save and restore local storage. CI pipelines often clear state periodically to avoid flaky tests caused by stale data.
Connections
Test Isolation
Preserving state balances with test isolation by selectively sharing context.
Understanding how preservation interacts with isolation helps design tests that are both fast and reliable.
Session Management in Web Apps
Preserving state in tests mimics how web apps manage user sessions across pages.
Knowing session management concepts clarifies why cookies and storage must be preserved to simulate real user behavior.
Memory Persistence in Operating Systems
Preserving state between tests is like how OS manages memory persistence across processes.
Seeing state preservation as memory management helps appreciate the tradeoffs between isolation and sharing.
Common Pitfalls
#1Not preserving cookies causes repeated logins in every test.
Wrong approach:describe('Tests', () => { it('logs in', () => { cy.visit('/login') cy.get('#user').type('user') cy.get('#pass').type('pass') cy.get('button').click() }) it('does something', () => { cy.visit('/dashboard') // expects logged in but session lost }) })
Correct approach:describe('Tests', () => { before(() => { cy.login() // custom command to log in once }) beforeEach(() => { Cypress.Cookies.preserveOnce('session_id') }) it('does something', () => { cy.visit('/dashboard') // session preserved }) })
Root cause:Assuming Cypress keeps cookies automatically without explicit preservation.
#2Trying to preserve local storage without saving and restoring it manually.
Wrong approach:beforeEach(() => { // no code to save or restore local storage })
Correct approach:let localStorageData = {} before(() => { cy.window().then(win => { localStorageData = {...win.localStorage} }) }) beforeEach(() => { cy.window().then(win => { Object.entries(localStorageData).forEach(([key, value]) => { win.localStorage.setItem(key, value) }) }) })
Root cause:Believing local storage is preserved automatically like cookies.
#3Preserving all cookies and storage without filtering causes flaky tests.
Wrong approach:Cypress.Cookies.defaults({ preserve: true })
Correct approach:Cypress.Cookies.defaults({ preserve: ['session_id', 'auth_token'] })
Root cause:Not understanding that preserving unnecessary data can cause hidden test dependencies.
Key Takeaways
Tests in Cypress run isolated by default, clearing cookies and storage between each test.
Preserving state means saving and restoring cookies or storage to share context and speed up tests.
Cypress provides built-in commands to preserve cookies and requires manual handling for local storage.
Over-preserving state can cause flaky tests, so preserve only what is necessary and manage expirations.
Custom commands and configuration help maintain clean, reusable, and reliable state preservation in real projects.