Postman 邮递员-如何循环请求,直到我得到特定的响应?

Postman 邮递员-如何循环请求,直到我得到特定的响应?,postman,web-api-testing,postman-collection-runner,Postman,Web Api Testing,Postman Collection Runner,我正在与Postman测试API,我遇到了一个问题: 我的请求属于某种中间件,因此我要么收到完整的1000多行JSON,要么收到PENDING状态和空结果数组: { “元”:{ “状态”:“待定”, “缺少连接器计数”:0, “xxx_类型”:“国际” }, “结果”:[] }在阅读您的问题时,我正在寻找同一问题的答案,并想到了可能的解决方案。 使用邮递员工作流程,在每次未收到所需响应时重新运行您的请求。不管怎样,这就是我要尝试的 postman.setNextRequest("request

我正在与Postman测试API,我遇到了一个问题: 我的请求属于某种中间件,因此我要么收到完整的1000多行JSON,要么收到
PENDING
状态和空结果数组:

{
“元”:{
“状态”:“待定”,
“缺少连接器计数”:0,
“xxx_类型”:“国际”
},
“结果”:[]

}
在阅读您的问题时,我正在寻找同一问题的答案,并想到了可能的解决方案。 使用邮递员工作流程,在每次未收到所需响应时重新运行您的请求。不管怎样,这就是我要尝试的

postman.setNextRequest("request_name");
试试这个:

var body=JSON.parse(responseBody);
if(body.meta.status!==“SUCCESS”&&body.results.length==0){
邮递员。setNextRequest(“此请求与标题相同”);
}否则{
邮递员:setNextRequest(“下一个请求”标题);
/*您也可以尝试postman.setNextRequest(null);*/

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

  • 使用Postman collection runner或newman并设置每一步延迟。此延迟插入到集合中的每一步之间。这里有两个挑战:除非您将延迟设置为请求持续时间永远不会超过的值,否则它可能是脆弱的,并且,通常只有少数步骤需要延迟,并且您正在增加总测试运行时间,为公共生成服务器创建过多的生成时间,从而延迟其他挂起的生成
  • 使用
    https://postman-echo.com/delay/10
    其中最后一个URI元素是等待的秒数。这是简单而简洁的,可以在长时间运行的请求之后作为单个步骤插入。挑战在于,如果请求持续时间变化很大,可能会因为等待时间不够长而导致错误失败
  • 使用
    postman.setNextRequest(request.name)重试同一步骤,直到成功。这里的挑战是,Postman将以最快的速度执行请求,这可能会对您的服务造成DDoS攻击,使您被列入黑名单(并导致错误失败),并且如果在公共构建服务器上运行,会占用大量CPU,从而减慢其他构建的速度
  • 在预请求脚本中使用setTimeout()。我在这种方法中看到的唯一缺点是,如果您有几个步骤需要这种逻辑,那么最终会得到一些需要保持同步的剪切粘贴代码
  • 注意:它们有一些细微的变化,比如在收藏、收藏文件夹、步骤等上设置它们

    我喜欢选项4,因为它为我的大多数案例提供了合适的粒度级别。请注意,这似乎是邮递员脚本中“睡眠”的唯一方式。现在不支持标准javascript睡眠方法,如带有async和await的Promise,并且使用沙盒的lodash
    \uz。delay(function(){},delay,args[…])
    不会在请求前脚本上保持脚本执行

    在Postman standalone app 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);
    
    console.log('Waiting to job completion in step“'+request.name+'”);
    //从环境变量构造我们的请求URL
    var url=request['url'].replace({{host}}),postman.getEnvironmentVariable('host');
    var-retryDelay=1000;
    var-retryLimit=3;
    函数isProcessingComplete(retryCount){
    发送请求(url,函数(错误,响应){
    如果(错误){
    //嗯。我应该继续尝试还是失败?现在就记录下来。
    控制台日志(err);
    }否则{
    //我还可以检查response.json().results.length>0,但是
    //将忽略可能有效的空结果的成功
    if(response.json().meta.status!=“成功”){
    如果(retryCount
    您可以在同一步骤中进行标准测试

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

    我找到了Christian Baumann的一个方法,该方法允许我找到一个合适的方法来解决完全相同的问题,即首先轮询某个操作的状态,并且只有在该操作完成后才运行实际测试

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

    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("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...
    }
    
    const maxNumberOfTries=3;//您的最大尝试次数
    常数sleepBetweenTries=5000;//你的两次尝试间隔
    如果(!pm.environment.get(“尝试”)){
    pm.environment.set(“尝试”,1);
    }
    const jsonData=pm.response.json();
    if((jsonData.meta.status!=“SUCCESS”&&jsonData.results.length==0)&&(pm.environment.get(“trys”)
    我喜欢这种方法的地方是call postman.setNextRequest(request.name)没有任何硬编码的请求名称。我看到这种方法的缺点是,如果将此类请求作为集合的一部分运行,它将重复多次,这可能会导致日志中出现不必要的噪音

    我考虑的另一种选择是编写一个预请求脚本,它将进行轮询(by)和旋转,直到状态达到某种程度的完成。这种方法的缺点是需要为相同的逻辑编写更多的代码。

    相关:。出色的解释