【问题标题】:Cypress request with retry带有重试的赛普拉斯请求
【发布时间】:2019-01-07 17:31:49
【问题描述】:

在 cypress 测试中,我需要通过调用外部 API 来验证操作。 API 调用将始终返回结果(来自先前的运行),因此我不能简单地调用一次并验证结果。我需要重试几次,直到找到与当前运行匹配且总体超时/失败的匹配项。获得当前结果所需的时间差异很大;在这个电话之前,我真的不能等待很长时间。
见下面 sn-p 中的 cmets;一旦我在循环中尝试一个请求,它就永远不会被调用。我使用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);

});

【问题讨论】:

    标签: cypress


    【解决方案1】:
    1. 您不能混合使用同步(while 循环;assert.isTrue 在 cy 命令之外...)和异步工作(cy 命令)。阅读introduction to cypress #Chains-of-Commands
    2. 您的第一个请求是断言 resp.something 值,如果失败,则整个命令将失败,因此不再重试。
    3. 你正在做异步工作,你不能 await cypress 命令(反正你没有这样做)因此你需要 recursion,而不是 iteration .换句话说,你不能使用 while 循环。

    这样的东西应该可以工作:

    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() 调用)。

    【讨论】:

    • 很好的答案。谢谢!
    • 这会将then 的使用与随后的cy.request 混合使用,这将失败并显示如下内容:cy.then() failed because you are mixing up async and sync code. In your callback function you invoked 1 or more cy commands but then returned a synchronous value. Cypress commands are asynchronous and it doesn't make sense to queue cy commands and yet return a synchronous value. You likely forgot to properly chain the cy commands using another cy.then().
    猜你喜欢
    • 1970-01-01
    • 2022-11-02
    • 2021-11-11
    • 2020-08-23
    • 1970-01-01
    • 2021-01-02
    • 2021-10-14
    • 2022-07-22
    • 1970-01-01
    相关资源
    最近更新 更多