Answer
Soft Assertions in Cucumber
Why Soft Assertions?
Hard assertions (default) stop the test at the first failure — you miss all other failures in that scenario. Soft assertions collect all failures and report them together at the end.
Gherkin
Scenario: Verify user profile details
Given the user is logged in
When the user opens the profile page
Then the name should be "John Doe"
And the email should be "john@example.com"
And the phone should be "9876543210"
And the role should be "ADMIN"
-- With hard assert: stops at first wrong field
-- With soft assert: checks ALL fields, reports ALL failures at once
Method 1: SoftAssert in Context (Recommended)
Java
// ScenarioContext.java
public class ScenarioContext {
public WebDriver driver;
public SoftAssert softAssert = new SoftAssert(); // one per scenario
}
// Step definitions use ctx.softAssert
public class ProfileSteps {
private final ScenarioContext ctx;
public ProfileSteps(ScenarioContext ctx) { this.ctx = ctx; }
@Then("the name should be {string}")
public void verifyName(String expected) {
String actual = profilePage.getName();
ctx.softAssert.assertEquals(actual, expected, "Name mismatch");
}
@Then("the email should be {string}")
public void verifyEmail(String expected) {
String actual = profilePage.getEmail();
ctx.softAssert.assertEquals(actual, expected, "Email mismatch");
}
@Then("the role should be {string}")
public void verifyRole(String expected) {
String actual = profilePage.getRole();
ctx.softAssert.assertEquals(actual, expected, "Role mismatch");
}
}
// Hooks.java — trigger assertAll after EVERY scenario
public class Hooks {
private final ScenarioContext ctx;
public Hooks(ScenarioContext ctx) { this.ctx = ctx; }
@After(order = 1) // runs before driver quit
public void assertAll() {
ctx.softAssert.assertAll(); // throws if any soft assertion failed
}
@After(order = 0) // runs last
public void tearDown() {
ctx.driver.quit();
}
}
Method 2: Local SoftAssert Per Step
Java
@Then("all product details should be correct")
public void verifyAllProductDetails() {
SoftAssert sa = new SoftAssert();
sa.assertEquals(productPage.getName(), "Laptop Pro", "Name wrong");
sa.assertEquals(productPage.getPrice(), "$999", "Price wrong");
sa.assertTrue(productPage.isInStock(), "Should be in stock");
sa.assertEquals(productPage.getRating(), "4.5/5", "Rating wrong");
sa.assertAll(); // fail here if any assertion above failed
}
Method 3: JUnit 5 SoftAssertions (Assertj)
Java
import org.assertj.core.api.SoftAssertions;
@Then("all dashboard metrics should be correct")
public void verifyDashboard() {
SoftAssertions softly = new SoftAssertions();
softly.assertThat(dashboardPage.getTotalOrders()).isEqualTo(150);
softly.assertThat(dashboardPage.getPendingOrders()).isLessThan(20);
softly.assertThat(dashboardPage.getRevenue()).startsWith("$");
softly.assertAll(); // reports all failures
}
Hook Order for assertAll
Java
// IMPORTANT: order value — HIGHER number runs FIRST in @After
@After(order = 100)
public void runSoftAssertions() {
ctx.softAssert.assertAll(); // must run BEFORE driver.quit()
}
@After(order = 0)
public void closeDriver() {
ctx.driver.quit(); // runs AFTER assertAll
}
If driver.quit() runs before assertAll(), screenshots of failures are impossible.
