k6 v0.57.0 特性详解:功能测试断言库、k6 new 模板化脚手架与 CSV 对象解析
【免费下载链接】k6A modern load testing tool, using Go and JavaScript项目地址: https://gitcode.com/GitHub_Trending/k6/k6
本指南以 k6 官方v0.57.0发布说明为核心,结合当前仓库源码,系统梳理该版本的三项核心能力:面向功能测试的官方 jslibk6-testing、k6 new命令的模板与--project-id支持、以及k6/experimental/csv模块新增的asObjects选项,同时覆盖 TypeScript 自动支持、破坏性变更与维护改进。读者阅读后可以掌握这些新特性的使用方式、适用场景及其底层实现原理,并据此完成升级与迁移。
版本总览
v0.57.0是 k6 向"功能测试 + 负载测试一体化"演进的重要版本,主要变化包括:
- 新增面向功能测试的官方 jslib
k6-testing,提供 Playwright 兼容风格的断言 API。 k6 new命令支持--template(minimal / protocol / browser)与--project-id参数。k6/experimental/csv模块新增asObjects选项,支持将 CSV 解析为 JavaScript 对象。- 正式移除
k6/experimental/browser模块,全面转向已毕业的稳定模块k6/browser。 - TypeScript(
.ts文件)默认自动识别与编译,同时弃用experimental_enhanced兼容模式。 - 大量非公开 API 迁入
internal包,收窄对外扩展面。
破坏性变更(Breaking changes)
1. 移除k6/experimental/browser
自本版本起,k6/experimental/browser模块被正式移除。仍在使用该模块的脚本需迁移至已毕业的稳定模块k6/browser,迁移路径为官方提供的 v0.52 迁移指南。从当前仓库的目录结构可以看到,稳定的浏览器模块实现已完全并入主代码库:internal/js/modules/k6/browser,其使用方式可直接参考 examples/browser 下的大量示例(如page.goto、locator、page.waitForEvent等)。
2. 非公开 API 迁入internal包
基于 k6 公开扩展(xk6)生态的实际使用情况,所有未被公开使用的 API 被移入internal包。这是一个偏机械性的结构调整,可能影响未公开的私有扩展,后续版本还可能继续删除或更新相关 API。这提醒扩展开发者:应只依赖官方文档化、稳定的 API 面。
3. TypeScript 默认支持,experimental_enhanced弃用
现在只要脚本文件使用.ts扩展名,k6 就会自动识别并编译 TypeScript,无需再依赖experimental_enhanced兼容模式(该模式因此被弃用)。从源码实现看,internal/js/compiler/compiler.go 在解析失败后会检查文件名后缀:isTsExtensionFile := strings.HasSuffix(filename, ".ts"),若是.ts文件(或标准输入),则调用StripTypes(src, filename)剥离类型后重新解析,并上报usageParsedTSFilesKey使用量统计;对于 stdin 输入同样支持。虽然experimental_enhanced已弃用,但它仍保留在兼容模式枚举中(见 lib/compatibility_mode_gen.go),保证存量脚本的向后兼容。
新特性一:k6-testing —— 面向功能测试的官方 jslib
k6 团队开发了新的官方 jslibk6-testing,专门用于功能测试。它仍处于积极开发中,API 可能发生破坏性变化,但其行为设计最终会并入 k6 核心,当前开放出来供社区早期反馈。
同步断言:Playwright 兼容的expect
k6-testing暴露一个expect函数,配合一组通用匹配器(matcher)即可完成断言,风格与 Playwright 断言库一致。与 k6 内置check最大的区别在于:当断言失败时,测试会立即失败,并给出包含期望值与实际值的清晰错误信息,而不是像check那样仅记录失败并继续执行。
import { expect } from 'https://jslib.k6.io/k6-testing/0.2.0/index.js'; import http from 'k6/http'; export default function () { const response = http.get('https://test.k6.io'); expect(response.status).toEqual(200); expect(response.body).toBeTruthy(); expect(response.json()).toEqual(JSON.stringify({ message: 'Hello, world!' })); }目前提供的通用匹配器包括toEqual、toBe、toBeTruthy等,更多匹配器(如toBeNull、toBeGreaterThan、toContain等)将持续扩充。
浏览器场景的异步匹配器
针对k6/browser场景,k6-testing还提供了一组异步匹配器,它们会等待直到期望的条件被满足,例如toBeVisible、toBeDisabled、toBeChecked等。典型用法如下:
import { expect } from "https://jslib.k6.io/k6-testing/0.2.0/index.js"; import { browser } from "k6/browser"; export const options = { scenarios: { ui: { executor: "shared-iterations", options: { browser: { type: "chromium", }, }, }, }, }; export default async function () { const page = await browser.newPage(); try { // Navigate to the page await page.goto("https://test.k6.io/my_messages.php"); // Type into the login input field: 'testlogin' const loc = await page.locator('input[name="login"]'); await loc.type("testlogin"); // Assert that the login input field is visible await expect(page.locator('input[name="login"]')).toBeVisible(); // Expecting this to fail as we have typed 'testlogin' into the input instead of 'foo' await expect(page.locator('input[name="login"]')).toHaveValue("foo"); } finally { await page.close(); } }注意场景配置中浏览器场景必须使用shared-iterations执行器并声明browser: { type: "chromium" },这是k6/browser场景的标准配置模式(与 internal/cmd/templates/browser.js 中生成的脚手架一致)。
获取方式
该库目前托管于 jslib CDN,在测试脚本中通过 import 引入即可:
import { expect } from "https://jslib.k6.io/k6-testing/0.2.0/index.js";新特性二:k6 new命令 —— 模板化脚手架与项目 ID
k6 new命令在本版本被重新设计,用于更友好地搭建 k6 测试脚本。其命令行定义见 internal/cmd/new.go,主要参数如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
[file] | script.js | 生成的脚本文件名(最多一个位置参数) |
-f, --force | false | 覆盖已存在的文件 |
--template | minimal | 模板类型:minimal、protocol、browser,也可以是自定义模板文件的相对/绝对路径 |
--project-id | 空 | 为测试指定 Grafana Cloud 项目 ID,自动写入cloud.projectID配置 |
基本用法
# 使用默认 minimal 模板生成 script.js $ k6 new # 指定文件名 $ k6 new test.js # 覆盖已存在文件 $ k6 new -f test.js # 使用 protocol 模板 $ k6 new --template protocol # 生成带指定 Grafana Cloud 项目 ID 的云端就绪脚本 $ k6 new --project-id 12345三种内置模板
模板由 Go 内嵌资源提供(见 internal/cmd/templates/templates.go 的//go:embed指令),支持{{ .ScriptName }}与{{ .ProjectID }}两个占位变量:
- minimal(minimal.js):最基本的 HTTP 脚本,固定 10 VUs 运行 30s,对
https://quickpizza.grafana.com发起请求并做状态码检查。 - protocol(protocol.js):协议级压测模板,包含
stages阶梯式负载、thresholds阈值(如http_req_duration: ["p(95)<500", "p(99)<1000"])、setup阶段健康检查,以及带 JSON 请求体与鉴权头的 POST 调用,适合接口协议压测。 - browser(browser.js):浏览器端 E2E 模板,使用
k6/browser打开页面、断言标题、点击按钮并截图,覆盖ui场景配置。
当指定--project-id时,三个模板都会在options中注入cloud: { projectID: <id>, name: "<scriptName>" }配置,实现 Grafana Cloud 测试的即开即用。
自定义模板
--template除了三种内置类型,还支持传入模板文件路径(只要包含路径分隔符即按文件路径处理,见templates.go的isFilePath判断)。此时 k6 会读取该文件作为 Gotext/template模板渲染,渲染成功后才创建目标脚本文件,因此模板语法错误会提前暴露而不会产生半成品文件。
新特性三:k6/experimental/csv的asObjects选项
k6/experimental/csv模块的解析操作新增asObjects选项,可将 CSV 数据解析为 JavaScript 对象而非默认的字符串数组。
使用方式
import http from 'k6/http'; import csv from 'k6/experimental/csv'; const csvData = csv.parse('data.csv', { asObjects: true });对于如下 CSV 文件:
name,age,city John,30,New York Jane,25,Los Angeles解析结果为:
[ { name: 'John', age: '30', city: 'New York' }, { name: 'Jane', age: '25', city: 'Los Angeles' }, ]规则要点:
- 表头行的列名成为对象键,对应列的值成为对象值;
- 如果没有表头行,或存在会改动解析起始点的选项,将抛出错误。
源码层面的实现细节
该模块实现位于 internal/js/modules/k6/experimental/csv/reader.go 与 internal/js/modules/k6/experimental/csv/module.go:
- 选项结构:
options结构体包含Delimiter(默认,)、SkipFirstLine、FromLine、ToLine、AsObjects(null.Bool类型,默认false)。选项解析在newParserOptionsFrom中完成,其中delimiter必须为单个字符,fromLine必须小于toLine。 - 表头预读:
NewReaderFrom在构造时若检测到asObjects开启,会先读取第一行作为表头存入columnNames,并累加currentLine计数。 - 行转对象:
Read方法在asObjects开启时返回map[string]string——遍历记录的每一列,以columnNames[i]为键、以对应值为值组装成对象。若表头缺失(columnNames == nil)会返回明确错误;若记录列数与表头列数不一致,同样返回带长度的错误信息。 - 选项互斥校验:
validateOptions明确规定asObjects与skipFirstLine: true互斥,且与fromLine > 0互斥(因为这都会改变解析起始点,破坏"第一行即表头"的假设),违反任一组合都会在构造阶段直接报错。 - 对象共享:
csv.parse底层通过 data 模块的NewSharedArrayFrom把解析结果放进共享数组(共享数组名称由文件路径与全部选项经 SHA-256 哈希生成,见buildSharedArrayName),保证多个 VU 间内存共享、各 VU 可独立迭代读取。 - Parser API:
csv.Parser构造器同样支持asObjects,其Next()方法逐行返回对象({ done, value }),适用于需要流式逐行消费 CSV 的场景。
UX 改进与增强
- 简写选项覆盖场景时发出警告:当
-u/-i/-d等简写选项会覆盖options.scenarios中的对应设置时,k6 会给出警告,帮助用户避免无意中修改场景配置。 - 浏览器数据目录前缀重命名:浏览器模块运行时数据目录前缀由
xk6-browser-data-更名为k6browser-data-,与模块从 xk6 生态并入主仓库的现状保持一致。 filescheme URL 支持:open、k6/experimental/fs.open以及k6/net/grpc.Client#load等文件加载 API 现在支持file://协议形式的 URL 路径,加载本地文件的方式更统一。- 示例切换为 quickpizza:示例脚本从遗留目标切换到
quickpizza.grafana.com(内置模板同样采用该地址,见上文模板内容)。
Bug 修复与维护改进
浏览器模块(重点):本版本修复了使用k6/browserAPI 时可能出现的多类数据竞争问题(涉及多个关联 PR);修复了高负载下点击操作可能引发的空指针解引用(NPD);修复了组件间通用事件处理的内存泄漏;修复了因未释放原始句柄导致的 NPD;测试结束后清理浏览器下载路径残留文件。
其他修复:修复--local-execution运行时因ArchiveURL 未隔离导致的运行问题。
维护与内部改进:将实验性 WebSocket 代码并入 k6 代码库;合并 xk6-webcrypto 扩展代码;移除浏览器模块不再需要的 packaging 目录;modulestest简化实验性 streams 测试;REST API 在输出刷新期间保持运行、刷新完成后才停止;dependabot 由每日改为每周运行并扩展跟踪依赖;更新 golangci-lint 版本及多项直接依赖;为配置文件相关操作补充了测试覆盖。
升级与迁移建议
- 脚本迁移:若脚本仍 import
k6/experimental/browser,需按官方迁移指南改用k6/browser,注意浏览器场景执行器须为shared-iterations。 - TypeScript 用户:
.ts文件已开箱即用,可移除--compatibility-mode=experimental_enhanced相关设置;该兼容模式已弃用但暂未删除,存量配置仍可运行。 - 扩展开发者:
internal包迁移可能导致私有 xk6 扩展编译失败,请评估并改用公开 API;后续版本还可能继续收敛 API 面。 - 新项目脚手架:优先使用
k6 new --template protocol|browser生成贴近生产实践的脚本,配合--project-id一步完成 Grafana Cloud 配置参数化。 - CSV 数据处理:需要按字段名访问数据时启用
asObjects,注意它要求首行为表头,不能与skipFirstLine、fromLine同时使用。
【免费下载链接】k6A modern load testing tool, using Go and JavaScript项目地址: https://gitcode.com/GitHub_Trending/k6/k6
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考