Bird
Raised Fist0
JUnittesting~15 mins

Single assertion per test debate in JUnit - Build an Automation Script

Choose your learning style10 modes available
Verify user login and welcome message
Preconditions (2)
Step 1: Open the login page
Step 2: Enter 'testuser' in the username field
Step 3: Enter 'Password123!' in the password field
Step 4: Click the login button
Step 5: Verify the URL changes to the dashboard page
Step 6: Verify the welcome message 'Welcome, testuser!' is displayed
✅ Expected Result: User is logged in successfully, dashboard page is shown, and welcome message is displayed
Automation Requirements - JUnit 5
Assertions Needed:
Verify current URL is dashboard URL after login
Verify welcome message text matches expected
Best Practices:
Use one assertion per test method to isolate failures
Use descriptive test method names
Use setup methods for preconditions
Use explicit waits if needed for page load
Use Page Object Model for page interactions
Automated Solution
JUnit
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

public class LoginTests {
    private WebDriver driver;
    private WebDriverWait wait;
    private final String baseUrl = "https://example.com/login";
    private final String dashboardUrl = "https://example.com/dashboard";

    @BeforeEach
    public void setUp() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        driver.get(baseUrl);
    }

    @Test
    public void testLoginRedirectsToDashboard() {
        driver.findElement(By.id("username")).sendKeys("testuser");
        driver.findElement(By.id("password")).sendKeys("Password123!");
        driver.findElement(By.id("login-button")).click();

        wait.until(ExpectedConditions.urlToBe(dashboardUrl));

        String currentUrl = driver.getCurrentUrl();
        assertEquals(dashboardUrl, currentUrl, "URL should be dashboard after login");

        driver.quit();
    }

    @Test
    public void testWelcomeMessageDisplayed() {
        driver.findElement(By.id("username")).sendKeys("testuser");
        driver.findElement(By.id("password")).sendKeys("Password123!");
        driver.findElement(By.id("login-button")).click();

        wait.until(ExpectedConditions.urlToBe(dashboardUrl));

        WebElement welcomeMessage = wait.until(
            ExpectedConditions.visibilityOfElementLocated(By.id("welcome-msg")));

        assertEquals("Welcome, testuser!", welcomeMessage.getText(), "Welcome message should greet the user");

        driver.quit();
    }
}

The code uses JUnit 5 and Selenium WebDriver to automate the login test.

We have two test methods, each with a single assertion to keep tests focused and failures clear:

  • testLoginRedirectsToDashboard checks that after login, the URL changes to the dashboard URL.
  • testWelcomeMessageDisplayed checks that the welcome message text is correct after login.

Both tests share setup steps to open the login page and enter credentials.

Explicit waits ensure the page loads and elements appear before assertions.

Using one assertion per test helps isolate which feature failed if a test breaks.

Driver is closed after each test to avoid resource leaks.

Common Mistakes - 4 Pitfalls
Putting multiple assertions in one test method
Not waiting for page load or elements before asserting
Hardcoding URLs or messages directly in multiple places
Not closing the WebDriver after tests
Bonus Challenge

Now add data-driven testing with 3 different username and password combinations to verify login success or failure.

Show Hint

Practice

(1/5)
1. Why is it recommended to have only one assertion per test in JUnit testing?
easy
A. It makes tests simpler and easier to understand.
B. It reduces the total number of tests needed.
C. It allows multiple failures to be reported at once.
D. It speeds up the execution time of tests significantly.

Solution

  1. Step 1: Understand test simplicity

    Having one assertion per test keeps the test focused and easy to read.
  2. Step 2: Understand failure clarity

    When a test fails, it is clear exactly what went wrong because only one condition is checked.
  3. Final Answer:

    It makes tests simpler and easier to understand. -> Option A
  4. Quick Check:

    One assertion = simple test [OK]
Hint: One assertion means clear, simple tests [OK]
Common Mistakes:
  • Thinking multiple assertions speed up tests
  • Believing one test must cover many cases
  • Confusing test simplicity with fewer tests
2. Which of the following JUnit test method structures follows the single assertion per test best practice?
easy
A. @Test void testSum() { assertTrue(sum(2, 3) > 0); assertTrue(sum(3, 4) > 0); }
B. @Test void testSum() { assertEquals(5, sum(2, 3)); assertEquals(7, sum(3, 4)); }
C. @Test void testSum() { int result = sum(2, 3); assertTrue(result > 0); assertEquals(5, result); }
D. @Test void testSum() { assertEquals(5, sum(2, 3)); } @Test void testSumNegative() { assertEquals(-1, sum(-2, 1)); }

Solution

  1. Step 1: Review each test method

    @Test void testSum() { assertEquals(5, sum(2, 3)); } @Test void testSumNegative() { assertEquals(-1, sum(-2, 1)); } splits checks into two separate test methods, each with one assertion.
  2. Step 2: Compare with other options

    Options B, C, and D have multiple assertions in one test method, which breaks the single assertion rule.
  3. Final Answer:

    Separate tests with one assertion each. -> Option D
  4. Quick Check:

    One assertion per test method = @Test void testSum() { assertEquals(5, sum(2, 3)); } @Test void testSumNegative() { assertEquals(-1, sum(-2, 1)); } [OK]
Hint: One test, one assertion, split tests if needed [OK]
Common Mistakes:
  • Putting multiple assertions in one test method
  • Not splitting tests logically
  • Confusing assertTrue with assertEquals usage
3. Given the following JUnit test, what will be the test result if sum(2, 3) returns 6?
@Test
void testSum() {
  assertEquals(5, sum(2, 3));
}
medium
A. Test passes successfully.
B. Test fails with an assertion error.
C. Test throws a compilation error.
D. Test is ignored during execution.

Solution

  1. Step 1: Understand assertEquals behavior

    assertEquals expects the first and second values to be equal for the test to pass.
  2. Step 2: Compare expected and actual values

    Expected is 5, actual is 6, so they do not match, causing failure.
  3. Final Answer:

    Test fails with an assertion error. -> Option B
  4. Quick Check:

    Expected != actual -> fail [OK]
Hint: Mismatch in assertEquals causes failure [OK]
Common Mistakes:
  • Assuming test passes if values differ
  • Confusing compilation errors with assertion failures
  • Thinking test is skipped without @Ignore
4. Identify the problem in this JUnit test method regarding the single assertion per test principle:
@Test
void testUser() {
  assertEquals("John", user.getName());
  assertEquals(30, user.getAge());
}
medium
A. The test method is missing the @Before annotation.
B. The assertEquals methods are used incorrectly with wrong parameter order.
C. The test method has multiple assertions, making it harder to find failures.
D. The test method should use assertTrue instead of assertEquals.

Solution

  1. Step 1: Check number of assertions

    The test has two assertEquals calls, violating the single assertion rule.
  2. Step 2: Understand impact of multiple assertions

    Multiple assertions make it unclear which check failed if the test fails.
  3. Final Answer:

    The test method has multiple assertions, making it harder to find failures. -> Option C
  4. Quick Check:

    Multiple assertions = unclear failure [OK]
Hint: One assertion per test avoids confusion [OK]
Common Mistakes:
  • Thinking multiple assertions are always better
  • Confusing @Before with test assertions
  • Misusing assertEquals parameter order
5. You have a method calculateDiscount that returns a discount percentage based on user type and purchase amount. How should you write JUnit tests following the single assertion per test debate best practice?
hard
A. Write separate test methods for each user type and purchase amount combination, each with one assertion.
B. Write tests only for the most common user type and skip others.
C. Write one test method that asserts the discount is never negative, ignoring user types.
D. Write one test method with multiple assertions checking all user types and amounts.

Solution

  1. Step 1: Understand test coverage needs

    Each user type and purchase amount combination can behave differently and needs separate testing.
  2. Step 2: Apply single assertion per test

    Writing separate test methods with one assertion each keeps tests clear and failures easy to locate.
  3. Final Answer:

    Write separate test methods for each user type and purchase amount combination, each with one assertion. -> Option A
  4. Quick Check:

    Separate focused tests = Write separate test methods for each user type and purchase amount combination, each with one assertion. [OK]
Hint: Split tests by case, one assertion each [OK]
Common Mistakes:
  • Combining many assertions in one test
  • Ignoring edge cases for coverage
  • Skipping tests for less common inputs
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard