【问题标题】:remove ids generated during the tests删除测试期间生成的 id
【发布时间】:2020-03-06 18:57:01
【问题描述】:

对于vu 阶段的负载测试,我生成了许多具有唯一ID 的对象,并将它们放入数据库中。我想在teardown阶段删除它们,以免污染数据库。

当保持这样的状态时

let ids = [];
export function setup() {
    ids.push('put in setup id');
}

export default function () {
    ids.push('put in vu id');
}

export function teardown() {
    ids.push('put in teardown id');
    console.log('Resources: ' + ids);
}

它不起作用,因为数组总是包含我放入teardown 阶段的数据。

由于众所周知的Cannot extend Go slice 问题,在阶段之间传递数据也不起作用,但即使这样,您也无法将数据从vu 阶段传递到teardown,因为它总是从@987654328 获取数据@舞台。

剩下的唯一解决方案是要么使用console log,要么只使用简单的 id 预设并在测试中使用它们。还有其他方法吗?

【问题讨论】:

    标签: javascript k6


    【解决方案1】:

    setup()teardown() 和 VU 的 default 函数在完全不同的 JavaScript 运行时中执行。对于分布式执行,它们可以在完全不同的机器上执行。因此,您不能只拥有一个可以从任何地方访问的全局 ids 变量。

    这个限制是你应该从setup() 返回任何你关心的数据的原因 - k6 会复制它并将它作为参数传递给default 函数(这样你就可以使用你设置的任何资源up)和teardown()(这样你就可以清理它们了)。

    您的示例必须看起来像这样:

    
    export function setup() {
        let ids = [];
        ids.push('put in setup id');
        return ids;
    }
    
    export default function (ids) {
        // you cannot push to ids here
        console.log('Resources: ' + ids);
    }
    
    export function teardown(ids) {
        console.log('Resources: ' + ids);
    }
    

    您可以在https://k6.io/docs/using-k6/test-life-cycle找到更多信息

    【讨论】:

    • 所以基本上我必须将 ID 生成与 vu 阶段分离?
    • 是的,这可能是最简单和最干净的选择
    【解决方案2】:

    为了扩展 @na-- 的答案,我建议使用 Redis 和 Webdis 管理 ID 的外部解决方法。

    其实很简单,如果你不介意运行一个额外的进程,并且不应该对性能有很大的影响:

    1. 启动一个 Webdis/Redis 容器: docker run --rm -it -p 127.0.0.1:7379:7379 nicolas/webdis

    2. script.js:

    import http from 'k6/http';
    
    const url = "http://127.0.0.1:7379/"
    
    export function setup() {
        const ids = [1, 2, 3];
        for (let id of ids) {
            http.post(url, `LPUSH/ids/${id}`);
        }
    }
    
    export default function () {
        const id = Math.floor(Math.random() * 10);
        http.post(url, `LPUSH/ids/${id}`);
    }
    
    export function teardown() {
        let res = http.get(`${url}LRANGE/ids/0/-1`);
        let ids = JSON.parse(res.body)['LRANGE'];
        for (let id of ids) {
            console.log(id);
        }
        // cleanup
        http.post(url, 'DEL/ids');
    }
    
    1. 运行 5 次迭代: k6 run -i 5 script.js

    示例输出:

    INFO[0000] 7
    INFO[0000] 2
    INFO[0000] 2
    INFO[0000] 6
    INFO[0000] 5
    INFO[0000] 3
    INFO[0000] 2
    INFO[0000] 1
    

    此解决方案的一个缺点是它会扭曲整体测试结果,因为额外的 HTTP 请求与测试本身无关。可能有一种方法可以用标签排除这些,否则这将是一个很好的功能请求。 :)

    使用 Node.js Redis 客户端来避免 HTTP 请求可能是一种替代方法,但这些库通常不是“可浏览的”,因此它们可能无法在 k6 中运行。

    【讨论】:

    • k6 不能以简单的方式解决这个问题真是太疯狂了。
    • @basickarl 那是因为这不是一个可以解决所有用例的简单问题。正如 na-- 解释的那样,导出的函数在不同的 JS 运行时中运行,并且可能在分布式执行中的不同进程或不同机器中运行。它需要一些集中的进程来同步状态,Redis 是一种方法。虽然随着 k6 扩展的引入,使用 github.com/MStoykov/xk6-counter 在单个 k6 进程中保持全局计数器是可能的,所以我想可以为共享全局状态做类似的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 2014-03-08
    • 1970-01-01
    • 2021-08-07
    • 2013-10-23
    • 1970-01-01
    • 2021-07-27
    相关资源
    最近更新 更多