About this lesson
REST Assured log().ifValidationFails(): request logging that stays quiet until a check fails
Learn REST AssuredAdvancedLogging
How it works
Calling log() on the request side returns a log specification with several levels: all(), headers(), body() and more. Those print every time the request runs, which turns a suite of a few hundred tests into pages of console noise. ifValidationFails() changes the timing. REST Assured holds on to the request details and only writes them out if one of the checks after then() fails, so a green run prints nothing extra.
When a check does fail, you get the full request first and the error second. In the runtime, a wrong expected name printed the method, the full request URI, then lines for proxy, request params, query params, form params, path params, headers, cookies, multiparts and body. After that came a java.lang.AssertionError beginning with "1 expectation failed." and naming the JSON path, the expected value and the actual one. The error ends the program, so nothing after the chain runs.
The chain can still give you data. extract() after the assertions switches from checking to extracting, and path() returns the value at a path. It only runs once every check has passed. Its return type is generic, so the same call gave a String for name and an Integer for id.
About the assignment
Fetch user 1 with failure-only request logging, check the status and the name, then pull the name out of the same chain and print it.
What you will do
- Start from
given()and calllog().ifValidationFails()before the HTTP method, then usewhen()andget()for/users/1. - After
then(), check status 200 withstatusCode()and thenamefield withbody()and theequalTo()matcher. - Finish the same chain with
extract()andpath()forname, storing the result in a String. - Print it after the label
Validated user:so the console shows that single line.
Common mistakes
Logging on the response side by accident
Placing
log().ifValidationFails()afterthen()logs the response instead of the request. Both are useful, but this lesson asks for the request side, which goes right aftergiven().Expecting to see the request on success
When every check passes, the conditional log prints nothing. Extra lines above your output mean an assertion failed, not that logging is working.
Sending a second request for the value
Re-fetching the user just to read the name doubles the traffic and can read a different state.
extract()at the end of the validated chain uses the response you already checked.
In a real test suite
Most teams want this behaviour everywhere, so they switch it on once: RestAssured.enableLoggingOfRequestAndResponseIfValidationFails() in a JUnit 5 @BeforeAll method logs both sides of any failing request in the whole suite. CI logs stay short, and every red test arrives with the exact request that broke it.
Related lessons
- Response Logging on FailureApplies the same failure-only logging to the response side after
then(). - Extract Single ValuePractises
extract()for getting values out of a validated response. - BDD Style - given/when/thenBuilds the given/when/then chain that this lesson adds logging to.
To try one of these calls on any API endpoint without a task, open the Online Selenium Java Compiler (REST Assured is included).
Starter code
The editor above opens with this code. Fill in the TODO lines, then run and submit it.
import io.restassured.RestAssured;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class Main {
public static void main(String[] args) {
RestAssured.baseURI = "https://testkru.com/api";
// TODO: Turn on request logging that only prints on failure, then GET /users/1
// TODO: Validate status 200 and that "name" equals "John Doe"
// TODO: Extract "name" at the end of the chain
// TODO: Print "Validated user: " + the name
}
}