首次调用selectPupil方法正常,第二次传参为何变为undefined?
Cypress 10.10.0中第二次调用selectPupil参数变为undefined的问题解决
问题描述
使用Cypress 10.10.0编写测试时,首次调用programs.selectPupil方法传入batchEnrollerChildId和batchEnrollerChildName参数时正常运行,但第二次调用该方法时,参数childId和childName变为undefined,触发断言错误。
测试代码
const programs = new require('../actions/programs.action') describe('Batch Enroller tests', () => { const batchEnrollerChildId = 43607 const batchEnrollerChildName = 'Child, Batch Enroller' it.only('Enroll and Unenroll student', () => { const programsTable = [['Universal Program', 'Universal Group', 'Universal', '$0.00'], ['Custom Program', 'Custom Group', 'Custom', '$100.00'], ['Monthly Program', 'Monthly Group', 'Monthly', '$50.00'], ['Monthly Dynamic Program', 'Monthly Group', 'Monthly Dynamic', '$10.00']] programs.goToProgramsPage() programs.openBatchEnrollerTab() programs.selectPupil(batchEnrollerChildId, batchEnrollerChildName) programs.selectPrograms(programsTable) programs.checkProgramTable(programsTable) programs.enroll() programs.goToProgramsPage() programs.openBatchEnrollerTab() programs.selectPupil(batchEnrollerChildId, batchEnrollerChildName) programsTable.forEach(function(program) { const programName = program[0] programs.isProgramSelected(programName) }) programs.checkProgramTable(programsTable) programs.unenroll() })
方法定义
const pupilsList = 'pupils_list' const selectProgramField = '[value="Select program"]' export function clickPupilCheckbox(childId) { cy.get(`[value="${childId}"]`) .parent() .click() } export function selectPupil(childId, childName) { cy.get(`[href="#${pupilsList}"]`).click() .parent() .should('have.class', 'active') cy.get(`[id="${pupilsList}"]`).should('be.visible') cy.get(`[data-id="${childId}"]`) .as('childName') .should('have.text', childName) clickPupilCheckbox(childId) cy.get('@childName') .parent() .should('have.class', 'selected_pupils') }
错误日志
Console was cleared index.656179c6.js:99332 Command: assert index.656179c6.js:99332 Message: expected [data-id="undefined"] to have text undefined, but the text was '' index.656179c6.js:99332 Error: AssertionError: expected '[data-id="undefined"]' to have text undefined, but the text was ''
原因分析
核心问题:错误的模块实例化方式
测试代码中使用new require('../actions/programs.action')是错误写法。require返回的是模块导出的普通对象(包含多个函数),而非构造函数。使用new关键字会导致programs对象的方法上下文被异常修改,第一次调用可能因临时缓存正常执行,但第二次调用时参数传递机制失效,导致childId和childName变为undefined。潜在问题:全局别名冲突
Cypress的别名(如@childName)是全局作用域的,在同一条测试用例中,第二次调用selectPupil时,cy.get('@childName')会优先获取第一次设置的别名,而新的别名还未完成绑定,可能加剧断言错误,但此问题是由第一个核心问题引发的次生问题。
解决方案
1. 修正模块引用方式
去掉new关键字,直接使用require获取模块导出的对象:
// 错误写法 // const programs = new require('../actions/programs.action') // 正确写法 const programs = require('../actions/programs.action')
如果项目使用ES模块语法,也可以改为:
import * as programs from '../actions/programs.action'
2. 优化别名避免全局冲突(可选)
为了避免同一条测试用例中全局别名的冲突,可以将别名改为局部唯一名称:
export function selectPupil(childId, childName) { cy.get(`[href="#${pupilsList}"]`).click() .parent() .should('have.class', 'active') cy.get(`[id="${pupilsList}"]`).should('be.visible') // 使用结合childId的唯一别名 cy.get(`[data-id="${childId}"]`) .as(`childName-${childId}`) .should('have.text', childName) clickPupilCheckbox(childId) cy.get(`@childName-${childId}`) .parent() .should('have.class', 'selected_pupils') }
内容的提问来源于stack exchange,提问作者andrefrc
相关产品推荐
相关产品推荐

