You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

k6如何在默认函数外打开文件?CSV图片上传施压遇阻求助

解决k6中CSV批量上传图片的施压问题

方案1:Init阶段预加载所有文件内容

在init阶段一次性读取CSV和所有图片的二进制内容,存储到共享数组中,VU阶段直接从数组取数据上传。注意:若单张图片体积大、总数量多,可能引发内存溢出,适合单文件较小的场景。

import http from 'k6/http';
import { SharedArray } from 'k6/data';
import { check } from 'k6';

// Init阶段读取CSV与所有图片内容
const imageData = new SharedArray('image dataset', function () {
  const csvData = open('./image_list.csv').split('\n').slice(1); // 跳过表头
  const result = [];
  for (const line of csvData) {
    if (!line.trim()) continue;
    const [filename, filesize, filepath, filehash] = line.split(',');
    // 读取文件二进制内容
    const fileContent = open(filepath, 'b');
    result.push({ filename, fileContent, filehash });
  }
  return result;
});

export const options = {
  vus: 10,
  duration: '30s',
};

export default function () {
  // 随机选取预加载的图片数据
  const item = imageData[Math.floor(Math.random() * imageData.length)];
  
  // 构造上传表单
  const formData = {
    file: http.file(item.fileContent, item.filename),
    filehash: item.filehash,
  };
  
  // 发送上传请求
  const res = http.post('https://your-upload-api.com/upload', formData);
  
  check(res, {
    '上传成功': (r) => r.status === 200,
  });
}

方案2:预编码图片为Base64存入CSV

提前将图片转为Base64编码并追加到CSV新列中,init阶段读取Base64字符串,VU阶段解码后上传。这种方式能降低init阶段的内存占用压力。

前置步骤:

  1. 用脚本批量将图片转为Base64,更新CSV新增base64_content列
  2. 确保CSV中每行包含filename,filesize,filepath,filehash,base64_content字段
import http from 'k6/http';
import { SharedArray } from 'k6/data';
import { check } from 'k6';

const imageData = new SharedArray('image dataset', function () {
  const csvData = open('./image_list_with_base64.csv').split('\n').slice(1);
  const result = [];
  for (const line of csvData) {
    if (!line.trim()) continue;
    const [filename, filesize, filepath, filehash, base64Content] = line.split(',');
    result.push({ filename, base64Content, filehash });
  }
  return result;
});

export const options = {
  vus: 10,
  duration: '30s',
};

export default function () {
  const item = imageData[Math.floor(Math.random() * imageData.length)];
  // 解码Base64为二进制内容
  const fileContent = atob(item.base64Content);
  
  const formData = {
    file: http.file(fileContent, item.filename),
    filehash: item.filehash,
  };
  
  const res = http.post('https://your-upload-api.com/upload', formData);
  
  check(res, {
    '上传成功': (r) => r.status === 200,
  });
}

方案3:自定义编译k6扩展(xk6-file)

使用xk6-file扩展突破VU阶段不能打开文件的限制,需要自行编译带该扩展的k6版本。

编译步骤:

  1. 安装xk6工具:go install go.k6.io/xk6/cmd/xk6@latest
  2. 编译带xk6-file的k6:xk6 build --with github.com/avitalique/xk6-file@latest
  3. 使用编译后的k6执行测试脚本
import http from 'k6/http';
import { SharedArray } from 'k6/data';
import { check } from 'k6';
import { open } from 'k6/x/file'; // 引入扩展的文件读取方法

const imagePaths = new SharedArray('image paths', function () {
  const csvData = open('./image_list.csv').split('\n').slice(1);
  const result = [];
  for (const line of csvData) {
    if (!line.trim()) continue;
    const [filename, filesize, filepath, filehash] = line.split(',');
    result.push({ filename, filepath, filehash });
  }
  return result;
});

export const options = {
  vus: 10,
  duration: '30s',
};

export default function () {
  const item = imagePaths[Math.floor(Math.random() * imagePaths.length)];
  // VU阶段直接打开文件读取内容
  const fileContent = open(item.filepath, 'b');
  
  const formData = {
    file: http.file(fileContent, item.filename),
    filehash: item.filehash,
  };
  
  const res = http.post('https://your-upload-api.com/upload', formData);
  
  check(res, {
    '上传成功': (r) => r.status === 200,
  });
}

方案4:分批次分布式测试

若5000张图片总内存占用过高,可将CSV拆分为多个小文件(如每个1000行),启动多个k6实例分别加载不同的CSV分片,同时运行施压。这种方式避免单实例内存过载,适合大规模测试场景。

内容的提问来源于stack exchange,提问作者pkhauzhal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:49:50