16

使用 cypress.io 进行测试时,是否有一种好方法可以断言没有对给定 URL 发出 XHR 请求?

我想断言单击“保存”按钮时会添加一个新的 foo,但单击“取消”按钮时不会添加新的 foo。

像这样的东西:

cy.route('POST', '/foos').as('postFoo');
cy.get('.cancel-button').click();
cy.route('@postFoo').should('not.have.been.called'); // (magic imaginary syntax!)

我已经尝试使用执行 assert.fail 的 onRequest 回调设置 cy.route,但是当调用 URL 时,测试并没有失败。

现在,我正在捕捉我的(有意的)“未发生请求”错误,如下所示:

cy.on('fail', (err, runnable) => {
  expect(err.message).to.include('No request ever occurred.');
  return false;
});  

cy.wait('@postFoo', { timeout: 0 }).then(xhr => {
  throw new Error('Unexpected API call.');
});

...这似乎有效,但肯定感觉不是很“柏树”。

4

3 回答 3

8

您可以重新别名route并更改其onRequest行为以抛出;然而,断言事情没有发生通常更糟糕,因为它们是非确定性的。在继续之前,您应该等待错误多长时间?

cy.route({
  method: 'POST',
  url: '/foos',
  onRequest: () => {
    throw new Error('Whoops')
  }
})
cy.get('.cancel-button').click();
cy.wait(1000)  // give it one second to throw, then move on

有这样的断言只会给你的测试增加不必要的时间。这种类型的测试被称为赛普拉斯文档中提到的条件测试

于 2018-06-28T11:42:04.037 回答
0

断言:

.should('not.have.been.called')

不能用于检查是否已发出网络请求。它用于 cy.spy()

您的 hack 有效,但您也可以尝试:

cy.intercept('POST', '/foos').as('postFoo');
cy.get('.cancel-button').click();
cy.wait('@postFoo').should('not.exist'); // (magic imaginary syntax!)
于 2022-01-28T20:51:40.027 回答
0

我认为您可以比较数据cy.state('routes')并检查状态。

let routes = cy.state('routes');
// check each URL and if it has "/foos" in it, add it to an array to test
// this step is just an example, there are plenty of different ways to approach this
let foosRoutes = [];
for (let route in routes) {
  for (let req in routes[route].requests) {
    let reqUrl = routes[route].requests[req].request.url;
    // test each URL for "/foos" and if it has it, add the URL to the array
    if((/\/foos/).test(reqUrl)) {
      fooRoutes.push(reqUrl);
    }
  }
};
expect(foosRoutes).to.have.property("length", 0);

或者,如果您以不同的方式进行挖掘,也许您可​​以按ofcy.state('routes')过滤,然后确保其为空或您期望的计数。aliaspostFoorequests

于 2021-06-01T19:36:11.683 回答