如何断言Cypress自定义命令执行失败?
如何断言Cypress自定义命令执行失败?
要复用现有自定义命令断言其执行失败,核心是解决命令在找不到元素时直接抛出错误、导致后续断言无法执行的问题。以下是具体可行的方案:
问题根源
你的测试代码cy.getTableRowContainingText('not-there').should('not.exist')失败,是因为当表格未渲染时,命令中的cy.get('table')找不到元素,直接抛出错误终止测试,根本没机会执行.should('not.exist')断言。
最优解决方案:修改自定义命令,兼容“存在/不存在”两种断言
修改命令逻辑,让它在找不到目标元素时不抛出错误,而是返回空的Chainable对象,这样就能直接用.should('exist')或.should('not.exist')完成两种场景的断言,完全复用现有命令,符合DRY原则。
修改后的getTableRowContainingText命令:
// support/commands.ts Cypress.Commands.add('getTableRowContainingText', (text: string): Cypress.Chainable<JQuery<HTMLElement>> => { return cy.get('table', { failOnNotFound: false }).then($table => { // 表格不存在时直接返回空链 if (!$table.length) return cy.wrap([]) // 查找包含目标文本的单元格 const $targetTd = $table .first() .find('tbody > tr > td') .filter(`:contains(${text})`) .first() // 找不到对应单元格时返回空链,否则返回其父行 return $targetTd.length ? cy.wrap($targetTd.parent('tr')) : cy.wrap([]) }) })
测试代码使用示例
// e2e/test.cy.ts // 断言表格行存在 cy.getTableRowContainingText('existing-item').should('exist') // 断言表格行不存在(删除后场景) cy.getTableRowContainingText('deleted-item').should('not.exist')
备选方案:捕获命令执行错误(不修改原命令)
如果不想修改原命令,可以通过Cypress.once('fail')捕获命令执行时的错误,验证错误类型后标记测试通过。这种方式适合保留原命令“找不到元素即抛错”的默认行为,仅在特定测试中临时捕获:
it('验证删除后表格行不存在', () => { cy.wrap(null).then(() => { return new Cypress.Promise((resolve) => { // 仅捕获一次失败事件 Cypress.once('fail', (err) => { // 验证错误是因为找不到元素(可根据实际错误信息调整匹配规则) expect(err.message).to.include('could not find any element') resolve() }) // 执行自定义命令 cy.getTableRowContainingText('not-there') }) }) })
注意事项
- 方案一(修改命令)更简洁通用,推荐作为首选;
:contains选择器是大小写敏感的,若需要忽略大小写,可替换为自定义过滤逻辑(如filter((index, el) => el.textContent.toLowerCase().includes(text.toLowerCase())));- 若命令中有多个可能抛错的
cy.get/find操作,都需要通过failOnNotFound: false或手动判断长度来避免提前抛错。
内容的提问来源于stack exchange,提问作者shennan
相关产品推荐
相关产品推荐

