Introduction

In our previous post, we explored Serialization and Deserialization in REST Assured, learning how to convert Java objects to JSON and vice versa. Now, we’ll dive into File Upload and Download, essential techniques for testing APIs that handle file operations, such as uploading images or downloading reports. This guide is designed for beginners and experienced developers, providing clear explanations and practical examples to master file handling in REST Assured.

Key Point: REST Assured simplifies file upload and download by providing methods to send files as multipart data and save response content to files, enabling robust API testing.

What are File Upload and Download in API Testing?

File Upload involves sending a file (e.g., image, PDF, or CSV) to an API endpoint, typically using a multipart/form-data request. For example, uploading a profile picture to a user account.

File Download involves retrieving a file from an API, such as downloading a generated report or an image. The response is often a binary stream that needs to be saved or validated.

REST Assured supports these operations with methods like multiPart() for uploads and extract().asByteArray() or extract().asInputStream() for downloads.

Setting Up for File Upload and Download

To test file upload and download, you need:

  • A sample file (e.g., sample.txt or image.jpg) in your project’s src/test/resources directory.
  • An API that supports file operations. Since https://jsonplaceholder.typicode.com doesn’t support file uploads/downloads, we’ll use illustrative examples with placeholder APIs or public APIs like https://reqres.in where applicable.

Ensure your pom.xml includes the necessary dependencies:



    
        io.rest-assured
        rest-assured
        5.1.0
        test
    
    
        org.junit.jupiter
        junit-jupiter-api
        5.8.2
        test
    
    
        org.hamcrest
        hamcrest
        2.2
        test
    


No additional dependencies are required for basic file handling in REST Assured.

File Upload in REST Assured

REST Assured uses the multiPart() method to send files as part of a request, typically a POST request with multipart/form-data.

Example 1: Uploading a Single File

Upload a text file to an API endpoint.

Create a sample file named sample.txt in src/test/resources with content like “This is a test file.”


import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import java.io.File;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class FileUploadTest {

    @Test
    public void testSingleFileUpload() {
        RestAssured.baseURI = "https://api.example.com"; // Replace with a file upload API

        File file = new File("src/test/resources/sample.txt");

        given()
            .multiPart("file", file)
            .formParam("description", "Test file upload")
            .when()
                .post("/upload")
            .then()
                .statusCode(200)
                .body("message", containsString("File uploaded successfully"));
    }
}

Explanation:

  • multiPart("file", file): Attaches the file to the request with the form field name file.
  • formParam("description", "Test file upload"): Adds additional form data if required by the API.
  • post("/upload"): Sends the multipart request to the upload endpoint.
  • Note: Replace https://api.example.com/upload with an actual API endpoint that supports file uploads (e.g., https://reqres.in/api/upload if available).
Important: Ensure the file path is correct and the API expects the correct form field name (e.g., file). Check the API documentation for details.

Example 2: Uploading Multiple Files

Upload multiple files in a single request.

Create another sample file, sample2.txt, in src/test/resources.


import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import java.io.File;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class MultipleFileUploadTest {

    @Test
    public void testMultipleFileUpload() {
        RestAssured.baseURI = "https://api.example.com"; // Replace with a file upload API

        File file1 = new File("src/test/resources/sample.txt");
        File file2 = new File("src/test/resources/sample2.txt");

        given()
            .multiPart("files", file1)
            .multiPart("files", file2)
            .formParam("userId", "123")
            .when()
                .post("/upload/multiple")
            .then()
                .statusCode(200)
                .body("message", containsString("Files uploaded"));
    }
}

Explanation:

  • multiPart("files", file1) and multiPart("files", file2): Attach multiple files under the same form field name files.
  • formParam("userId", "123"): Adds additional metadata if required.

File Download in REST Assured

REST Assured allows you to download files by extracting the response as a byte array or input stream and saving it to a local file.

Example: Downloading a File

Download a file from an API and save it locally.


import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import static io.restassured.RestAssured.*;

public class FileDownloadTest {

    @Test
    public void testFileDownload() throws IOException {
        RestAssured.baseURI = "https://api.example.com"; // Replace with a file download API

        byte[] fileBytes = given()
            .when()
                .get("/download/sample.pdf")
            .then()
                .statusCode(200)
                .extract().asByteArray();

        // Save the file locally
        try (FileOutputStream fos = new FileOutputStream("downloaded_sample.pdf")) {
            fos.write(fileBytes);
        }

        // Validate file size
        assert fileBytes.length > 0;
    }
}

Explanation:

  • extract().asByteArray(): Extracts the response as a byte array for binary content.
  • FileOutputStream: Saves the byte array to a local file (downloaded_sample.pdf).
  • assert fileBytes.length > 0: Verifies the file was downloaded (non-empty).
  • Note: Replace https://api.example.com/download/sample.pdf with a real file download endpoint.
Pro Tip: Use asInputStream() instead of asByteArray() for large files to avoid loading the entire file into memory.

Using Request Specification

Use a Request Specification to centralize common settings for file upload and download tests.


import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.File;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class FileSpecTest {

    private static RequestSpecification requestSpec;

    @BeforeAll
    public static void setup() {
        requestSpec = new RequestSpecBuilder()
            .setBaseUri("https://api.example.com") // Replace with your API
            .addHeader("Authorization", "Bearer token123") // If required
            .build();
    }

    @Test
    public void testFileUploadWithSpec() {
        File file = new File("src/test/resources/sample.txt");

        given()
            .spec(requestSpec)
            .multiPart("file", file)
            .formParam("description", "Test upload")
            .when()
                .post("/upload")
            .then()
                .statusCode(200)
                .body("message", containsString("success"));
    }
}

Explanation:

  • requestSpec: Defines the base URI and an optional authentication header.
  • spec(requestSpec): Applies the specification to the upload request.

Validating Downloaded Files

Validate the content of a downloaded text file.


import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static io.restassured.RestAssured.*;

public class ValidateDownloadTest {

    @Test
    public void testValidateDownloadedFile() throws IOException {
        RestAssured.baseURI = "https://api.example.com"; // Replace with a file download API

        byte[] fileBytes = given()
            .when()
                .get("/download/sample.txt")
            .then()
                .statusCode(200)
                .extract().asByteArray();

        // Save file
        Path tempFile = Files.createTempFile("downloaded", ".txt");
        Files.write(tempFile, fileBytes);

        // Validate content
        String content = Files.readString(tempFile);
        assert content.contains("Expected text");

        // Clean up
        Files.delete(tempFile);
    }
}

Explanation:

  • Files.createTempFile: Creates a temporary file to store the downloaded content.
  • Files.readString: Reads the file content for validation.
  • assert content.contains("Expected text"): Verifies the file’s content.

Step 3: Verify Setup with pom.xml

Ensure your pom.xml includes all required dependencies:



    
        io.rest-assured
        rest-assured
        5.4.0
        test
    
    
        org.junit.jupiter
        junit-jupiter
        5.10.2
        test
    
    
        org.hamcrest
        hamcrest
        2.2
        test
    

Run the tests using mvn test or your IDE’s test runner to confirm the setup.

Tips for Beginners

  • Check API Documentation: Verify the endpoint, form field names, and supported file types for uploads/downloads.
  • Test with Small Files: Start with small text files to simplify validation and debugging.
  • Validate Content: For downloads, check file size or content to ensure correctness.
  • Enable Logging: Use RestAssured.enableLoggingOfRequestAndResponseIfValidationFails() to debug file-related issues.
Troubleshooting Tip: If file uploads fail with a 400 Bad Request, check the form field name and file format. For downloads, ensure the endpoint returns the correct content type and file data.

What’s Next?

In the next post, we’ll cover Error Handling, exploring how to test and handle API errors effectively in REST Assured. Stay tuned for more hands-on examples!