You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cucumber报告中展示Nightwatch VRT视觉回归测试的失败用例

解决方案

问题根源

  • Nightwatch 内置的verify属于软断言,默认只会记录失败日志不会标记用例失败,和Cucumber集成时失败状态没有同步到Cucumber报告上下文,因此会出现对比失败但用例标记通过的问题
  • assert属于硬断言,一旦失败就抛出未捕获错误终止测试流程,不符合跑完所有用例的需求

实现步骤

第一步:配置Cucumber全局钩子同步软断言状态

在Cucumber的全局钩子文件(比如hooks.js或cucumber.conf.js)中添加以下逻辑,捕获Nightwatch软断言失败并同步到Cucumber报告:

const fs = require('fs')

// 场景执行前重置软断言计数,避免跨场景污染
Before(() => {
  browser.verify.reset()
})

// 每个步骤执行完同步校验状态
AfterStep(async function (step, scenario) {
  const verifyFailures = browser.verify.failures
  if (verifyFailures.length > 0) {
    // 遍历所有失败项,把错误信息和差异图附加到Cucumber步骤
    for (const fail of verifyFailures) {
      this.attach(`VRT校验失败:${fail.message}`, 'text/plain')
      // 可选:嵌入差异截图到报告
      if (fail.screenshotDiffPath && fs.existsSync(fail.screenshotDiffPath)) {
        const diffImg = fs.readFileSync(fail.screenshotDiffPath, {encoding: 'base64'})
        this.attach(diffImg, 'image/png')
      }
    }
    // 标记当前步骤为失败
    return Promise.reject(new Error(`当前步骤共${verifyFailures.length}条校验失败`))
  }
})

// 场景执行完清空失败记录
After(() => {
  browser.verify.reset()
})

第二步:替换测试代码中的断言指令

把原代码中所有assert.screenshotIdenticalToBaseline替换为verify.screenshotIdenticalToBaseline,修改后测试函数示例如下:

Test2(){
  var radioButtonLink = '//a[@id="RadioButton"]';
  var RadioButton = '//div[@title="Personne physique"]//span';
  var image = '//span[@class="picto-up-vert-small"]';
  var EmojiRBtn = '//div[@class="doc_example"][3]//div[@class="ca_checkbox_main"]//*[contains(text(), "Activer/Désactiver")]';

  return this
    .waitForElementPresent('@Frame', 1000,'iframe is found')
    .getAttribute('@Frame', 'id', function(result) {
      var iframe_id = result.value;             
      var iframe_CCV =this.frame(iframe_id); 
      iframe_CCV
        .waitForElementVisible(radioButtonLink, 500, 'lien radio button visible')
        .click(radioButtonLink)             
    })  

    .getAttribute('@FrameContent', 'id', function(result) {
      var iframe_content_id = result.value;            
      var iframe_content =this.frame(iframe_content_id); 
      iframe_content
        .waitForElementVisible(RadioButton, 1000,'radio button is found')
        .click(RadioButton)

        .waitForElementVisible(image, 1000,'image emoji is found')
        // 替换为软断言
        .verify.screenshotIdenticalToBaseline(image, 'image Emoji', {threshold: 0}, 'VRT complete.')
        
        .waitForElementVisible(EmojiRBtn, 1000,'radio button emoji is found')
        .click(EmojiRBtn)
        .pause(1000)
        // 替换为软断言
        .verify.screenshotIdenticalToBaseline(image, 'image Emoji after click', {threshold: 0}, 'VRT complete.')
    })
}

最终效果

  • 所有测试用例可以完整执行,不会因为单条VRT校验失败中断后续流程
  • VRT校验失败的文字说明、差异截图都会展示在对应Cucumber步骤的详情中
  • 存在校验失败的用例会被正确标记为失败状态,不会误判为通过

内容的提问来源于stack exchange,提问作者Nouha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 05:15:00