邮递员 - 在获得特定回复之前如何循环请求?

时间:2017-04-08 14:07:25

标签: postman web-api-testing postman-collection-runner

我正在使用Postman测试API,我遇到了一个问题: 我的请求是中间件,所以要么我收到一个完整的1000多行JSON,要么我收到PENDING状态和空数组结果:

{
  "meta": {
    "status": "PENDING",
    "missing_connectors_count": 0,
    "xxx_type": "INTERNATIONAL"
  },
  "results": []
}

问题是,如何在Postman中循环此请求,直到我获得状态SUCCESS和结果数组> 0? 当我一个接一个地手动发送这些请求时,没关系,但是当我通过Collection Runner运行它们时,“PENDING”会弄乱一切。

4 个答案:

答案 0 :(得分:3)

试试这个:

var body = JSON.parse(responseBody);

if (body.meta.status !== "SUCCESS" && body.results.length === 0){
  postman.setNextRequest("This_same_request_title");
} else {
  postman.setNextRequest("Next_request_title"); 
  /* you can also try postman.setNextRequest(null); */  
}

答案 1 :(得分:2)

在等待服务准备就绪或轮询长时间运行的作业结果时,我会看到4个基本选项:

  1. 使用Postman集合运行器或newman并设置每步延迟。此延迟插入集合中的每个步骤之间。这里有两个挑战:它可能是脆弱的,除非你将延迟设置为一个值,请求持续时间永远不会超过,并且,通常,只有少量步骤需要延迟,并且你增加了总测试运行时间,从而产生了过多的构建时间公共构建服务器延迟其他待定构建。
  2. 使用https://postman-echo.com/delay/10 ,其中最后一个URI元素是等待的秒数。这简单而简洁,可以在长时间运行请求后作为单个步骤插入。挑战在于,如果请求持续时间变化很大,您可能会因为没有等待足够长时间而遭遇错误的失败。
  3. 使用postman.setNextRequest(request.name);重试同样的步骤。这里面临的挑战是Postman将尽可能快地执行请求,这可能会使您的服务失败,让您黑名单(并导致错误的失败),并且如果在公共构建服务器上运行则会咀嚼大量CPU - 减慢其他生成。
  4. 在预请求脚本中使用setTimeout()。我在这种方法中看到的唯一缺点是,如果你有几个步骤需要这个逻辑,你最终得到一些削减&粘贴您需要保持同步的代码
  5. 注意:这些有一些细微的变化 - 比如在集合,集合文件夹,步骤等上设置它们。

    我喜欢选项4,因为它为我的大多数情况提供了正确的粒度级别。请注意,这似乎是“睡眠”的唯一方法。在邮差脚本中。现在不支持像带有异步和等待的Promise这样的标准javascript睡眠方法,并且使用沙盒的lodash _.delay(function() {}, delay, args[...])不会在预请求脚本上保留脚本执行。

    在Postman独立应用v6.0.10中,将步骤预请求脚本设置为:

    console.log('Waiting for job completion in step "' + request.name + '"');
    
    // Construct our request URL from environment variables
    var url = request['url'].replace('{{host}}', postman.getEnvironmentVariable('host'));
    var retryDelay = 1000;
    var retryLimit = 3;
    
    function isProcessingComplete(retryCount) {
        pm.sendRequest(url, function (err, response) {
            if(err) {
                // hmmm. Should I keep trying or fail this run? Just log it for now.
                console.log(err);
            } else {
                // I could also check for response.json().results.length > 0, but that
                // would omit SUCCESS with empty results which may be valid
                if(response.json().meta.status !== 'SUCCESS') {
                    if (retryCount < retryLimit) {
                        console.log('Job is still PENDING. Retrying in ' + retryDelay + 'ms');
                        setTimeout(function() {
                            isProcessingComplete(++retryCount);
                        }, retryDelay);
                    } else {
                        console.log('Retry limit reached, giving up.');
                        postman.setNextRequest(null);
                    }
                }
            }
        });
    }
    
    isProcessingComplete(1);
    

    您可以在同一步骤中进行标准测试。

    注意:标准警告适用于使retryLimit变大。

答案 2 :(得分:2)

我找到了克里斯蒂安·鲍曼(Christian Baumann)的awesome post about retrying a failed request,这使我能够找到一种适当的方法来解决完全相同的问题,即首先轮询某些操作的状态,并且仅在完成实际测试后才能进行。

如果我是你,我最终要得到的代码是:

const maxNumberOfTries = 3; // your max number of tries
const sleepBetweenTries = 5000; // your interval between attempts

if (!pm.environment.get("tries")) {
    pm.environment.set("tries", 1);
}

const jsonData = pm.response.json();

if ((jsonData.meta.status !== "SUCCESS" && jsonData.results.length === 0) && (pm.environment.get("collection_tries") < maxNumberOfTries)) {
     const tries = parseInt(pm.environment.get("tries"), 10);
     pm.environment.set("tries", tries + 1);
     setTimeout(function() {}, sleepBetweenTries);
     postman.setNextRequest(request.name);
 } else {
     pm.environment.unset("tries");

     // your actual tests go here...
}

我喜欢这种方法的原因是调用 postman.setNextRequest(request.name)没有任何硬编码的请求名称。我看到的这种方法的缺点是,如果您将此类请求作为集合的一部分来运行,它将被重复多次,这可能会在日志中产生不必要的噪音。

我正在考虑的替代方法是编写一个 Pre-request Script ,该脚本将进行轮询(通过sending a request)并旋转直到状态完成为止。这种方法的缺点是,对于相同的逻辑,需要更多的代码。

答案 3 :(得分:1)

当我正在阅读你的问题时,我正在寻找同一个问题的答案并想到了一个可能的解决方案。   每次您没有得到您正在寻找的回复时,请使用邮递员工作流程重新运行您的请求。无论如何,这就是我要尝试的。

postman.setNextRequest("request_name");

https://www.getpostman.com/docs/workflows