Cypress test data
Drop a generated JSON file into cypress/fixtures and every spec gets realistic, identical data โ locally, in CI and on the machine of whoever reviews the failure.
The fixtures folder
Export JSON with a seed, save it as cypress/fixtures/users.json, and it is available by name:
describe('user list', () => {
beforeEach(() => {
cy.fixture('users').as('users');
});
it('renders every user', function () {
cy.visit('/users');
cy.getByTestId('user-row').should('have.length', this.users.length);
cy.contains(this.users[0].full_name).should('be.visible');
});
});
Because the file was generated with a seed, users[0].full_name is a fixed value. That is the difference between an assertion you can read and a snapshot you have to trust.
Stubbing the network
The fixture pairs directly with cy.intercept, which is where generated data earns its keep โ arbitrary response states become one line each:
cy.intercept('GET', '/api/users*', { fixture: 'users.json' }).as('list');
cy.intercept('GET', '/api/users*', { statusCode: 500 });
cy.intercept('GET', '/api/users*', { body: [] }); // empty state
cy.intercept('GET', '/api/users*', { forceNetworkError: true });
cy.intercept('GET', '/api/users*', (req) => {
req.reply({ delay: 3000, fixture: 'users.json' }); // slow response
});
Generate a large fixture for the pagination and virtual-scroll tests, a three-row one for layout, and an empty array for the empty state. All three come from the same schema with a different row count, which keeps them consistent with each other.
Data-driven specs
import cases from '../fixtures/signup-cases.json';
cases.forEach((c) => {
it(`rejects ${c.label}`, () => {
cy.visit('/signup');
cy.getByTestId('email').type(c.email);
cy.getByTestId('submit').click();
cy.getByTestId('form-error').should('have.text', c.expected);
});
});
Note the import rather than cy.fixture: the loop has to run while the spec file is being evaluated, before any Cypress command has executed, so the file needs to be available synchronously. Using cy.fixture here silently produces zero tests, which is a confusing hour if you have not hit it before.
Seeding a real database
For tests that go all the way through, export SQL and run it from a task, since specs cannot touch the filesystem or a database directly:
// cypress.config.js
setupNodeEvents(on) {
on('task', {
seedDb() {
require('node:child_process').execSync('psql $TEST_DB -f cypress/fixtures/seed.sql');
return null;
}
});
}
// spec
beforeEach(() => { cy.task('seedDb'); });
Reseed rather than append. A suite that passes only on a database with three previous runs' worth of rows in it is not testing what you think.
Fixtures and encoding
Generated data contains non-ASCII names by design, and cy.fixture reads JSON as UTF-8, so those arrive intact. This is worth keeping rather than filtering out โ a fixture of ASCII-only names will never tell you that your application mangles Yฤฑlmaz somewhere between the API and the DOM. If you also want to check binary handling, that is what the encoding argument on cy.fixture is for.
A practice target that does not change
If you are learning Cypress or building a training exercise, this site is designed for it: every control carries a stable data-testid that survives deploys. The schema builder covers text inputs, selects, checkboxes, dialogs, drag-and-drop reordering, dynamically added rows, file downloads and a preview table that updates as you type โ a fuller surface than most practice applications, and it needs no environment of your own.
Common questions
Where do generated fixtures go in a Cypress project?
Save the JSON export as cypress/fixtures/name.json and load it with cy.fixture('name'), or import it directly when you need the data synchronously.
Why does my forEach over cy.fixture produce no tests?
cy.fixture is a command that runs after the spec file has been evaluated, so the loop body never registers any tests. Import the JSON file directly at the top of the spec instead.
How do I test error and empty states?
Pair the fixture with cy.intercept โ statusCode: 500 for errors, body: [] for empty, forceNetworkError for connection failures, and req.reply with a delay for slow responses.
How do I seed a real database from Cypress?
Specs cannot reach the filesystem, so register a task in setupNodeEvents that runs the generated SQL, then call cy.task from beforeEach. Reseed each run rather than appending.
Can I practise Cypress against this site?
Yes. Every interactive control has a stable data-testid, covering forms, dialogs, drag-and-drop, downloads and dynamically rendered rows.
Related
- Playwright test data โ the same patterns with page.route.
- QA test data guide โ data classes worth covering.
- Sample JSON data โ typed fixture output.
- Mock API data โ response states and envelopes.