在 K6 中测试如何使用 async 编写代码,在执行另一个请求之前等待响应

Test in K6 use async how wrote code waiting for a response before executing another request

提问人:Dariusz Andryskowski 提问时间:11/11/2023 最后编辑:Dariusz Andryskowski 更新时间:11/13/2023 访问量:54

问:

我正在寻找解决方案,但我经历了各种配置,但未能获得令人满意的结果。

我需要做什么?队列获取 4 个 ID 并逐个传递执行,等到队列上的任务结束或超过执行任务的时间,然后获取下一个。

因此,我需要获取 4 个 id 的列表,这些 id 在队列中执行。首先,一个 ID 添加请求 URL,需要等待执行完成并返回响应。如果执行时间超过 7 分钟,这应该会返回 http 代码 400。 最初,我希望整个测试最多持续 30 分钟。

这是我的代码的样子:

import http from 'k6/http';
import { expect } from 'https://jslib.k6.io/k6chaijs/4.3.4.3/index.js';
import { check, sleep } from 'k6';


let idsParam = `
    1
    2
    3
    4
    5
    6
`;

let params = {
  timeout: '780s',

};


export const optons = {
  vus: 1,
  timeout: '480s',
  duration: '10m',
};

let data = idsParam.trim().split('\n').slice(1).map(row => row.trim());

export default async function () {

    for (let id of data) {
        let url = `https://pagequeue.com/task/{id}`;

        console.info(`Request for ID ${id} `);
        let res = await http.asyncRequest('GET', url, null, params);
        
            // Wait until the request is processed
        if (res.status != 200) {
          console.warn(`Request for ID ${id} is still processing with status ${res.status}...`);
          console.warn(res);
          sleep(60);
        } 


        // Check if the response status is 200 or 400, mark as failure otherwise
        check(res, {
        'Status is 200': (r) => r.status === 200,
        });

        // Check if the response status is 200 or 400, mark as failure otherwise
        check(res, {
        'Status is 400': (r) => r.status === 400,
        });
        
        expect(res.status).to.equal(200);
    }
    
}

对于队列中长达 1 分钟的任务,它效果很好,但对于需要 3 分钟以上的请求,不要等待,而是使用 id 接收另一个请求。尽管增加了等待来自 http 请求的异步响应的超时时间,但它对我不起作用,只有测试结束,尽管将时间设置为 20 分钟。它在 10 分 30 秒后结束。在队列端,服务已准备好返回 http 代码响应。 我在 jmeter 上检查了这一点,它在那里运行良好。目前我需要使用我的 k6 来编写测试。谁能建议它应该是什么样子?

JavaScript 异步 测试 async-await k6

评论

0赞 trincot 11/12/2023
为什么当你得到 400 时,你输出请求仍在处理中?你打算用 60 岁的睡眠达到什么目的?这似乎没用。当你的代码清楚地期望返回 400 时,你为什么会有......to.equal(200)
0赞 Dariusz Andryskowski 11/12/2023
谢谢你的提问。我写了我需要的代码。
0赞 trincot 11/12/2023
回答你的问题很好,但问题还没有澄清,这应该发生在你原来的帖子中。

答:

0赞 Dariusz Andryskowski 11/12/2023 #1

我为我的情况找到了解决方案。也许它会对某人有用。我写了什么:

import http from 'k6/http';
import { check, sleep } from 'k6';
import { describe } from 'https://jslib.k6.io/k6chaijs/4.3.4.3/index.js';

let params = {
    timeout: '420s'
};

let data = [1, 2, 3, 4, 5, 6];

export let options = {
    vus: 1, 
};


function sendRequest(id) {
    
    return new Promise((resolve, reject) => {

        let url = `https://pagequeue.com/task/${id}`;
        let res = http.get(url, params);

        let checkRes = check(res, {
            'Status is 200': (r) => r.status === 200,
        });

        if (!checkRes) {
            reject(`Request for ID ${id} failed with status ${res.status}`);
            console.log('Response time was ' + String(res.timings.duration) + ' ms');
        } else {
            console.log(`Request for ID ${id} completed with status ${res.status}`);
            console.log('Response time was ' + String(res.timings.duration) + ' ms');

            resolve();
        }
    });
}

async function runQueue() {

    for (const [index, id] of data.entries()) {
        
        try {
            await sendRequest(id);
            continue;
        } catch (error) {
            console.warn(error);
        }
    }
}

export default function() {

    describe('[Queue service] Run task from list by id', () => {
        runQueue();
    });
}

在顶部,我添加了放置超时的位置,我们等待完成请求的时间。超时的默认值为 60 秒。params