【问题标题】:Cypress.io - Assert no XHR requests to URL?Cypress.io - 断言没有对 URL 的 XHR 请求?
【发布时间】:2018-04-27 23:06:12
【问题描述】:

使用 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.');
});

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

【问题讨论】:

  • 在执行某些 UI 操作时,是否有办法检查网络选项卡中调用的特定 API?

标签: cypress


【解决方案1】:

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

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

这样的断言只会给你的测试增加不必要的时间。这种类型的测试称为Conditional Testing as mentioned in the Cypress Docs

【讨论】:

  • "...断言事情没有发生通常更糟糕" - 我们通过使用 cy.get 调用而不是单击取消按钮后观察发生的 DOM 更改来解决这个问题cy.wait 所以我们知道动作在没有调用路由的情况下执行了。
  • 您如何知道在单击取消按钮后等待 DOM 更改的时间?
  • 我们在调用和隐藏取消对话框按钮所在的模式之间建立了良好的先发制人关系,因此我们可以依赖于对话框消失时完成的请求。为此,我们只是在 cy.get 调用中使用默认等待时间来等待模态框再次被隐藏,然后假设由于没有发生错误并且对话框已关闭,因此请求没有发生。
  • 与此类似,我们正在测试组件是否在客户端正确缓存数据(以节省昂贵的查询)。如果组件更新为预期的内容,但在更新时没有触发任何请求,那么我们知道它一定已经从缓存中获取了数据。
【解决方案2】:

我认为您可以比较 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);

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多