# How to Create Custom TestEventListeners in GoogleTest: A Complete Implementation Guide

> Learn to create custom TestEventListeners in GoogleTest by extending EmptyTestEventListener and overriding callbacks. Implement custom test event handling for your C++ projects.

- Repository: [Google/googletest](https://github.com/google/googletest)
- Tags: how-to-guide
- Published: 2026-08-29

---

**You create custom TestEventListeners in GoogleTest by inheriting from `EmptyTestEventListener`, overriding lifecycle callback methods such as `OnTestStart` and `OnTestEnd`, and registering the instance via `UnitTest::GetInstance()->listeners()->Append()` before invoking `RUN_ALL_TESTS()`.**

The GoogleTest framework exposes a flexible event-notification mechanism that lets you observe and react to the test execution lifecycle without modifying the library source. By implementing custom TestEventListeners in the `google/googletest` repository, you can build custom logging pipelines, performance monitors, or alternative reporting formats that integrate seamlessly with the existing test infrastructure.

## The TestEventListener Architecture

The event system is built around an abstract interface and a convenience base class located in the public header [`googletest/include/gtest/gtest.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest.h).

### The TestEventListener Interface

The abstract class **`TestEventListener`** (defined around line 930 in [`gtest.h`](https://github.com/google/googletest/blob/main/gtest.h)) declares pure virtual methods that the framework calls at specific execution points. These callbacks include `OnTestProgramStart`, `OnTestIterationStart`, `OnTestCaseStart`, `OnTestStart`, `OnTestEnd`, `OnTestCaseEnd`, `OnTestIterationEnd`, and `OnTestProgramEnd`. Each method receives context-specific references—such as `const TestInfo&` or `const UnitTest&`—allowing listeners to inspect test metadata, results, and timing.

### The EmptyTestEventListener Base Class

Rather than implementing every pure virtual method, inherit from **`EmptyTestEventListener`** (located around line 997 in [`gtest.h`](https://github.com/google/googletest/blob/main/gtest.h)). This class provides empty implementations for all callbacks, enabling you to override only the specific lifecycle events you need. This pattern minimizes boilerplate when implementing custom TestEventListeners.

## Implementing a Custom Timing Listener

Below is a complete example that records the duration of each test by capturing a timestamp in `OnTestStart` and calculating the delta in `OnTestEnd`.

```cpp
#include <gtest/gtest.h>
#include <chrono>
#include <iostream>

class TimingListener : public ::testing::EmptyTestEventListener {
 public:
  void OnTestStart(const ::testing::TestInfo& test) override {
    start_ = std::chrono::steady_clock::now();
  }

  void OnTestEnd(const ::testing::TestInfo& test) override {
    auto end = std::chrono::steady_clock::now();
    std::chrono::duration<double> secs = end - start_;
    std::cout << "[  TIME  ] " << test.test_case_name() << '.' << test.name()
              << " : " << secs.count() << " seconds\n";
  }

 private:
  std::chrono::steady_clock::time_point start_;
};

```

## Registering Listeners with the UnitTest Singleton

Listeners are managed by the **`TestEventListeners`** collection owned by the `UnitTest` singleton (accessible around line 1026 in [`gtest.h`](https://github.com/google/googletest/blob/main/gtest.h)). You must register your listener after calling `InitGoogleTest` but before `RUN_ALL_TESTS`.

```cpp
int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  
  // Append custom listener to the event queue
  ::testing::UnitTest::GetInstance()->listeners()->Append(new TimingListener);
  
  return RUN_ALL_TESTS();
}

```

### Removing and Replacing Default Output

To suppress the default console printer and use only your custom listener, call **`Release`** on the default result printer to take ownership, then delete it. Alternatively, use **`SetDefaultResultPrinter`** to substitute your own implementation as the primary output generator.

```cpp
int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  
  auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
  
  // Remove the default printer to silence standard output
  delete listeners.Release(listeners.default_result_printer());
  
  // Install a minimal custom printer
  class MinimalPrinter : public ::testing::EmptyTestEventListener {
   public:
    void OnTestProgramEnd(const ::testing::UnitTest& unit_test) override {
      std::cout << "Total tests run: " << unit_test.total_test_count() << "\n";
    }
  };
  
  listeners.SetDefaultResultPrinter(new MinimalPrinter);
  return RUN_ALL_TESTS();
}

```

## Essential Callback Methods

When implementing custom TestEventListeners, override these key methods to intercept specific events:

- **`OnTestProgramStart(const UnitTest&)`** – Called once before any tests run; use for global setup or header logging.
- **`OnTestCaseStart(const TestCase&)`** – Called before the first test in a test case (test suite) begins.
- **`OnTestStart(const TestInfo&)`** – Called immediately before an individual test starts; ideal for timers or resource tracking.
- **`OnTestEnd(const TestInfo&)`** – Called immediately after a test completes; receives the test result (success or failure).
- **`OnTestCaseEnd(const TestCase&)`** – Called after all tests in a test case finish.
- **`OnTestProgramEnd(const UnitTest&)`** – Called once after all tests complete; use for final summaries or cleanup.

## Summary

- **Inherit from `EmptyTestEventListener`** (defined in [`googletest/include/gtest/gtest.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest.h)) to avoid implementing unused callback methods when creating custom TestEventListeners.
- **Register listeners** via `UnitTest::GetInstance()->listeners()->Append()` after `InitGoogleTest` but before `RUN_ALL_TESTS()`.
- **Remove default output** by calling `Release()` on `default_result_printer()` and deleting the returned pointer to suppress standard console reporting.
- **Replace the default printer** using `SetDefaultResultPrinter()` to redirect all output through your custom implementation.
- **Access test metadata** through arguments like `const TestInfo&` and `const UnitTest&` to build detailed custom reports.

## Frequently Asked Questions

### What is the difference between `TestEventListener` and `EmptyTestEventListener`?

`TestEventListener` is an abstract interface declaring all pure virtual callback methods, while `EmptyTestEventListener` is a concrete base class that provides empty implementations for every method. You should inherit from `EmptyTestEventListener` when creating custom TestEventListeners so you only override the specific lifecycle events you need.

### How do I disable the default console output when using a custom listener?

Obtain the `TestEventListeners` collection via `UnitTest::GetInstance()->listeners()`, then call `Release(listeners.default_result_printer())` to detach the default printer. Delete the returned pointer to free the memory, which prevents the framework from printing the standard `[  OK  ]` or `[FAILED]` messages to stdout.

### Can I register multiple custom listeners simultaneously?

Yes. The `TestEventListeners` class maintains an internal repeater that forwards each callback to every registered listener in sequence. You can call `Append()` multiple times to add different listeners for distinct concerns—such as one for timing and another for custom report generation—and they will execute independently without interfering with each other.

### Which callback should I use to capture test duration accurately?

Override `OnTestStart(const TestInfo&)` to capture the start time and `OnTestEnd(const TestInfo&)` to calculate and record the duration. These callbacks fire immediately before and after the test body executes, excluding fixture setup and teardown time. If you need to include fixture lifecycle duration, use `OnTestCaseStart` and `OnTestCaseEnd` instead.