赛普拉斯请求重试 [英] Cypress request with retry

查看:57
本文介绍了赛普拉斯请求重试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在赛普拉斯测试中,我需要通过调用外部API来验证操作.API调用将始终返回结果(来自先前的运行),因此我不能简单地调用一次并验证结果.我需要重试几次,直到找到与当前运行匹配的整体超时/故障.获得当前结果所需的时间差异很大;我真的不能在这个电话会议前花很长时间疯狂.
请参见下面的摘录中的注释;一旦我在一个循环中尝试一个请求,它就永远不会被调用.使用 cy.wait 我得到了相同的结果.我也不能将实际请求包装在另一个返回 Cypress.Promise 或类似功能的函数中,该函数只会将问题推高一个堆栈帧.

In a cypress test, I need to validate an action by calling an external API. The API call will always return results (from some prior run), so I can't simply call once and validate the result. I need to retry some number of times until I find a match for the current run with an overall timeout/failure. The amount of time necessary to get a current result varies greatly; I can't really just put a crazy long wait before this call.
See comments in snippet below; as soon as I try a request in a loop it's never called. I got the same result using cy.wait. Nor can I wrap the actual request in another function that returns Cypress.Promise or similar, that just pushes the problem up one stack frame.

Cypress.Commands.add("verifyExternalAction", (someComparisonValue) => { 

    const options = {
      "url": some_url,
      "auth": { "bearer": some_apikey },
      "headers": { "Accept": "application/json" }
    };

    //// This works fine; we hit the assertion inside then.
    cy.request(options).then((resp) => {
      assert.isTrue(resp.something > someComparisonValue);
    });

    //// We never enter then.
    let retry = 0;
    let foundMatch = false;
    while ((retry < 1) && (!foundMatch)) {
      cy.wait(10000);
      retry++;
      cy.request(options).then((resp) => {
        if (resp.something > someComparisonValue) {
          foundMatch = true;
        }
      });
    }
    assert.isTrue(foundMatch);

});

推荐答案

  1. 您不能在cy命令之外混合同步( while 循环; assert.isTrue ...)和异步工作(cy命令).阅读 cypress的介绍#Chains-of-命令
  2. 您的第一个请求将声明 resp.something 值,如果失败,则整个命令将失败,因此不再重试.
  3. 您正在执行异步工作,因此无法 await cypress命令(无论如何您都没有这样做),因此您需要递归,而不是迭代.换句话说,你不能使用 while 循环.
  1. You can't mix sync (while loop; assert.isTrue outside the cy commands...) and async work (cy commands). Read introduction to cypress #Chains-of-Commands
  2. Your first request is asserting the resp.something value and if it fails the whole command fails, thus no more retries.
  3. You're doing async work and you can't await cypress commands (which you weren't doing, anyway) thus you need recursion, not iteration. In other words, you can't use a while loop.

喜欢的东西应该可以工作:

Something likes this should work:

Cypress.Commands.add("verifyExternalAction", (someComparisonValue) => {

    const options = {
        "url": some_url,
        "auth": { "bearer": some_apikey },
        "headers": { "Accept": "application/json" }
    };

    let retries = -1;

    function makeRequest () {
        retries++;
        return cy.request(options)
            .then( resp => {
                try {
                    expect( resp.body ).to.be.gt( someComparisonValue );
                } catch ( err ) {

                    if ( retries > 5 ) throw new Error(`retried too many times (${--retries})`)
                    return makeRequest();
                }
                return resp;
            });
    }

    return makeRequest();
});

如果您不希望赛普拉斯在重试期间记录所有失败的期望,请不要使用抛出的 expect / assert ,并进行定期比较(并且可能进行比较)仅在 .then 回调的末尾断言,链接到最后一个 makeRequest()调用).

If you don't want cypress to log all the failed expectations during retries, don't use expect/assert which throws, and do regular comparison (and possibly assert only at the end in a .then callback chained to the last makeRequest() call).

这篇关于赛普拉斯请求重试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆