Cypress - Fixtures
Cypress - Managing Test Data with Fixtures
Section titled “Cypress - Managing Test Data with Fixtures”Cypress fixtures are used to manage static data that your tests might need. They are typically external files (e.g., JSON, CSV, images, HTML) stored in the cypress/fixtures folder. Fixtures help in separating test data from test logic, making tests cleaner and more maintainable, especially for data-driven testing.
By default, Cypress looks for fixture files within the cypress/fixtures directory. You can organize your fixtures in subfolders within this directory.
Using cy.fixture()
Section titled “Using cy.fixture()”The cy.fixture() command is used to load a fixture file. It yields the content of the file, which can then be used in subsequent Cypress commands or assertions.
Syntax
Section titled “Syntax”cy.fixture(filePath)cy.fixture(filePath, encoding)cy.fixture(filePath, options)cy.fixture(filePath, encoding, options)Where:
filePath: Path to the fixture file (relative to thecypress/fixturesfolder). E.g., ‘user.json’, ‘test-data/credentials.json’.encoding(optional): Encoding to be used (e.g., ‘utf8’, ‘ascii’). Defaults to ‘utf8’ for most text-based files. For binary files like images, Cypress often infers this or you might set it tonull.options(optional): An object to modify default behavior, such astimeout. The default timeout forcy.fixture()isfixturesFolder.
Example: Loading JSON Data
Section titled “Example: Loading JSON Data”Let’s say you have a cypress/fixtures/user.json file with the following content:
{ "username": "testUser", "email": "test@example.com", "password": "securePassword123"}You can load and use this data in your test:
describe('Login Functionality', () => { it('should login with valid credentials from fixture', () => { cy.fixture('user.json').then((userData) => { cy.visit('/login'); cy.get('input[name="username"]').type(userData.username); cy.get('input[name="password"]').type(userData.password); cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard'); cy.contains(`Welcome, ${userData.username}`).should('be.visible'); }); });});Using Fixtures with beforeEach or before Hooks
Section titled “Using Fixtures with beforeEach or before Hooks”For data that’s used across multiple tests in a suite, it’s common to load fixtures in a beforeEach or before hook. You can use an alias (.as()) or the this context (with standard functions, not arrow functions for hooks/tests) to make the data available.
Using Aliases (.as())
Section titled “Using Aliases (.as())”describe('User Profile Tests', () => { beforeEach(() => { // Load fixture and alias it cy.fixture('userProfile.json').as('profileData'); cy.visit('/profile'); });
it('should display user information correctly', function() { // Use 'function' for 'this' context with aliases // Access aliased data using this.profileData cy.get('#userNameDisplay').should('contain.text', this.profileData.name); cy.get('#userEmailDisplay').should('contain.text', this.profileData.email); });
it('should allow updating profile details', function() { cy.get('input[name="name"]').clear().type(this.profileData.newName); // ... other actions });});To use this.profileData, the test (it) and hook (beforeEach) must be standard functions, not arrow functions, because arrow functions do not have their own this binding.
Using this Context Directly (Traditional Approach)
Section titled “Using this Context Directly (Traditional Approach)”describe('Registration Form', function() { // Note: using 'function' for 'this' context before(function() { cy.fixture('registrationData.json').then(function(data) { this.testData = data; // Assign to 'this' context }); });
it('should fill and submit the registration form', function() { cy.visit('/register'); cy.get('input[name="fullName"]').type(this.testData.fullName); cy.get('input[name="email"]').type(this.testData.email); // ... fill other fields using this.testData cy.get('button[type="submit"]').click(); cy.contains('Registration successful!').should('be.visible'); });});Other Fixture File Types
Section titled “Other Fixture File Types”Fixtures are not limited to JSON. You can load images, text files, HTML, etc.
- Images:
cy.fixture('logo.png').then(fileContent => cy.get('input[type="file"]').attachFile({ fileContent, fileName: 'logo.png', mimeType: 'image/png' }));(usingcypress-file-uploadplugin as an example for attaching). - Text Files:
cy.fixture('sample.txt').should('contain', 'Expected text');
Practical Application: Data-Driven Tests
Section titled “Practical Application: Data-Driven Tests”Fixtures are essential for data-driven testing, where you run the same test logic with multiple data sets.
Example: cypress/fixtures/loginCredentials.json
[ { "username": "validUser", "password": "validPass", "shouldSucceed": true }, { "username": "invalidUser", "password": "wrongPass", "shouldSucceed": false }, { "username": "validUser", "password": "", "shouldSucceed": false }]Test file:
describe('Login Data-Driven Tests', () => { beforeEach(() => { cy.visit('/login'); });
it('processes multiple login attempts from fixture', () => { cy.fixture('loginCredentials.json').then((credentialsList) => { credentialsList.forEach((creds) => { cy.get('input[name="username"]').clear().type(creds.username || ''); // Handle empty username cy.get('input[name="password"]').clear().type(creds.password || ''); // Handle empty password cy.get('button[type="submit"]').click();
if (creds.shouldSucceed) { cy.url().should('include', '/dashboard'); cy.visit('/login'); // Navigate back for next iteration if needed } else { cy.get('.error-message').should('be.visible'); // Clear fields or refresh page as needed for next iteration cy.reload(); // Simple way to reset for next iteration } }); }); });});Note: For more complex data-driven scenarios, iterating within a single it block can make debugging harder. Consider generating tests dynamically if each data set represents a distinct test case. See Cypress documentation on dynamic tests.
Further Reading: