如何在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
相关产品推荐
相关产品推荐

