Building a Load Testing Framework using K6.io — Handling Multi-part requests with form-data (Part 6)
In Part-05 of this series we saw how to handle Batch Requests using Grafana k6.
And more often than that we may need to upload files/such as pdf or JSON files which we saw briefly in Part-02, which requires Multi-part requests. The Key to which is the FormData
The polyfill for k6.
Simple Data Upload
Let's see how a simple data upload request looks like in k6. Following is an example k6 documentation.
import http from 'k6/http';
//important step
const binFile = open('/path/to/file.bin', 'b');
export default function () {
const data = {
field: 'this is a standard form field',
file: http.file(binFile, 'test.bin'),
};
const res = http.post('https://example.com/upload', data);
}
Note:
const binFile = open('/path/to/file.bin', 'b');
This part of code is important for Loading the files into memory from the file system is done using the open() function.
More on which you can find from Part-02 of this series.
Creating Data Upload requests with multi-part
More often we will have complex requirements for uploading data to required destination. For which we would need to skillfully craft a requestBody using FormData and then use multi-part headers to upload such files.
We can start by packaging the file-upload code in a uploadFiles()
so, the current 'file upload' test will look like below:
describe('file upload', () => {
//file upload list
let fileList = ["Invoice-1.pdf", "data.json"]
fileList.forEach((file, index) => {
let fileToBeUploaded = init.getAFile(file)
let fileUploadResponse = uploadFiles(fileToBeUploaded)
expect(fileUploadResponse.status,`Upload file response status ${fileUploadResponse.status}`).to.not.eq(200);
})
})
uploadFile() Function:
In this function 4 things happen:
- Prepares form data for file upload using
FormData
.
1) first way uses directly attaching json with the FormData by specifying the data
and the content_type
:formData.append('attributes', { data: "{"usecase":"test"}", content_type: 'application/json' });
2) we can also directly attach a physical file using FormData:
formData.append("files", http.file(document.file, document.name));
formData.boundary
is defined to set in multi-part request- Measures the time taken for the file upload using
fileUploadTime
metric - Sends a POST request to upload the file and returns the response.
function uploadFiles(document) {
const params = {
timeout: config.requestTimeout
};
let formData = new FormData();
formData.append('attributes', { data: "{\"usecase\":\"test\"}", content_type: 'application/json' });
formData.append("files", http.file(document.file, document.name));
fileUploadStartTime = new Date().getTime();
const uploadFileResponse = http.request('POST', `${baseUrl}/cck/rest/2.0/submissions`, formData.body(), {
headers: {
'Content-Type': 'multipart/form-data; boundary=' + formData.boundary
}
}, params);
fileUploadEndTime = new Date().getTime();
fileUploadTime.add(fileUploadEndTime - fileUploadStartTime);
return uploadFileResponse;
}
Running the code will yield into following result:
Note:
As we are using a dummy file upload endpoint, I have tweaked theexpect()
to yield a false positive by expecting negativeto.not.eq(200)
That was all related to crafting multi-part requests using FormData. You can refer following documentation get more insights:
Good Luck!!
GitHub repo:
https://github.com/far11ven/k6-LoadTestingFramework/tree/main/Part%2006?ref=kushalbhalaik.xyz