Cypress wrap内动态添加测试:解决表格行测试rowsUUID未定义问题
问题根本原因
Cypress 运行测试分为两个阶段:
- 代码扫描阶段:优先执行所有顶层代码,完成所有
it测试用例、生命周期钩子的注册,此阶段不会执行it内部的代码,也不会执行 Cypress 异步命令的实际逻辑。 - 测试执行阶段:按顺序执行已注册的钩子和
it内部代码。
你写在顶层的 Cypress._.range(...).forEach(...) 属于代码扫描阶段执行的逻辑,此时第一个 it 内部给 rowsUUID 赋值的逻辑还未运行,所以 rowsUUID 始终是初始的 undefined。
可行解决方案
方案1:单测试内用软断言实现行独立校验
如果你的表格数据是页面渲染生成、无法提前从接口获取,推荐用这种方式,单条行校验失败不会阻断其他行的执行,同时可以清晰标记每一行的校验结果。
首先安装软断言依赖:
npm install cypress-soft-assertions
然后在 cypress/support/e2e.js 引入:
import 'cypress-soft-assertions'
测试代码调整为:
it('校验所有符合条件的表格行状态为succeeded', () => { cy.fixture('esign').then($esignStore => { cy.wait(2000); cy.get('table[data-qa="act_ops_log_table"] tbody[data-qa="act_ops_log_table_body"]') .children('tr') .then($rows => { // 过滤符合条件的行 const rowsUUID = $rows.filter(index => $rows.eq(index).is(`:contains(${$esignStore.requestUUID})`)); expect(rowsUUID).not.undefined; expect(rowsUUID).length.gt(0); // 遍历每行校验,用软断言实现单条失败不阻断 Cypress._.range(0, rowsUUID.length).forEach(($rowIndex: number) => { const rowUUID = rowsUUID[$rowIndex]; const status = rowUUID.cells[2].textContent.replace(/\s/g, ''); // 每条校验前打日志区分行 cy.log(`校验第 ${$rowIndex} 行状态`); cy.softExpect(status).to.be.a('string').equals('succeeded'); }); // 最后断言所有软校验结果 cy.assertSoftAssertions(); }); }); });
方案2:提前获取数据动态生成独立测试用例
如果表格数据可通过后端接口直接获取,你可以在代码扫描阶段用同步请求拿到数据,再动态生成 it 测试用例:
// 顶层代码用同步请求提前拿表格数据 const axios = require('axios'); let tableRows = []; // 同步请求接口拿数据,注意要配置好请求域名、鉴权信息 const request = async () => { const esignData = require('../fixtures/esign.json') const res = await axios.get('你的表格数据接口地址', { headers: { // 按需补充鉴权头 } }); tableRows = res.data.filter(row => row.uuid === esignData.requestUUID); }; // 等待数据返回后再注册测试用例 before(async () => { await request(); }); // 动态生成测试用例 Cypress._.range(0, tableRows.length).forEach(($rowIndex: number) => { it(`校验第 ${$rowIndex} 行状态为succeeded`, () => { expect(tableRows[$rowIndex].status.replace(/\s/g, '')).to.equal('succeeded'); }); });
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

