The default output printer in gtest is an object named PrettyUnitTestResultPrinter that extends the TestEventListener class. TestEventListener objects can hook into the test framework and handle various events as tests are executed. You can learn about implementing TestEventListener classes here. The documentation even shows you how to implement a minimalist printer, but without the functionality of the default printer. The built in PrettyUnitTestResultPrinter does a nice job of reporting test results. The results are even colored green for success and red for failure. Being an open source project, you could just copy the implementation of PrettyUnitTestResultPrinter and modify it to your needs. I did not want to take this approach as it would be messy to extract this class and all of its dependencies and cause more maintenance.
Instead I created a TestEventListenerProxy class that implements all of the methods in TestEventListener and forwards the calls to a TestEventListener object. This class will take ownership of the pointer passed in to the constructor (deleting it in the destructor). Thus if I can get a pointer to a TestEventListener object, I can wrap it and override methods. See the code below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class TestEventListenerProxy : public TestEventListener
{
public:
explicit TestEventListenerProxy(TestEventListener* event_listener);
virtual ~TestEventListenerProxy();
virtual void OnTestProgramStart(const UnitTest& unit_test);
virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
virtual void OnTestCaseStart(const TestCase& test_case);
virtual void OnTestStart(const TestInfo& test_info);
virtual void OnTestPartResult(const TestPartResult& result);
virtual void OnTestEnd(const TestInfo& test_info);
virtual void OnTestCaseEnd(const TestCase& test_case);
virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
virtual void OnTestProgramEnd(const UnitTest& unit_test);
protected:
TestEventListener* listener;
}; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class CaseSummaryAndFailurePrinter : public TestEventListenerProxy
{
public:
explicit CaseSummaryAndFailurePrinter(TestEventListener* default_printer)
: TestEventListenerProxy(default_printer)
{
}
virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) { }
virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) { }
virtual void OnTestStart(const TestInfo& /*test_info*/) { }
virtual void OnTestEnd(const TestInfo& test_info) {
if (test_info.result()->Failed())
listener->OnTestEnd(test_info);
}
}; |
Finally, for unit tests I use the SummaryAndFailurePrinter class. This class extends CaseSummaryAndFailurePrinter and overrides the OnTestCaseStart and OnTestCaseEnd methods to remove the printing of the test case information. Thus for my 600+ unit test I see only the summary of the number of tests that were executed, and any that may have failed. This removes the verbosity of the default printer in gtest while still getting its functionality when needed.
1 2 3 4 5 6 7 8 9 10 11 | class SummaryAndFailurePrinter : public CaseSummaryAndFailurePrinter
{
public:
explicit SummaryAndFailurePrinter(TestEventListener* default_printer)
: CaseSummaryAndFailurePrinter(default_printer)
{
}
virtual void OnTestCaseStart(const TestCase& /*test_case*/) { }
virtual void OnTestCaseEnd(const TestCase& /*test_case*/) { }
}; |
1 2 3 4 5 6 7 8 9 10 | testing::InitGoogleTest(&argc, argv);
testing::InitGoogleMock(&argc, argv);
testing::TestEventListeners& listeners =
testing::UnitTest::GetInstance()->listeners();
auto default_printer = listeners.Release(listeners.default_result_printer());
listeners.Append(new SummaryAndFailurePrinter(default_printer));
return RUN_ALL_TESTS(); |
The more I use gtest and gmock the more impressed I am. This is by far the best C++ testing framework that I have ever seen. Great job google people!
This comment has been removed by the author.
ReplyDeleteThis is hugely helpful! This is just the bit I've found missing from the gtest framework.
ReplyDeleteYour article came helpful in writing my own listener, thank you janglin.
ReplyDeleteWhat are the possibilities, ideas, or even creative ideas lent via some other martial arts as well as informative cultures which may be different on the readers as well as which in turn will need more justification? https://imgur.com/a/GpLq1xi https://imgur.com/a/sQ5DSxp https://imgur.com/a/PntoZrs https://imgur.com/a/xa2xZbs https://imgur.com/a/3GJ8utn https://imgur.com/a/1kYFnqm https://imgur.com/a/AkIBlvz
ReplyDelete