Building a Load Testing Framework using K6.io — Handling Multi-part requests with form-data (Part 6)

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.

Building a Load Testing Framework using K6.io — Uploading Files (Part 3)
In Part-02 of this article series, we saw how to add support for managing multiple configs and environments. In this article, we will dive into uploading files which is a key component for very peculiar software applications that involves measuring performance when a bunch of data is uploaded and waiting

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:

Run Result
Note:

As we are using a dummy file upload endpoint, I have tweaked the expect() to yield a false positive by expecting negative to.not.eq(200)

That was all related to crafting multi-part requests using FormData. You can refer following documentation get more insights:

Data Uploads | Grafana k6 documentation
Scripting examples on how to execute a load test that will upload a file to the System Under Test (SUT).

Good Luck!!

GitHub repo:

https://github.com/far11ven/k6-LoadTestingFramework/tree/main/Part%2006?ref=kushalbhalaik.xyz