Cypress - 测试固件
Cypress - 使用 Fixtures 管理测试数据
Section titled “Cypress - 使用 Fixtures 管理测试数据”Cypress fixtures(测试夹具)用于管理测试可能需要的静态数据。它们通常是存储在 cypress/fixtures 文件夹中的外部文件(例如,JSON、CSV、图像、HTML)。Fixtures 有助于将测试数据与测试逻辑分离,使测试更清晰、更易于维护,尤其适用于数据驱动测试。
默认情况下,Cypress 会在 cypress/fixtures 目录中查找 fixture 文件。你可以在此目录下的子文件夹中组织你的 fixtures。
使用 cy.fixture()
Section titled “使用 cy.fixture()”cy.fixture() 命令用于加载 fixture 文件。它会返回文件的内容,这些内容随后可以在后续的 Cypress 命令或断言中使用。
cy.fixture(filePath)cy.fixture(filePath, encoding)cy.fixture(filePath, options)cy.fixture(filePath, encoding, options)其中:
filePath: fixture 文件路径(相对于cypress/fixtures文件夹)。例如,‘user.json’, ‘test-data/credentials.json’。encoding(可选): 要使用的编码(例如,‘utf8’, ‘ascii’)。大多数文本文件默认为 ‘utf8’。对于图像等二进制文件,Cypress 通常会推断编码,或者你可以将其设置为null。options(可选): 一个对象,用于修改默认行为,例如timeout。cy.fixture()的默认超时设置是fixturesFolder。
示例:加载 JSON 数据
Section titled “示例:加载 JSON 数据”假设你在 cypress/fixtures/user.json 中有以下内容:
{ "username": "testUser", "email": "test@example.com", "password": "securePassword123"}你可以在测试中加载并使用这些数据:
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'); }); });});在 beforeEach 或 before Hooks 中使用 Fixtures
Section titled “在 beforeEach 或 before Hooks 中使用 Fixtures”对于在套件中多个测试中使用的数据,通常在 beforeEach 或 before hook 中加载 fixtures。你可以使用 alias (.as()) 或 this 上下文(结合标准 function,而不是 hook/测试中的箭头函数)来使数据可用。
使用 Aliases (.as())
Section titled “使用 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 });});要使用 this.profileData,测试 (it) 和 hook (beforeEach) 必须是标准函数(function() {}),而不是箭头函数(() => {}),因为箭头函数没有自己的 this 绑定。
直接使用 this 上下文 (传统方法)
Section titled “直接使用 this 上下文 (传统方法)”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'); });});其他 Fixture 文件类型
Section titled “其他 Fixture 文件类型”Fixtures 不仅限于 JSON。你可以加载图像、文本文件、HTML 等。
- 图像:
cy.fixture('logo.png').then(fileContent => cy.get('input[type="file"]').attachFile({ fileContent, fileName: 'logo.png', mimeType: 'image/png' }));(使用cypress-file-upload插件作为附加文件的示例)。 - 文本文件:
cy.fixture('sample.txt').should('contain', 'Expected text');
实际应用:数据驱动测试
Section titled “实际应用:数据驱动测试”Fixtures 对于数据驱动测试至关重要,你可以在其中使用多个数据集运行相同的测试逻辑。
示例: cypress/fixtures/loginCredentials.json
[ { "username": "validUser", "password": "validPass", "shouldSucceed": true }, { "username": "invalidUser", "password": "wrongPass", "shouldSucceed": false }, { "username": "validUser", "password": "", "shouldSucceed": false }]测试文件:
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 } }); }); });});注意:对于更复杂的数据驱动场景,在单个 it 块内迭代可能会使调试变得困难。如果每个数据集都代表一个独特的测试用例,可以考虑动态生成测试。请参阅 Cypress 文档关于动态测试的内容。
进一步阅读: