Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11A custom framework listener is a callback that responds to test or framework lifecycle events. In TestNG, a listener can log when a test starts, collect failure diagnostics, process results when a run finishes, or pass outcomes to another system. You can attach it to a test class or register it for a broader build scope.
What a custom framework listener does
A listener lets your code observe events without placing the same logging or reporting logic inside every test. Max Saperstone notes that “Most testing frameworks (JUnit, TestNG, Cucumber, Robot…) have what they call a ‘listener.’” The exact events and registration mechanism depend on the framework; the examples below focus on TestNG.
A useful way to evaluate a listener is to ask what lifecycle events it covers, how widely it is registered, whether it preserves the framework’s default behavior, and what happens if its callback fails. TestNG callbacks are part of test execution, so keep their work focused and account for any external integration they call.
TestNG listener lifecycle methods
For common test-level callbacks, extend TestNG’s TestListenerAdapter and override the methods that match your need.
#1 Best Overall
| Method | When it is useful | Typical work |
|---|---|---|
onTestStart |
When an individual test begins | Log the test start or check a feature flag before proceeding. |
onTestFailure |
When an individual test fails | Collect diagnostics or report the failure. |
onFinish |
When the test run finishes | Process passed and failed tests together, such as for a final report. |
Call the superclass implementation where appropriate so inherited behavior is not accidentally lost. Keep per-test actions in per-test callbacks and run-wide processing in onFinish; this makes the scope and timing of each action clear.
Create a custom TestNG listener
A basic listener can override only the callbacks it needs. The following example logs starts and failures; it does not add a reporting integration or change test outcomes.
import org.testng.TestListenerAdapter;
import org.testng.ITestResult;
public class LoggingListener extends TestListenerAdapter {
@Override
public void onTestStart(ITestResult result) {
super.onTestStart(result);
System.out.println("Starting: " + result.getName());
}
@Override
public void onTestFailure(ITestResult result) {
super.onTestFailure(result);
System.err.println("Failed: " + result.getName());
}
}
For a feature-flag check, a listener can mark a test skipped and throw a skip exception when the feature is disabled. This is different from ordinary logging: it intentionally affects execution, so use it only when skipping that test is the desired result.
Register the listener at the scope you need
Choose registration based on whether the listener should apply to one class or a wider test run. TestNG supports class-level annotation and build-level registration; a shared base test class can also provide inherited registration.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
One test class
Annotate the test class with @Listeners:
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners(LoggingListener.class)
public class AccountTests {
@Test
public void opensAccount() {
// test body
}
}
Shared base class
If several test classes inherit from a common base class, put the registration there to share it among those subclasses. This keeps registration limited to the tests using that base rather than making it an automatic build-wide choice.
Build-wide or runner configuration
For suite-wide setup, register the listener through Maven Surefire or Failsafe properties, Gradle’s options.listeners, or Ant’s TestNG command-line arguments. The exact configuration syntax depends on the plugin, task, and project setup, so use the configuration entry point for the runner actually executing your tests.
Send results to another system
A listener can forward outcomes to a test-management system. One documented example records test results and calls Zephyr methods to mark executions passed or failed. The callback can therefore bridge TestNG’s result lifecycle and an external reporting workflow.
Plan for integration failures as well as successful reporting: the listener runs during the test lifecycle, and an external call can affect that run. Keep result mapping explicit, decide how a reporting error should affect the build, and avoid adding slow or fragile work to callbacks that run for every test unless that trade-off is intentional.
Listeners outside test reporting
The term also applies beyond test frameworks, but behavior is framework-specific. Oxygen XML’s custom-framework extension bundle uses an activation-state listener to add or remove editor listeners as a framework becomes active or inactive. Flight PHP documents synchronous event listeners: callbacks run in registration order to completion, and returning false stops later callbacks. These examples illustrate why a listener should be understood through its framework’s lifecycle and callback contract, rather than by name alone.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

