Bird
Raised Fist0
JUnittesting~15 mins

Failure notification setup in JUnit - Build an Automation Script

Choose your learning style10 modes available
Verify failure notification is sent when a test fails
Preconditions (2)
Step 1: Create a JUnit test class with one passing test and one failing test
Step 2: Run the test suite
Step 3: Observe the failure notification system for messages about the failing test
✅ Expected Result: A notification is sent only for the failing test, containing the test name and failure reason
Automation Requirements - JUnit 5
Assertions Needed:
Verify that the failure notification method is called exactly once for the failing test
Verify the notification contains the correct test name and failure message
Best Practices:
Use JUnit 5 TestWatcher extension to listen for test failures
Use mock objects or spies to verify notification calls
Keep test code clean and readable
Use descriptive test method names
Automated Solution
JUnit
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.TestWatcher;
import org.junit.jupiter.api.extension.ExtensionContext;
import static org.mockito.Mockito.*;
import java.util.Optional;

class NotificationService {
    void sendFailureNotification(String testName, String reason) {
        // Imagine this sends an email or logs the failure
    }
}

class FailureNotificationWatcher implements TestWatcher {
    private final NotificationService notificationService;

    FailureNotificationWatcher(NotificationService notificationService) {
        this.notificationService = notificationService;
    }

    @Override
    public void testFailed(ExtensionContext context, Throwable cause) {
        String testName = context.getDisplayName();
        String reason = cause.getMessage();
        notificationService.sendFailureNotification(testName, reason);
    }

    @Override
    public void testSuccessful(ExtensionContext context) {
        // No notification on success
    }
}

@ExtendWith(FailureNotificationWatcher.class)
public class FailureNotificationTest {

    static NotificationService notificationService = mock(NotificationService.class);

    static FailureNotificationWatcher watcher = new FailureNotificationWatcher(notificationService);

    @Test
    void passingTest() {
        // This test passes
        assert(true);
    }

    @Test
    void failingTest() {
        // This test fails
        throw new RuntimeException("Simulated failure");
    }

    @Test
    void verifyNotificationSent() {
        // Run the failing test manually to trigger notification
        ExtensionContext context = mock(ExtensionContext.class);
        when(context.getDisplayName()).thenReturn("failingTest()");

        RuntimeException failure = new RuntimeException("Simulated failure");

        watcher.testFailed(context, failure);

        verify(notificationService, times(1)).sendFailureNotification("failingTest()", "Simulated failure");
    }
}

The NotificationService class simulates sending failure notifications.

The FailureNotificationWatcher implements JUnit 5's TestWatcher interface to listen for test failures. When a test fails, it calls sendFailureNotification with the test name and failure reason.

The test class FailureNotificationTest uses Mockito to mock NotificationService. It defines a passing test and a failing test. The verifyNotificationSent test manually triggers the failure notification and verifies that the notification method was called exactly once with the correct parameters.

This setup ensures that failure notifications are sent only on test failures and contain the right information.

Common Mistakes - 3 Pitfalls
{'mistake': 'Not using a TestWatcher or listener and trying to send notifications inside test methods', 'why_bad': 'This mixes test logic with notification logic and is not scalable or maintainable.', 'correct_approach': "Use JUnit 5's TestWatcher extension to separate notification logic from test code."}
Hardcoding notification calls without mocking in tests
Not verifying the notification content (test name and failure reason)
Bonus Challenge

Now add data-driven testing with 3 different failing scenarios and verify notifications for each

Show Hint

Practice

(1/5)
1. What is the primary purpose of setting up failure notification in JUnit tests?
easy
A. To get alerts immediately when a test fails
B. To speed up test execution
C. To automatically fix failed tests
D. To skip tests that might fail

Solution

  1. Step 1: Understand failure notification purpose

    Failure notification is designed to alert developers right when a test fails so they can act quickly.
  2. Step 2: Eliminate unrelated options

    Speeding tests, auto-fixing, or skipping tests are not related to failure notifications.
  3. Final Answer:

    To get alerts immediately when a test fails -> Option A
  4. Quick Check:

    Failure notification = Immediate alerts [OK]
Hint: Failure notification means alerts on test failure [OK]
Common Mistakes:
  • Thinking it speeds up tests
  • Assuming it fixes tests automatically
  • Believing it skips tests
2. Which JUnit feature is commonly used to detect test failures and trigger notifications?
easy
A. TestRule
B. TestSuite
C. TestWatcher
D. TestRunner

Solution

  1. Step 1: Identify JUnit classes for failure detection

    TestWatcher is a JUnit rule designed to watch test execution and detect failures.
  2. Step 2: Compare with other options

    TestRule is a general interface, TestSuite groups tests, TestRunner runs tests but does not notify failures.
  3. Final Answer:

    TestWatcher -> Option C
  4. Quick Check:

    Failure detection = TestWatcher [OK]
Hint: TestWatcher watches tests and detects failures [OK]
Common Mistakes:
  • Confusing TestRule interface with TestWatcher
  • Thinking TestSuite handles failure notifications
  • Assuming TestRunner sends alerts
3. Given the following JUnit snippet, what will happen when the test fails?
public class MyTest {
  @Rule
  public TestWatcher watcher = new TestWatcher() {
    @Override
    protected void failed(Throwable e, Description d) {
      System.out.println("Test failed: " + d.getMethodName());
    }
  };

  @Test
  public void testFail() {
    assertEquals(1, 2);
  }
}
medium
A. Sends an email automatically
B. Test passes silently without output
C. Throws a runtime exception and stops tests
D. Prints 'Test failed: testFail' to the console

Solution

  1. Step 1: Understand TestWatcher failed() method

    The failed() method runs when a test fails and prints the method name.
  2. Step 2: Analyze the testFail() method

    assertEquals(1, 2) fails, triggering failed() to print the message.
  3. Final Answer:

    Prints 'Test failed: testFail' to the console -> Option D
  4. Quick Check:

    Failed test triggers failed() print [OK]
Hint: Failed test triggers failed() print message [OK]
Common Mistakes:
  • Thinking test passes silently
  • Expecting automatic email without code
  • Assuming runtime exception stops all tests
4. Identify the error in this JUnit failure notification setup:
public class NotifyTest {
  @Rule
  public TestWatcher watcher = new TestWatcher() {
    @Override
    protected void failed() {
      System.out.println("Failure detected");
    }
  };

  @Test
  public void testExample() {
    fail();
  }
}
medium
A. Missing parameters in failed() method override
B. @Rule annotation is misplaced
C. fail() method is undefined
D. TestWatcher cannot be used with @Rule

Solution

  1. Step 1: Check failed() method signature

    TestWatcher.failed() requires parameters (Throwable, Description) to override correctly.
  2. Step 2: Verify other parts

    @Rule is correctly placed, fail() is a JUnit method, TestWatcher works with @Rule.
  3. Final Answer:

    Missing parameters in failed() method override -> Option A
  4. Quick Check:

    Override failed() with correct parameters [OK]
Hint: Override failed(Throwable, Description) exactly [OK]
Common Mistakes:
  • Omitting parameters in failed() override
  • Misplacing @Rule annotation
  • Confusing fail() method usage
5. You want to send an email alert whenever a JUnit test fails. Which approach correctly integrates this using TestWatcher?
public class EmailAlertTest {
  @Rule
  public TestWatcher watcher = new TestWatcher() {
    @Override
    protected void failed(Throwable e, Description d) {
      // What should go here?
    }
  };

  @Test
  public void testEmail() {
    assertTrue(false);
  }
}
hard
A. Use @After annotation to send email after all tests
B. Call a method to send email inside failed(), passing e and d
C. Throw a new exception inside failed() to trigger email
D. Print stack trace only; email sending is automatic

Solution

  1. Step 1: Understand TestWatcher failed() role

    failed() runs on test failure; it is the right place to trigger email sending.
  2. Step 2: Choose correct action inside failed()

    Calling a method to send email with failure details is correct; throwing exceptions or relying on @After is incorrect.
  3. Final Answer:

    Call a method to send email inside failed(), passing e and d -> Option B
  4. Quick Check:

    Send email in failed() method [OK]
Hint: Send email inside failed() override [OK]
Common Mistakes:
  • Throwing exceptions to send email
  • Using @After for failure alerts
  • Assuming email sends automatically without code
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