k6测试中如何实现异步数据获取及setup阶段ORM等操作?
在k6中实现数据库操作与数据参数化(替代async/await方案)
核心限制说明
k6的运行时基于Go的V8引擎,不原生支持Promise、async/await,也无法直接使用依赖Node.js API或Promise机制的ORM库(比如Sequelize、Prisma)。要实现数据库架构清理/创建、ORM查询这类操作,得换用同步风格的方案。
可行解决方案
1. 使用k6官方数据库扩展(优先推荐)
k6提供了官方的k6/x/sql扩展,支持MySQL、PostgreSQL、SQLite等主流数据库,所有操作都是同步执行,完全适配k6的生命周期方法。
PostgreSQL示例代码:
import sql from 'k6/x/sql'; // 建立数据库连接 const db = sql.open('postgres', 'postgres://user:password@localhost:5432/test_db'); export function setup() { // 清理旧数据 db.exec('TRUNCATE TABLE users RESTART IDENTITY;'); // 插入测试数据 db.exec('INSERT INTO users (name, email) VALUES ($1, $2)', ['Alice', 'alice@test.com']); // 查询数据用于参数化 const userList = sql.query(db, 'SELECT id, email FROM users;'); return { users: userList }; } export default function (testData) { // 从setup返回的参数化数据中随机选取用户 const randomUser = testData.users[Math.floor(Math.random() * testData.users.length)]; console.log(`当前测试用户: ${randomUser.email}`); // 后续可结合k6/http模块发起带参数的请求 } export function teardown() { // 关闭数据库连接 db.close(); }
2. 搭建同步HTTP中间层(适配特定ORM场景)
如果业务必须依赖特定ORM,可单独搭建一个同步HTTP服务作为中间层:
- 在Node.js环境中编写小服务,封装ORM的数据库操作(比如用Prisma执行架构变更、查询)
- k6通过
k6/http模块发送同步HTTP请求到该中间层,间接完成数据库操作
Node.js中间层示例(Express + Prisma):
// 单独运行的中间层服务 const express = require('express'); const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); const app = express(); app.use(express.json()); // 处理k6的setup请求 app.post('/init-db', async (req, res) => { try { await prisma.user.deleteMany(); await prisma.user.create({ data: { name: 'Bob', email: 'bob@test.com' } }); const users = await prisma.user.findMany(); res.json({ success: true, users }); } catch (err) { res.status(500).json({ success: false, error: err.message }); } }); app.listen(3000, () => console.log('中间层服务运行在3000端口'));
k6测试代码:
import http from 'k6/http'; import { check } from 'k6'; export function setup() { const res = http.post('http://localhost:3000/init-db'); check(res, { '数据库初始化成功': (r) => r.json().success }); return res.json().users; } export default function (testData) { const targetUser = testData[Math.floor(Math.random() * testData.length)]; console.log(`使用测试用户: ${targetUser.email}`); }
3. 预生成离线参数化数据
如果数据库操作不需要动态执行,可提前用脚本生成测试数据:
- 用Node.js/Python等支持ORM的环境,提前生成JSON/CSV格式的参数化数据文件
- k6通过
open()函数读取本地文件,直接使用数据
示例:
import { open } from 'k6'; export function setup() { // 读取预生成的测试数据 const rawData = open('./test-users.json'); return JSON.parse(rawData); } export default function (testData) { const selectedUser = testData[Math.floor(Math.random() * testData.length)]; // 基于selectedUser发起测试请求 }
关键注意事项
setup和teardown是单线程执行的,适合做全局数据库初始化、清理操作- 测试函数(
default)是多线程运行的,避免在其中执行数据库写操作(除非有严格的并发控制) - 官方数据库扩展的性能优于HTTP中间层,优先选择官方方案
内容的提问来源于stack exchange,提问作者mleko
相关产品推荐
相关产品推荐

