arbisoft brand logo
arbisoft brand logo
Contact Us

API Field Validation Testing in JMeter Using CSV with Valid and Invalid Inputs

Hassan's profile picture
Hassan IkramPosted on
7-8 Min Read Time

In the world of API testing, validating how an endpoint handles both valid and invalid inputs is a fundamental part of testing. But beyond just sending requests, there are challenges in structuring tests, handling edge cases like null values, and especially in generating clean, readable reports that stakeholders can understand.

 

In this blog, I’ll show you a practical way to do field-level validation testing in JMeter using CSV data that has both valid and invalid entries for a specific field. This example is for a single field but can be scaled to multiple fields with minimal changes.

 

I’ll also share some of the challenges I faced while working on this, like making JMeter process data row by row, passing nulls through CSV, and cleaning up multiline responses, and how I solved them to produce a concise, structured file that’s suitable for stakeholder reporting and analysis. 

 

Why Use JMeter for Field Validation Testing?

JMeter isn’t just for performance testing, it is also great for functional API testing when dealing with multiple inputs and reporting needs. While Postman works well for smaller test sets, JMeter scales better and makes data-driven testing and reporting much easier.

 

One of the biggest wins for me was being able to flatten the request-response data and export it in a structured, single-line format, making the results easy to interpret and present to non-technical stakeholders.

 

Scenario Overview

Imagine you’re working with a POST API endpoint, and there's one particular field in the body that has undergone recent changes. This field needs to accept both valid and invalid data, where valid inputs return a 200 OK status code and invalid ones return accordingly.

 

The goal is to automate the validation of this field’s behavior by sending both valid and invalid data and confirming that the API responds appropriately. To make the process scalable, I decided to use a CSV file to store both types of data and run tests on them in bulk.

 

While this article focuses on testing one field, this approach is designed to be easily scalable, you can apply the same methodology to multiple fields by adjusting the CSV file to contain various values for each field and altering the request body accordingly.

 

Setting Up the Test in JMeter

Let’s walk through the setup of the test.

 

1. Add a Thread Group. Set the number of threads(users) similar to the number of rows used in csv file.

2. Include JSR223 PreProcessor in this thread group. The script will be attached below in the challenges section.

3. Add an HTTP request to define your payload and endpoint details.

 

unnamed (4).png

 

4. Add CSV Data Set Config to read the input file to pass it in your payload. A sample is attached here.

 

unnamed (5).png

 

5. Add HTTP Header Manager to add all the token information and cookie details.

6. Add View Results Tree and View Results in Table to evaluate calls during test execution.

7. Add JSR223 PostProcessor to modify results. The script will be given below in the challenges section.
 

Challenges Faced & How I Overcame Them

While the overall approach is straightforward, there were several challenges along the way. Here are the main ones:

 

1. Ensuring JMeter Reads the CSV Top-to-Bottom, Row-by-Row


Challenge: One of the first issues I faced was getting JMeter to read the CSV file sequentially, from top to bottom, for each test case. Without the right configuration, JMeter might loop through the file or pick up data inconsistently.
 

Solution: I configured the CSV Data Set Config with the following settings:
Recycle on EOF: False
Stop thread on EOF: True

 

2. Handling Strings and Null Values


Challenge: The field I was validating could accept either a string or a null, and both needed to be treated as valid. The issue was that when I entered NULL or null in the CSV file, JMeter read it as a string (i.e., "null") instead of interpreting it as an actual null value. This led to incorrect test behavior.


Solution:  I used a JSR223 PostProcessor to check if the field value (read from the CSV) was the string "null" or "NULL", and if so, I programmatically converted it to an actual null. This ensured that the validation logic handled the input correctly in all cases.

 

// Get the value of a JMeter variable named "variable_3"
def variable_3_Value = vars.get("variable_3")

// Check if the value is the string 'NULL' (used as a placeholder in CSV)
// If it is, assign a JSON null line -- otherwise, wrap the value in quotes for a valid JSON string
def variable_3_Json_Line = variable_3_Value == 'NULL'
// Output if value is 'NULL'
 ? '"variable_3": null'                         
// Output of value is an actual string (e.g., "active")
 : "\"variable_3\": \"${variable_3_Value}\""     

// Store the resulting JSON line into a new JMeter variable called "variable_3_Line"
vars.put("variable_3_Line", variable_3_Json_Line)

 

unnamed (6).png

 

CSV-style output that was much easier to read and share with stakeholders, without relying on unreliable third-party tools.

The following scripts cater to both challenges defined in points 3 and 4.

 

import java.io.FileWriter      // For writing to a file
import java.io.PrintWriter     // For formatted file writing
import java.io.File            // For file system handling

// Define the file path where results will be saved
def filePath = "/Users/xyz/Downloads/results.CSV"
def file = new File(filePath)

// If the file does not exist, create it and write the CSV header
if (!file.exists()) {
   file.withWriter { writer ->
       writer.writeLine("Variable,Request Body,Response Code,Response Message,Response Body")
   }
}

// Get the full HTTP request that was sent (headers + body)
def fullRequest = prev.getSamplerData() ?: ""
def requestBody = ""

// Extract the JSON body from the full HTTP request
int startIndex = fullRequest.indexOf("{")
if (startIndex != -1) {
   int open Braces = 0
   for (int i = startIndex; i < fullRequest.length(); i++) {
       char c = fullRequest.charAt(i)
       if (c == '{') openBraces++        // Count opening brace
       else if (c == '}') openBraces--   // Count closing brace

       // When braces are balanced, extract JSON substring
       if (openBraces == 0) {
           requestBody = fullRequest.substring(startIndex, i + 1)
           break
       }
   }
}

// Remove all newlines from the request body to keep CSV clean
requestBody = requestBody.replaceAll("[\\r\\n]+", " ") ?: ""

// Extract the value of "variable_3" from the request JSON
def variable_3 = ""
def variable_3_Matcher = requestBody =~ /"variable_3":\s*(null|"([^"]*)")/
if (variable_3_Matcher.find()) {
   // If value is null, keep "null", else extract the actual string
   variable_3 = variable_3_Matcher.group(1) == "null" ? "null" : variable_3_Matcher.group(2) ?: ""
}

// Get the HTTP response code (e.g., 200, 400)
def responseCode = prev.getResponseCode() ?: ""
// Get the response message (e.g., OK, Bad Request)
def responseMessage = prev.getResponseMessage() ?: ""
// Get the response body, remove newlines for CSV formatting
def responseBody = prev.getResponseDataAsString()?.replaceAll("[\\r\\n]+", " ") ?: ""

// Escape double quotes in request/response for proper CSV formatting
requestBody = requestBody.replaceAll('"', '""')
responseBody = responseBody.replaceAll('"', '""')

// Append a line to the CSV with all the extracted and formatted data
file.withWriterAppend { writer ->
   writer.writeLine("\"${variable_3}\",\"${requestBody}\",\"${responseCode}\",\"${responseMessage}\",\"${responseBody}\"")
}

 

Results in a Clean Format

 

Final Thoughts

Field validation is a critical part of API testing, and using JMeter made it much easier to automate checks for both valid and invalid inputs. It allowed me to test how the API handles different data types and edge cases. With CSV-driven data and JMeter’s flexibility, the setup worked really well—once I got past a few early challenges like dealing with null values and cleaning up the output format.

 

While this example focused on just one field, the same approach can easily scale. By updating the CSV file, tweaking the request body, and modifying the scripts slightly, you can extend this setup to validate multiple fields. It’s a solid, reusable method for testing larger, more complex APIs without reinventing the wheel each time.

...Loading

Explore More

Have Questions? Let's Talk.

We have got the answers to your questions.

Newsletter

Join us to stay connected with the global trends and technologies