Cypress下拉框断言异常:have.value失败但contains.text成功
Cypress下拉框断言问题处理方案
问题描述
使用Cypress开展自动化测试时,针对下拉框选择随机数值后的验证场景,使用断言.should('have.value', random_minute)会触发AssertionError,但改用.should('contains.text', random_minute)时测试可正常通过。疑问:该如何处理?应判定测试通过还是失败?
报错代码(使用have.value)
it('Dropdowns of schedule are working accordingly', () => { var checkbox_name = ['dayOfWeekMon', 'dayOfWeekTue', 'dayOfWeekWed', 'dayOfWeekThu', 'dayOfWeekFri', 'dayOfWeekSat', 'dayOfWeekSun']; var week_wise = ['First', 'Second', 'Third', 'Forth'] var word = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; var month_word = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'Decemeber' ]; const random_hour = getRandomArbitrary(1, 24) const random_dayoftheweek = getRandomDayOftheWeek(word) const random_monthoftheyear = getRandomDayOftheWeek(month_word) const select_period = ['Minutes', 'Daily', 'Weekly', 'Monthly', 'Yearly'] cy.wait(10000) if (cy.isChecked('#scheduleToggle')) { cy .get('#scheduleToggle') .check({ force: true }) } cy .get('#openCronSchedulerModal') .should('be.visible') .click({ force: true }) cy .get('.cron-period-select') .should('have.value', 'Minutes') select_period.forEach(($period) => { switch ($period) { case "Minutes": const random_minute = getRandomArbitrary(1, 60) cy .get('.cron-minutes-select') .should('be.visible') .select(random_minute) // .should('contains.text', random_minute) .should('have.value', random_minute) break; // 其他case代码省略 }) })
输出:触发AssertionError
测试通过代码(使用contains.text)
it('Dropdowns of schedule are working accordingly', () => { var checkbox_name = ['dayOfWeekMon', 'dayOfWeekTue', 'dayOfWeekWed', 'dayOfWeekThu', 'dayOfWeekFri', 'dayOfWeekSat', 'dayOfWeekSun']; var week_wise = ['First', 'Second', 'Third', 'Forth'] var word = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; var month_word = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'Decemeber' ]; const random_hour = getRandomArbitrary(1, 24) const random_dayoftheweek = getRandomDayOftheWeek(word) const random_monthoftheyear = getRandomDayOftheWeek(month_word) const select_period = ['Minutes', 'Daily', 'Weekly', 'Monthly', 'Yearly'] cy.wait(10000) if (cy.isChecked('#scheduleToggle')) { cy .get('#scheduleToggle') .check({ force: true }) } cy .get('#openCronSchedulerModal') .should('be.visible') .click({ force: true }) cy .get('.cron-period-select') .should('have.value', 'Minutes') select_period.forEach(($period) => { switch ($period) { case "Minutes": const random_minute = getRandomArbitrary(1, 60) cy .get('.cron-minutes-select') .should('be.visible') .select(random_minute) .should('contains.text', random_minute) // .should('have.value', random_minute) break; // 其他case代码省略 }) })
输出:测试通过
对应HTML结构
<select class="cron-minutes-select"><option value="1" selected="selected">1</option> <option value="2">2</option> <option value="3">3</option> <!-- 省略中间选项 --> <option value="59">59</option> <option value="60">60</option> </select>
问题原因
- 类型不匹配:HTML中option的
value属性是字符串类型(如value="1"),但getRandomArbitrary(1,60)返回的是数字类型。Cypress的have.value断言采用严格匹配(包含类型校验),数字和字符串不相等,因此触发断言错误。 contains.text的逻辑特性:该断言仅检查元素文本内容是否包含目标值,数字会被自动转为字符串,和option的文本内容一致,因此测试通过。
处理方案
方案1:将随机数转为字符串
修改随机数生成逻辑,确保和option的value类型一致:
case "Minutes": // 先取整(避免getRandomArbitrary返回浮点数)再转字符串 const random_minute = String(Math.floor(getRandomArbitrary(1, 60))) cy .get('.cron-minutes-select') .should('be.visible') .select(random_minute) .should('have.value', random_minute) break;
方案2:断言时转换类型
如果不想修改随机数生成逻辑,可以在断言时临时转换类型:
.should('have.value', String(random_minute))
结论
不能因为contains.text断言通过就判定测试通过——下拉框的核心业务值是value属性(表单提交时传递的是该值),文本仅为前端展示用。使用have.value验证选中值才是更严谨的测试方式,修复类型不匹配问题后,用have.value的断言结果才是有效的测试结论。
内容的提问来源于stack exchange,提问作者Avdhut Joshi
相关产品推荐
相关产品推荐

