How to Generate XML Test Reports with GoogleTest

GoogleTest generates JUnit-compatible XML reports via the --gtest_output=xml flag, which triggers the internal XmlUnitTestResultPrinter listener to serialize test results to disk.

GoogleTest (the google/googletest repository) provides built-in support for exporting detailed XML test reports without requiring third-party tools. This functionality is implemented directly in the core framework through a specialized test event listener that captures results and writes them to a JUnit-compatible schema.

Enabling XML Output via the --gtest_output Flag

The primary mechanism to generate XML test reports is the --gtest_output command-line flag. You can also set the GTEST_OUTPUT environment variable to achieve the same result.

When you append :xml to the flag, GoogleTest instantiates an XmlUnitTestResultPrinter (defined in googletest/src/gtest.cc around line 3983) and registers it as the default XML generator in the TestEventListeners collection.

Run your test binary with one of the following patterns:


# Generate XML in the default file (test_detail.xml in the working directory)

./my_test --gtest_output=xml

# Specify a custom file path

./my_test --gtest_output=xml:/path/to/report.xml

# Output to a directory (filename derived from test binary name)

./my_test --gtest_output=xml:/tmp/test_reports/

The XML Generation Architecture

The XML reporting system centers on the XmlUnitTestResultPrinter class. According to the source code in googletest/src/gtest.cc, this listener implements the OnTestIterationEnd callback, which executes after all tests complete.

The printer is stored as the default_xml_generator within the global UnitTest instance (see googletest/include/gtest/gtest.h line 1178). At runtime, GoogleTest populates TestResult objects for each test case, then delegates serialization to the printer's static helper methods including EscapeXml, OutputXmlAttribute, and OutputXmlTestSuiteForTestResult.

The Serialization Pipeline

The XML generation follows a four-stage pipeline:

  1. Listener Creation: The constructor XmlUnitTestTestResultPrinter::XmlUnitTestResultPrinter (line 3985 in googletest/src/gtest.cc) receives the output path derived from the flag value.

  2. Result Collection: As tests execute, GoogleTest populates TestResult objects. You can augment these with custom data via TestResult::RecordProperty (declared in googletest/include/gtest/gtest.h line 1082).

  3. XML Serialization: When the test run ends, OnTestIterationEnd (line 4087 in googletest/src/gtest.cc) opens the target file using OpenFileForWriting, builds the XML buffer using escape and formatting utilities, and writes the output.

  4. File Naming: If you specify a directory rather than a file, GetOutputFile (in googletest/include/gtest/internal/gtest-filepath.h line 98) derives the filename from the test binary name and appends a numeric suffix (_1, _2, etc.) to prevent overwrites.

Customizing XML Output

Adding Custom Properties with RecordProperty

You can inject custom XML attributes into individual test cases using the RecordProperty API. These properties appear as XML attributes on the <testcase> element.

#include <gtest/gtest.h>

TEST(Foo, Bar) {
  // Add custom metadata that appears in the XML output
  ::testing::TestResult* result = ::testing::UnitTest::GetInstance()
                                      ->current_test_info()
                                      ->result();
  result->RecordProperty("custom_key", "custom_value");
  
  EXPECT_TRUE(true);
}

Implementing Custom XML Listeners

For advanced use cases, you can replace the default XML generator with a custom implementation by manipulating the TestEventListeners collection. Retrieve the current default via Release, then register your replacement using SetDefaultXmlGenerator.

#include <gtest/gtest.h>

class MyXmlListener : public testing::EmptyTestEventListener {
 public:
  void OnTestIterationEnd(const testing::UnitTest& unit_test, int) override {
    // Implement custom XML generation logic here
  }
};

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  
  // Access the listeners collection
  testing::TestEventListeners& listeners = 
      ::testing::UnitTest::GetInstance()->listeners();
  
  // Remove and delete the default XML generator
  testing::TestEventListener* old = 
      listeners.Release(listeners.default_xml_generator());
  delete old;
  
  // Install custom listener
  listeners.SetDefaultXmlGenerator(new MyXmlListener);
  
  return RUN_ALL_TESTS();
}

XML Format and Schema Compatibility

The generated XML adheres to the JUnit schema, using the <testsuites> root element containing nested <testsuite> and <testcase> elements. Failed assertions generate <failure> nodes with detailed message attributes, while RecordProperty data appears as custom attributes on test cases.

This format is compatible with continuous integration systems like Jenkins, GitLab CI, and Azure DevOps, which can ingest the reports for test visualization and trend analysis.

Summary

  • Enable XML output using --gtest_output=xml:path/to/file.xml or the GTEST_OUTPUT environment variable.
  • Core implementation lives in googletest/src/gtest.cc within the XmlUnitTestResultPrinter class.
  • Customize attributes by calling TestResult::RecordProperty during test execution for metadata inclusion.
  • Replace the generator by releasing default_xml_generator from TestEventListeners and installing a custom listener.
  • Automatic file naming handles directory inputs via GetOutputFile in gtest-filepath.h, appending numeric suffixes to avoid collisions.

Frequently Asked Questions

How do I generate XML test reports using the GoogleTest command line?

Pass the --gtest_output=xml flag followed by an optional path. For example, ./test_binary --gtest_output=xml:results.xml writes a JUnit-compatible XML file to results.xml. If you omit the path, GoogleTest creates test_detail.xml in the working directory.

What XML schema does GoogleTest use?

GoogleTest generates JUnit-compatible XML using a <testsuites> root element containing <testsuite> and <testcase> nodes. The schema supports standard elements like <failure> for assertion failures and allows custom attributes via the RecordProperty API.

Can I customize the XML output file name dynamically?

Yes. When --gtest_output=xml points to a directory, GoogleTest automatically generates filenames based on the test binary name using the GetOutputFile utility in gtest-filepath.h. The logic appends incremental numeric suffixes (_1, _2) to prevent overwriting existing files.

How do I add custom metadata to GoogleTest XML output?

Call RecordProperty on the current test result during test execution. Access the result via ::testing::UnitTest::GetInstance()->current_test_info()->result(), then invoke RecordProperty(key, value). These key-value pairs appear as XML attributes on the corresponding <testcase> element in the final report.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →