Introduction
In our previous post, we explored Query Parameters in REST Assured, learning how to add dynamic key-value pairs to API requests. Now, we’ll dive into Path Parameters, which allow you to work with dynamic segments in API URLs. This guide is designed for beginners and experienced developers, offering clear explanations and practical examples to help you use path parameters effectively in REST Assured.
Key Point: Path parameters enable you to create flexible and reusable tests by dynamically replacing parts of the URL, making it easier to test specific resources in RESTful APIs.
What Are Path Parameters?
Path Parameters are placeholders in the URL path of an API request, used to identify specific resources. For example, in the URL https://api.example.com/users/1
, the 1
is a path parameter representing a user ID. Unlike query parameters, which are appended after a question mark, path parameters are embedded directly in the URL path.
In REST Assured, you can define path parameters using the pathParam()
method or by embedding them directly in the URL with placeholders. This makes your tests dynamic and reusable for different resource IDs or values.
Adding Path Parameters in REST Assured
REST Assured provides multiple ways to handle path parameters, making it easy to test APIs with dynamic endpoints. Let’s explore these approaches using the public API https://jsonplaceholder.typicode.com
.
Option 1: Using pathParam()
The pathParam()
method allows you to define a placeholder in the URL and assign it a value dynamically.
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class PathParamTest {
@Test
public void testSinglePathParam() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
given()
.pathParam("userId", 1)
.when()
.get("/users/{userId}")
.then()
.statusCode(200)
.body("id", equalTo(1))
.body("name", notNullValue());
}
}
Explanation:
pathParam("userId", 1)
: Defines a path parameter nameduserId
with the value1
.get("/users/{userId}")
: Uses{userId}
as a placeholder in the URL, which is replaced by the value1
, resulting in/users/1
.then()
: Validates the response, ensuring the status code is 200 and the user’sid
matches the path parameter.
Important: The placeholder name in the URL (e.g.,{userId}
) must match the name used inpathParam()
. Mismatches will cause errors.
Option 2: Using Multiple Path Parameters
For APIs with multiple path parameters, use multiple pathParam()
calls or the pathParams()
method for conciseness.
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class MultiplePathParamTest {
@Test
public void testMultiplePathParams() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
given()
.pathParams("userId", 1, "postId", 1)
.when()
.get("/users/{userId}/posts/{postId}")
.then()
.statusCode(200)
.body("userId", equalTo(1))
.body("id", equalTo(1));
}
}
Explanation:
pathParams("userId", 1, "postId", 1)
: Defines two path parameters, resulting in the URL/users/1/posts/1
.- The test fetches a specific post for a user and validates its
userId
andid
.
Option 3: Using Request Specification
To reuse path parameters across tests, include them in a Request Specification. This is useful when testing multiple endpoints with similar URL patterns.
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class PathParamSpecTest {
private static RequestSpecification requestSpec;
@BeforeAll
public static void setup() {
requestSpec = new RequestSpecBuilder()
.setBaseUri("https://jsonplaceholder.typicode.com")
.addHeader("Content-Type", "application/json")
.build();
}
@Test
public void testUserWithSpec() {
given()
.spec(requestSpec)
.pathParam("userId", 1)
.when()
.get("/users/{userId}")
.then()
.statusCode(200)
.body("id", equalTo(1));
}
@Test
public void testPostWithSpec() {
given()
.spec(requestSpec)
.pathParam("postId", 1)
.when()
.get("/posts/{postId}")
.then()
.statusCode(200)
.body("id", equalTo(1));
}
}
Explanation:
RequestSpecBuilder
: Defines a reusable specification with the base URI and header.pathParam()
: Adds path parameters specific to each test.spec(requestSpec)
: Applies the common configuration, while path parameters are added dynamically.
Pro Tip: Combine Request Specifications with path parameters to maintain consistent settings across tests while allowing flexibility for dynamic URLs.
Step 1: Handling Dynamic Path Parameters
Path parameters are often dynamic, varying based on test data. You can pass different values to the same endpoint to test multiple resources.
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class DynamicPathParamTest {
@Test
public void testDynamicPathParam() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
int userId = 2; // Dynamic value
given()
.pathParam("userId", userId)
.when()
.get("/users/{userId}")
.then()
.statusCode(200)
.body("id", equalTo(userId));
}
}
Explanation:
userId
: A variable that can be changed to test different users.- The test dynamically constructs the URL (e.g.,
/users/2
) and validates the response.
Step 2: Combining Path and Query Parameters
You can combine path and query parameters for more complex requests.
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class CombinedParamsTest {
@Test
public void testPathAndQueryParams() {
RestAssured.baseURI = "https://jsonplaceholder.typicode.com";
given()
.pathParam("userId", 1)
.queryParam("id", 1)
.when()
.get("/users/{userId}/posts")
.then()
.statusCode(200)
.body("[0].id", equalTo(1));
}
}
Explanation:
pathParam("userId", 1)
: Sets the user ID in the URL path.queryParam("id", 1)
: Adds a query parameter to filter posts.- The resulting URL is
/users/1/posts?id=1
.
Step 3: Verify Setup with pom.xml
Ensure your pom.xml
includes the necessary dependencies for REST Assured and JUnit:
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 correct path parameter names and URL structure in the API’s documentation.
- Use Descriptive Placeholders: Name placeholders clearly (e.g.,
{userId}
) to improve readability. - Test with Public APIs: Practice with
jsonplaceholder.typicode.com
for safe experimentation. - Enable Logging: Use
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails()
to debug URL issues.
Troubleshooting Tip: If the API returns a 404 error, ensure the path parameter values and URL structure are correct. Mismatched placeholders or invalid IDs may cause failures.
What’s Next?
In the next post, we’ll cover Request Body (JSON, XML), exploring how to send data in API requests using REST Assured. Stay tuned for more hands-on examples!