代码之家  ›  专栏  ›  技术社区  ›  dudeNumber4

带重试的Cypress请求

  •  1
  • dudeNumber4  · 技术社区  · 6 年前

    在Cypress测试中,我需要通过调用外部API来验证操作。API调用将始终返回结果(来自以前的一些运行),因此我不能简单地调用一次并验证结果。我需要重试几次,直到找到与当前运行匹配的总体超时/失败为止。获得当前结果所需的时间差异很大;我不能在这通电话之前花很长时间等待。
    请参阅下面代码片段中的注释;只要我在循环中尝试一个请求,它就不会被调用。我用同样的方法得到了同样的结果 cy.wait . 我也不能将实际请求包装在另一个返回 Cypress.Promise 或者类似的,只会把问题推到一个堆栈帧上。

    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 回复  |  直到 6 年前
        1
  •  1
  •   dwelle    6 年前
    1. 你不能混合同步( while 循环; assert.isTrue 在cy命令…)和异步工作(cy命令)之外。读 introduction to cypress #Chains-of-Commands
    2. 您的第一个请求是断言 resp.something 值,如果失败,则整个命令将失败,因此不再重试。
    3. 你在做异步工作,你不能 await 柏树命令(不管怎么说,你没有这样做),因此你需要 递归 不是 迭代 . 换句话说,你不能使用 一 虽然 循环。

    像这样的东西应该管用:

    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();
    });
    

    如果您不希望Cypress在重试期间记录所有失败的预期,请不要使用 expect / assert 它抛出并进行定期比较(并且可能只在 .then 回调链接到最后一个 makeRequest() 打电话)