k6脚本调用fs.writeFileSync报TypeError: Value is not an object求助
k6脚本调用fs.writeFileSync报错:TypeError: Value is not an object: undefined
问题场景
用TypeScript编写k6性能测试脚本,执行流程为:
- 执行
yarn webpack编译脚本 - 用
k6 run .\dist\myscript.js运行编译后的文件
调用Node.js的fs.writeFileSync时,无论传递2个参数还是带配置对象的3个参数,都会抛出错误:TypeError: Value is not an object: undefined。
测试脚本
import { sleep, check } from 'k6'; import { Options } from 'k6/options'; import http from 'k6/http'; import { createNodeJson } from './test_data/create_node_json'; import { CreateNode } from './test_data/create_node_json'; import { uuidv4 } from "https://jslib.k6.io/k6-utils/1.4.0/index.js" import { writeFile, writeFileSync } from 'fs'; const url = 'https://test.com/create'; export let options:Options = { vus: 1, duration: '2s' }; export default () => { const json = uuidUpdate(createNodeJson); console.log("JSON used:" + JSON.stringify(json)); const response = http.post(url, JSON.stringify(json), { headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer asdasdasdasdasdasdad', 'Accept': '*/*', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }, }); console.log("Response: " + response.body); check(response, { 'Response status is 201 HTTP': () => response.status === 201 }); sleep(2); console.log("Saving uuid into file..."); // 两种调用方式均报错 // writeFileSync("test.txt", "asdasdasd", { // encoding: "utf8", // flag: "a+", // mode: 0o666 // }); writeFileSync("test.txt", "asdasdasd"); }; function uuidUpdate(json: CreateNode): CreateNode { json.id = uuidv4(); return json; }
报错信息
.... INFO[0000] JSON used:{"id":"7cef4aed-b7da-4587-ba15-0575677ed90c"} source=console INFO[0002] Saving uuid into file... source=console ERRO[0002] TypeError: Value is not an object: undefined running at post_200_create_node_test (webpack://typescript/./src/myscript.ts:55:16(75)) executor=constant-vus scenario=default source=stacktrace ✓ Response status is 201 HTTP
tsconfig配置
{ "compilerOptions": { "target": "es5", "moduleResolution": "node", "module": "commonjs", "noEmit": true, "allowJs": true, "removeComments": false, "strict": true, "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "skipLibCheck": true, "typeRoots": [ "node_modules/@types" ], } }
报错原因
k6基于Go语言实现了独立的JavaScript运行时,完全不支持Node.js的核心模块(包括fs模块)。你在脚本中导入的fs模块在k6运行环境中实际是undefined,调用writeFileSync时自然会抛出类型错误。
解决方案
方案1:用handleSummary钩子写入文件(推荐)
k6提供了handleSummary钩子函数,该函数在测试结束后运行,且执行环境为Node.js,支持文件写入操作。你可以在测试过程中收集需要保存的数据,最后通过该钩子统一写入文件。
修改后的脚本示例:
import { sleep, check } from 'k6'; import { Options } from 'k6/options'; import http from 'k6/http'; import { createNodeJson } from './test_data/create_node_json'; import { CreateNode } from './test_data/create_node_json'; import { uuidv4 } from "https://jslib.k6.io/k6-utils/1.4.0/index.js" const url = 'https://test.com/create'; const savedIds: string[] = []; // 收集需要保存的ID export let options:Options = { vus: 1, duration: '2s' }; export default () => { const json = uuidUpdate(createNodeJson); console.log("JSON used:" + JSON.stringify(json)); const response = http.post(url, JSON.stringify(json), { headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer asdasdasdasdasdasdad', 'Accept': '*/*', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }, }); console.log("Response: " + response.body); const isSuccess = check(response, { 'Response status is 201 HTTP': () => response.status === 201 }); if(isSuccess) { savedIds.push(json.id); // 仅保存成功请求的ID } sleep(2); }; // 测试结束后执行,自动写入文件 export function handleSummary() { return { 'test.txt': savedIds.join('\n'), // 将ID逐行写入test.txt // 可选:保存测试汇总数据到JSON文件 'summary.json': JSON.stringify({ savedIds }, null, 2), }; } function uuidUpdate(json: CreateNode): CreateNode { json.id = uuidv4(); return json; }
运行后,k6会自动在当前目录生成test.txt和summary.json文件。
方案2:通过标准输出重定向保存数据
如果不需要在测试结束后汇总,也可以将需要保存的内容通过console.log输出,然后在运行时将标准输出重定向到文件:
- 修改脚本,给需要保存的内容添加标识前缀:
// 在测试逻辑中添加 console.log(`SAVED_ID: ${json.id}`);
- 运行脚本时过滤并重定向输出:
# Windows系统 k6 run .\dist\myscript.js | findstr "SAVED_ID" > test.txt # Linux/macOS系统 k6 run .\dist\myscript.js | grep "SAVED_ID" > test.txt
这样test.txt中只会包含带有SAVED_ID前缀的内容,提取后即可得到需要的ID列表。
内容的提问来源于stack exchange,提问作者27P
相关产品推荐
相关产品推荐

