我想我们都知道 cypress 和软断言已经被讨论得死去活来,并且有各种实现软解决方案的解决方案。一段时间以来,我一直在使用以下代码,基于旧的堆栈问题cypress 支持软断言吗?:
let isSoftAssertion = false;
let errors = [];
chai.softExpect = function ( ...args ) {
isSoftAssertion = true;
return chai.expect(...args);
},
chai.softAssert = function ( ...args ) {
isSoftAssertion = true;
return chai.assert(...args);
}
const origAssert = chai.Assertion.prototype.assert;
chai.Assertion.prototype.assert = function (...args) {
if ( isSoftAssertion ) {
try {
origAssert.call(this, ...args)
} catch ( error ) {
errors.push(error);
}
isSoftAssertion = false;
} else {
origAssert.call(this, ...args)
}
};
// monkey-patch `Cypress.log` so that the last `cy.then()` isn't logged to command log
const origLog = Cypress.log;
Cypress.log = function ( data ) {
if ( data && data.error && /soft assertions/i.test(data.error.message) ) {
data.error.message = '\n\n\t' + data.error.message + '\n\n';
throw data.error;
}
return origLog.call(Cypress, ...arguments);
};
// monkey-patch `it` callback so we insert `cy.then()` as a last command
// to each test case where we'll assert if there are any soft assertion errors
function itCallback ( func ) {
func();
cy.then(() => {
if ( errors.length ) {
const _ = Cypress._;
let msg = '';
if ( Cypress.browser.isHeaded ) {
msg = 'Failed soft assertions... check log above ↑';
} else {
_.each( errors, error => {
msg += '\n' + error;
});
msg = msg.replace(/^/gm, '\t');
}
throw new Error(msg);
}
});
}
const origIt = window.it;
window.it = (title, func) => {
origIt(title, func && (() => itCallback(func)));
};
window.it.only = (title, func) => {
origIt.only(title, func && (() => itCallback(func)));
};
window.it.skip = (title, func) => {
origIt.skip(title, func);
};
beforeEach(() => {
errors = [];
});
afterEach(() => {
errors = [];
isSoftAssertion = false;
});
到目前为止,这一直运行良好!我现在需要测试跨源...对于针对我的基本 URL 的断言,没有任何变化...但是当我尝试在 cy.origin 中使用 softExpect 时,断言正确通过/失败,但父断言无论如何,测试都会通过。例如:
describe('dummy test', () => {
it('tests without cy.origin - this will fail correctly', () => {
chai.softExpect(1).to.equal(2)
})
it('tests without cy.origin - the assertion will fail, but test is passed', () => {
cy.origin('some.url', () => {
Cypress.require('../../support/modules/soft_assertions.js')
chai.softExpect(1).to.equal(3)
})
})
})
谁能告诉我这是为什么吗?或者我如何才能将 1+ 软断言失败的事实传递回使用 cy.origin 的顶层“it”块?
蒂亚!
对 为什么它通过测试 的简短回答是
cy.origin()
为您提供了一个不同的 Cypress 实例。使用 Cypress.require()
导入的任何模块也有一个单独的实例。
外部(主)实例不知道内部原始实例中发现的软断言。
最快的解决方法是按照单例模式的方式更改模块,但由于猴子补丁,我坚持使用你的代码。
我是根据这个问题来实现的如何使用npm包在Cypress中使用软断言软断言。
一般来说,跨多个来源使用任何包
Cypress.require()
导入包(在您的情况下已完成)
Yielding-a-value
从cy.origin()
返回产量数据
柏树/支持/e2e
const jsonAssertion = require("soft-assert")
Cypress.Commands.add('softAssert', (actual, expected, message) => {
jsonAssertion.softAssert(actual, expected, message)
if (jsonAssertion.jsonDiffArray?.length) {
jsonAssertion.jsonDiffArray.forEach(diff => {
const log = Cypress.log({
name: 'Soft assertion error',
displayName: 'softAssert',
message: diff.error.message.split('message:')[1].trim()
})
log.set({state: 'failed', end: true})
})
}
cy.wrap(jsonAssertion, {log:false}) // return the internal instance (data only)
});
Cypress.Commands.add('combineSoftResults', (resultsFromOrigin) => {
resultsFromOrigin.jsonDiffArray.forEach(jsonDiff => {
const {actual, expected, message} = jsonDiff.error
jsonAssertion.softAssert(actual, expected, message) // sync with main instance
})
})
Cypress.Commands.add('softAssertAll', () => {
if (jsonAssertion.softAssertCount) throw new Error('Failed soft assertions')
})
测试
我添加了一个新的cy.origin2()
命令来组合结果,但如果愿意,您可以只应用 Cypress 文档中给出的模式。
context('soft assert', () => {
Cypress.Commands.add('origin2', (...args) => {
cy.origin(...args).then(result => {
cy.combineSoftResults(result)
})
})
it('testing numbers with soft-assert', () => {
cy.softAssert(1, 2) // main test soft fail
cy.origin2('https://example.com', () => {
Cypress.require('../support/e2e')
cy.softAssert(1, 3) // origin soft fail
})
cy.softAssert(1, 4) // main test soft fail
cy.softAssertAll() // throw to fail test
})
})
结果
内外都有软故障cy.origin()
cy.origin()
cy.softAssertAll()
,测试会通过,但显示软故障。