How to Generate XML Test Reports with GoogleTest
GoogleTest generates JUnit-compatible XML reports natively by passing the --gtest_output=xml flag or setting the GTEST_OUTPUT environment variable, which triggers the XmlUnitTestResultPrinter listener to serialize test results at the end of execution.
The GoogleTest framework (google/googletest) provides built-in support for generating machine-readable XML test reports without requiring external tools. This functionality centers around the XmlUnitTestResultPrinter class, which captures test execution data and serializes it into a standard JUnit-compatible format. Understanding how to generate XML test reports with GoogleTest enables seamless integration with CI/CD pipelines and test analytics platforms.
Enabling XML Output via Command Line
The simplest way to generate XML test reports is through the --gtest_output command-line flag. When set to xml, GoogleTest automatically instantiates an XmlUnitTestResultPrinter and registers it as the default XML generator in the TestEventListeners collection.
Generate a report with the default filename (test_detail.xml):
./my_test --gtest_output=xml
Specify a custom file path:
./my_test --gtest_output=xml:/tmp/custom_report.xml
Alternatively, use the GTEST_OUTPUT environment variable:
export GTEST_OUTPUT="xml:./test_reports/"
./my_test
When a directory is provided, GoogleTest derives the filename from the test binary name and appends a numeric suffix (_1, __2, etc.) to avoid overwriting existing files.
How the XML Generator Works Internally
The XML generation pipeline is implemented in googletest/src/gtest.cc and orchestrated through three core components:
XmlUnitTestResultPrinter Construction
When the --gtest_output=xml flag is detected, GoogleTest creates an instance of XmlUnitTestResultPrinter (see line 3983 in googletest/src/gtest.cc). The constructor receives the output path and initializes the listener. This object is stored as the default_xml_generator in the global TestEventListeners collection (defined at line 1178 in googletest/include/gtest/gtest.h).
Result Collection During Execution
As tests execute, each TestResult object accumulates data including pass/fail status, execution time, and any custom properties added via TestResult::RecordProperty (declared at line 1082 in googletest/include/gtest/gtest.h). The XML printer observes these results through the test event listener interface.
Serialization and File Writing
At the end of the test run, the OnTestIterationEnd method (line 4087 in googletest/src/gtest.cc) handles the actual XML generation. This method:
- Opens the target file via
OpenFileForWriting - Builds the XML document using static helper functions including
EscapeXml,OutputXmlAttribute, andOutputXmlTestSuiteForTestResult - Writes the complete buffer to disk
The resulting XML follows the JUnit schema with <testsuites>, <testsuite>, <testcase>, and <failure> elements.
Customizing XML Report Content
Adding Custom Properties with RecordProperty
You can inject custom metadata into the XML output using RecordProperty, which adds attributes to the <testcase> element:
#include <gtest/gtest.h>
TEST(Database, Connection) {
// Record custom properties that appear as XML attributes
::testing::TestResult* result = ::testing::UnitTest::GetInstance()
->current_test_info()
->result();
result->RecordProperty("hostname", "server01");
result->RecordProperty("build_id", "2024.1.2");
EXPECT_TRUE(ConnectToDatabase());
}
These properties appear as <testcase hostname="server01" build_id="2024.1.2" ... /> in the final XML.
Replacing the Default XML Generator
For advanced use cases, replace the built-in XML generator with a custom listener by manipulating the TestEventListeners registry:
#include <gtest/gtest.h>
#include <fstream>
class CustomXmlListener : public testing::EmptyTestEventListener {
public:
void OnTestIterationEnd(const testing::UnitTest& unit_test, int) override {
std::ofstream xml_file("custom_output.xml");
xml_file << "<?xml version=\"1.0\"?>\n<testsuites>\n";
// Custom serialization logic here
xml_file << "</testsuites>\n";
}
};
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
testing::TestEventListeners& listeners =
::testing::UnitTest::GetInstance()->listeners();
// Remove and delete the default XML generator
testing::TestEventListener* old_xml =
listeners.Release(listeners.default_xml_generator());
delete old_xml;
// Install custom listener
listeners.SetDefaultXmlGenerator(new CustomXmlListener);
return RUN_ALL_TESTS();
}
XML File Naming and Output Locations
When specifying a directory rather than a file path, GoogleTest uses the GetOutputFile helper (defined at line 98 in googletest/include/gtest/internal/gtest-filepath.h) to construct the output filename. The algorithm:
- Extracts the binary name from
argv[0] - Appends
.xmlextension - Checks for existing files and appends numeric suffixes (
_1,_2) to prevent overwrites
This ensures that multiple test runs in the same directory preserve historical results rather than clobbering previous XML files.
Summary
- Enable XML output using
--gtest_output=xmlor theGTEST_OUTPUTenvironment variable to trigger the built-inXmlUnitTestResultPrinter. - Customize metadata by calling
TestResult::RecordPropertywithin test bodies to inject custom XML attributes. - Replace the generator via
TestEventListeners::ReleaseandSetDefaultXmlGeneratorfor complete control over XML formatting. - File naming automatically handles directory paths and collision avoidance through the
GetOutputFileimplementation ingtest-filepath.h.
Frequently Asked Questions
What XML format does GoogleTest use?
GoogleTest produces JUnit-compatible XML following the standard testsuites schema. The output includes <testsuite> elements containing <testcase> entries with attributes for execution time, status, and failure messages, making it compatible with Jenkins, GitLab CI, and other JUnit-consuming tools.
How do I specify a custom output directory for XML reports?
Pass a directory path to the --gtest_output flag: ./test --gtest_output=xml:./reports/. GoogleTest automatically names the file based on the test binary name (e.g., test_suite_1.xml) and places it in the specified directory, incrementing the numeric suffix if files already exist.
Can I add custom metadata to GoogleTest XML output?
Yes. Within any test case, call RecordProperty(key, value) on the current test result. These key-value pairs appear as XML attributes on the <testcase> element, allowing you to annotate tests with build numbers, environment details, or categorization tags.
Is it possible to disable the default XML generator in GoogleTest?
Yes. Obtain the TestEventListeners instance from UnitTest::GetInstance()->listeners(), call Release(listeners.default_xml_generator()) to remove the default printer, and optionally install a custom listener via SetDefaultXmlGenerator. This is useful when you need to suppress XML output or replace it with an alternative format entirely.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →