如何在Cypress中定义全局变量实现跨测试文件复用?
解决Cypress API测试中复用手机号与用户ID的问题
先排查现有代码的核心问题
- 命令名不匹配:
createUser中调用了未定义的cy.generateRandomMobileNumber(),实际定义的命令是generateAndSetMobileNumber,导致每次创建用户时可能生成新手机号 - 命令未返回值:
generateAndSetMobileNumber没有返回手机号,导致createUser无法正确获取已缓存的手机号 - 测试文件语法错误:
before钩子的写法错误,且变量名不统一(prospectId与UserId混用) - 变量未声明:测试代码中直接使用未声明的
prospectId、mobileNumber,存在全局变量污染风险
步骤1:修复commands.js代码
修改命令逻辑,确保手机号只生成一次,且返回必要的用户信息:
import { faker } from '@faker-js/faker'; Cypress.Commands.add('generateAndSetMobileNumber', () => { // 检查环境变量中是否已存在手机号,不存在则生成 if (!Cypress.env('mobileNumber')) { const mobileNumber = faker.datatype.number({ min: 5700000000, max: 5899999999 }).toString(); Cypress.env('mobileNumber', mobileNumber); } // 返回已缓存的手机号 return cy.wrap(Cypress.env('mobileNumber')); }); Cypress.Commands.add('createUser', () => { // 使用正确的命令名获取手机号 return cy.generateAndSetMobileNumber().then((mobileNumber) => { return cy.api({ failOnStatusCode: false, method: 'POST', url: '/products/users/', body: { "countryCode": "971", "mobileNo": mobileNumber, "viewId": "createView", "agentCode": "", "language": "EN", } }).then((response) => { expect(response.status).to.eq(201); const prospectId = response.body.userId; // 将用户ID存入环境变量 Cypress.env('prospectId', prospectId); // 返回手机号和用户ID,方便测试用例直接使用 return cy.wrap({ mobileNumber, prospectId }); }); }); });
步骤2:修复测试文件代码
修正语法错误,统一变量名,确保正确读取环境变量:
describe("Generating OTP", () => { before(() => { // 正确调用createUser命令,只执行一次 cy.createUser(); }); it("Verify user is able to generate OTP by entering their mobile number", () => { // 声明变量并读取环境变量中的值 const prospectId = Cypress.env('prospectId'); const mobileNumber = Cypress.env('mobileNumber'); cy.api({ failOnStatusCode: false, method: 'POST', url: 'products/otp', body: { "action": "generate", "prospectId": prospectId, "countryCode": "971", "mobileNo": mobileNumber, } }).then((response) => { expect(response.status).to.eq(200); expect(prospectId).to.have.length(5); expect(response.body.verified).to.eq(true); }); }); });
步骤3:跨测试文件复用(如果需要)
如果要在多个测试文件中复用同一手机号和用户ID,可按以下方式处理:
方案1:全局before钩子
在cypress/support/e2e.js中添加全局前置钩子,确保createUser只执行一次:
before(() => { // 仅当未创建用户时执行 if (!Cypress.env('prospectId')) { cy.createUser(); } });
方案2:使用Cypress Session(Cypress 12+)
利用Session功能持久化用户信息,避免重复创建:
// 在commands.js中添加 Cypress.Commands.add('getOrCreateUser', () => { cy.session('test-user', () => { cy.createUser(); }, { validate: () => { // 验证用户信息是否存在 expect(Cypress.env('mobileNumber')).to.exist; expect(Cypress.env('prospectId')).to.exist; } }); }); // 在测试文件中使用 before(() => { cy.getOrCreateUser(); });
关键说明
- API测试运行在Node环境,浏览器的
localStorage无法生效,因此无需使用cypress-localstorage-commands插件 Cypress.env默认是全局作用域,只要不重启Cypress,值会一直保留;若需要跨Cypress会话持久化,可将值写入本地文件(如cypress/fixtures/user.json),在测试开始时读取
内容的提问来源于stack exchange,提问作者Mariam Aslam
相关产品推荐
相关产品推荐

