Cypress Fixtures
cy.fixture() โ Loading Test Data
// cypress/fixtures/user.json
{
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"role": "admin"
}
// Loading a fixture
cy.fixture('user').then(user => {
cy.log(user.name); // Alice
cy.get('#name').should('have.text', user.name);
});
// Alias for reuse
cy.fixture('user').as('userData');
cy.get('@userData').then(user => {
cy.get('form').fill(user);
});
// Load in beforeEach
beforeEach(function () {
cy.fixture('user').as('user');
cy.fixture('products').as('products');
});
it('shows user name', function () {
// Use this.user from fixture alias
expect(this.user.name).to.equal('Alice');
cy.visit('/profile');
cy.get('h1').should('have.text', this.user.name);
});
Fixture File Types
// JSON โ auto-parsed
cy.fixture('data.json'); // Object/Array
// Plain text
cy.fixture('message.txt'); // String
// Image (base64)
cy.fixture('logo.png'); // base64 string
// Encoding option
cy.fixture('logo.png', 'binary'); // Binary
cy.fixture('data.json', 'utf-8'); // Force encoding
// Subdirectories
cy.fixture('users/admin.json');
cy.fixture('api/responses/success.json');
// Fixture directory: cypress/fixtures/ (configurable)
// cypress.config.ts:
// fixturesFolder: 'cypress/fixtures'
intercept with Fixtures
// Use fixture file directly
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
cy.intercept('GET', '/api/products', { fixture: 'products/list.json' });
// Fixture with modified status
cy.intercept('GET', '/api/users', {
statusCode: 200,
fixture: 'users.json',
headers: { 'x-total-count': '42' },
});
// Error response
cy.intercept('GET', '/api/users', {
statusCode: 500,
body: { error: 'Internal Server Error' },
}).as('getServerError');
// Dynamic fixture based on request
cy.intercept('GET', '/api/users/*', (req) => {
const userId = req.url.split('/').pop();
req.reply({ fixture: `users/${userId}.json` });
});
// Wait and assert
cy.visit('/');
cy.wait('@getUsers').then(({ response }) => {
expect(response.statusCode).to.equal(200);
expect(response.body).to.have.length.above(0);
});
Dynamic Fixture Data
// Modify fixture data before using
cy.fixture('user').then(user => {
const adminUser = { ...user, role: 'superadmin', active: true };
cy.intercept('GET', '/api/me', adminUser);
cy.visit('/dashboard');
cy.get('[data-cy="role"]').should('have.text', 'superadmin');
});
// Generate dynamic fixtures with faker
cy.fixture('user').then(template => {
const users = Array.from({ length: 5 }, (_, i) => ({
...template,
id: i + 1,
name: `User ${i + 1}`,
}));
cy.intercept('GET', '/api/users', users);
});
// Parameterize fixture loading
const testCases = ['valid', 'invalid', 'partial'];
testCases.forEach(scenario => {
it(`handles ${scenario} data`, () => {
cy.fixture(`scenarios/${scenario}`).then(data => {
cy.intercept('GET', '/api/form-data', data);
cy.visit('/form');
// assertions based on scenario
});
});
});
Fixture Merging & Factory Pattern
// cypress/support/factories.ts
export function makeUser(overrides = {}) {
return {
id: Math.random(),
name: 'Test User',
email: 'test@example.com',
role: 'viewer',
active: true,
...overrides,
};
}
export function makeOrder(overrides = {}) {
return {
id: 1,
total: 99.99,
status: 'pending',
items: [],
...overrides,
};
}
// In tests
import { makeUser, makeOrder } from '../support/factories';
it('admin can approve orders', () => {
const admin = makeUser({ role: 'admin' });
const order = makeOrder({ status: 'pending', total: 250 });
cy.intercept('GET', '/api/me', admin);
cy.intercept('GET', '/api/orders/1', order);
cy.visit('/orders/1');
cy.get('[data-cy="approve-btn"]').should('be.visible');
});
Fixtures Best Practices
| Practice | Reason |
|---|---|
Use data-cy attributes | Decouple tests from CSS/structure changes |
| Keep fixtures minimal | Only include fields your test uses |
| Use factories for variations | Avoid duplicating fixture files |
| Version fixture data | Keep in sync with API schema changes |
| Name fixtures descriptively | user-admin.json vs data1.json |
| Alias fixtures in beforeEach | Makes this.fixtureName available |