【问题标题】:Postman / Newman retry in case of failure邮递员/纽曼在失败的情况下重试
【发布时间】:2017-09-15 16:33:53
【问题描述】:

在 Newman 中,我想测试以确保响应代码正确、响应时间合理且响应值正确。

在某些情况下,由于网络中断或其他一些系统条件,某些请求可能会以超时或错误值结束,如果同一请求在几秒钟后处理,这些将解决。

在这种情况下,我想重试同一个请求 x 次,请求之间有 Y 次超时。

如果重试后迭代通过,我希望 Newman 退出代码为 0(成功运行)。

【问题讨论】:

    标签: postman newman


    【解决方案1】:

    您可以像这样设置请求工作流:

    使用请求创建一个集合,然后:

    在预请求选项卡中,您可以实现一个计数器:

    // Counter for number of requests
    var counter = environment.counter ? _.parseInt(environment.counter) + 1 : 1;
    postman.setEnvironmentVariable("counter", counter);
    

    您的测试选项卡如下所示:

    const code = (responseCode.code === 200);
    
    if (code === 200 && environment.counter < X) {
        // Stop execution
        tests["Status code is 200"] = code;
        postman.setNextRequest();
    }
    else {
        // retry the same request
        postman.setNextRequest("Name of this request");
    }
    

    可以使用 newman CLI 配置请求本身的超时:

    newman run myCollection.json --timeout-request Y
    

    【讨论】:

      【解决方案2】:

      几个小时后,我以这样的功能结束:

      function retryOnFailure(successCode, numberOfRetrys) {
          var key = request.name + '_counter';
          var execCounter = postman.getEnvironmentVariable(key) || 1;
      
          var sleepDuration = 1000;
          var waitUntilTime = new Date().getTime() + sleepDuration;
          if (responseCode.code !== successCode && execCounter <= numberOfRetrys) {
              while (new Date().getTime() < waitUntilTime) {
                  // Do Nothing -> Wait
              }
              console.log('Retrying: ' + request.name + '\nGot: ' + responseCode.code + ' Expected: ' + successCode + '\nWaited: ' + sleepDuration / 1000 + 'sec  \nRetry Number: ' + execCounter + ' of ' + numberOfRetrys);
              execCounter++;
              postman.setEnvironmentVariable(key, execCounter);
              postman.setNextRequest(request.name);
          }
      }
      

      用法:

      retryOnFailure(404, 4);
      

      【讨论】:

      • 是的,可重用函数可能是这里更好的解决方案。使用邮递员/纽曼获得一些优雅的重试逻辑是一项艰巨的工作。我希望尽快实现可重用的全局脚本。
      • 我们将把这个脚本放在哪里,它在我们邮递员收藏的test script 部分?
      • 您可以通过 pm.globals.set() 将其放在 postman 环境变量中,并在每次需要该功能时对其执行 eval()
      【解决方案3】:

      这是相同的可重用函数

      postmanFunctions.common.retryOnFailure(predicate,retryCount,waitbetweenRetrySec,ReroutetorequestifNeeded ,postmanAssertions);
      
      • 谓词函数决定成败
      • 断言函数具有所有邮递员断言
      • 如果重新路由为空,则在重试尝试后,断言将被执行。
      • 具有重试次数和等待时间的灵活轮询(如果谓词不再通过 轮询/重排)
      • 有一个 maxflow 计数器(env var),它限制了流跳转的数量 避免无限循环

      将以下函数存储在 Globals 或 env 中:

      () => {
      var sleep = (sleepDuration) => {
          var startTime = new Date().getTime();
          while (new Date().getTime() - startTime < sleepDuration) {}
      }
      var sleepByAsyncDelayTime = () => {
          var sleepDuration = postman.getEnvironmentVariable('asyncDelayTime') || 0;
          sleep(sleepDuration);
      }
      var retryOnFailure = (predicate, numberOfRetrys, sleepDuration, reRouteRequestName, postmanAssertions) => {
          var retryCountPerReq_key = request.name + '_retry_count';
          var retryCountPerReq = pm.environment.get(retryCountPerReq_key) || 0;
          var reflowCountPerReq_key = request.name + '_reflow_count';
          var reflowCountPerReq = pm.environment.get(reflowCountPerReq_key) || 0;
          var totalReflowCount_key = 'totalReflowCount';
          var totalReflowCount = pm.environment.get(totalReflowCount_key) || 0;
          var maxReflowCounter = postman.getEnvironmentVariable('maxReflowCounter') || 0;
          var maxReflowCounterPerReq = postman.getEnvironmentVariable('maxReflowCounterPerReq') || 0;
      
          function clearAndExit() {
              pm.environment.unset(retryCountPerReq_key);
              pm.environment.unset(reflowCountPerReq_key);
              postmanAssertions();
          }
      
          function retry() {
              sleep(sleepDuration);
              pm.environment.set(retryCountPerReq_key, ++retryCountPerReq);
              postman.setNextRequest(request.name);
          }
      
          function reFlow() {
              if (totalReflowCount < maxReflowCounter && reflowCountPerReq < maxReflowCounterPerReq) {
                  pm.environment.unset(retryCountPerReq_key);
                  pm.environment.set(totalReflowCount_key, ++totalReflowCount);
                  pm.environment.set(reflowCountPerReq_key, ++reflowCountPerReq);
                  postman.setNextRequest(reRouteRequestName);
              } else clearAndExit();
          }
          if (predicate()) clearAndExit();
          else if (retryCountPerReq < numberOfRetrys) retry();
          else if (reRouteRequestName != '') reFlow();
          else clearAndExit();
      }
      return {
          common: {
              sleepByAsyncDelayTime,
              sleep,
              retryOnFailure
          }
      };
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-08
        • 2020-01-21
        • 2018-03-09
        • 2017-06-14
        • 2018-09-08
        • 2021-09-27
        • 2020-09-24
        • 1970-01-01
        相关资源
        最近更新 更多