There is an export api can export all users as an excel file,
I want to save it and use it for import api, how can I do?
Please give me some suggestion~
Hello Jessie! Can you be more specific about what you want to do? Do you mind giving an example workflow across the overall k6 test life cycle?
An early guess:
-
In the
init
stage, export the users as a CSV. -
(Still in
init
), combinepapaparse
with aSharedArray
to turn the CSV file into an array that your VUs can reference. -
In the default function, run your VU code and use the CSV-turned-array data as you wish.
If you want to write the API response to a file, you may need to use an extension.
This post explains why, and links some viable extensions: Write data to file - #2 by imiric
I hope that puts you on the right track! If not, at least that’s two for the process of elimination .
Really appreciate for your reply!
I’m trying to use k6 for single-interface performance testing, so exporting and importing users are two separate scripts.
Sending a get request when exporting users, and get response like this:
1.Can I get the attachment and save it ?
2.If I save response with file.writeString(path, res.body), how can I use it for importing?
Importing user like this
Hello Jessie! Thanks for the context. Unfortunately, I’m still not totally clear about what you want to do, but I can make some guesses. I’ve done some experimenting with k6 so I have a bit of a better idea of capabilities.
Please note two things:
- All the examples below assume that you understand the stages of the Test life cycle.
- I’m not saying these are the best solutions! Just ideas. I only tested the solution in option a.
Option a: 1 data file, many VUs
Maybe this is the workflow you want:
- Make a GET request to get all items.
- Link each virtual user to an item.
- Run a test script where each VU does operations for a specific item.
As far as I can tell, a viable option here is the following:
- Before the test runs, grab your CSV file.
- In the init context, make a
SharedArray
from the file. - In the init context, set your number of VUs to be the length of the array
- In VU code, use the VU number to link that VU’s operations to a specific item in the array.
I’ve adapted this solution from the Data Parametrization and Execution context variable docs.
For example, you can test this out on the k6 API server. I use JSON, but it would be very similar with CSV.
The only problem is that you need to get your file first. A simple way is to make a curl call before the test runs:
If save the following test snippet as sharedArray.js
, then these two commands should work in sequence:
curl "https://test-api.k6.io/public/crocodiles" > crocs.json;
k6 run sharedArray.js
import { SharedArray } from "k6/data";
import http from "k6/http";
import exec from "k6/execution";
const data = new SharedArray("crocs", function () {
return JSON.parse(open("crocs.json"));
});
export const options = {
vus: data.length,
duration: "30s",
};
export default function () {
//make VU count 0-based
const vu = exec.vu.idInTest - 1;
http.get(`https://test-api.k6.io/public/crocodiles/${vu}`);
}
For what I can tell, it’s going to be hard to write the CSV to a file and link an item to a unique VU all inside the k6 script, because:
init
code can’t make http requests currentlysetUp
code can make requests, but it runs after init code- The number of VUs is defined in
init
code, so you can’t use data derived from operations insetUp
If you don’t need to link a VU to a specific item, you have some flexibility:
Option b: Share data without linking VUs to specific items
For this you could:
- GET the CSV in setup code, return it as an array.
- Run the VU script however you want, passing the returned data from setup.
export function setup() {
// 2. setup code
}
export default function (data) {
// 3. VU code
}
Depending on the length of the CSV, this could be less performant than using a SharedArray
Option c: Every VU exports the CSV
If you want every VU to make the GET request, you could do something like this:
import http from 'k6/http';
export default function () {
const response = http.get('https://test-api.k6.io/public/crocodiles/');
const crocs = JSON.parse(response.body);
crocs.forEach((croc) => {
http.get(`https://test-api.k6.io/public/crocodiles/${croc['id']}/`);
});
}
Let me know if one of these options works. Good luck!
Thanks for your solution, I really understand what you are trying to say. Unfortunately, I still can’t find a solution to my problem.
To test a single interface without being affected by other interfaces, I run only one script containing a single interface at a time.
Due to the relevance between businesses, I want to save the attachment (Content-Type:application/octet-stream, Content-Disposition:attachment; filename=xxxx.xxx; filename*=UTF-8’xxxx.xxx) in the response of the export interface, and reuse this file for next script.
The problem is that I don’t know how to save this attachment and how to save file stream in the response.
Oh, well, sorry for the unnecessary procedures. I think I understand better now.
This thread might help:
Unfortunately, xk6-file only allow writing string.
If I write this uint8array to a file, It can’t be an valid zip file.
Add method in file.go of GitHub - avitalique/xk6-file: k6 extension for writing files
Then use it like this: