I am trying to capture the stdout at the start of each individual test, and if the test fails, only then print the stdout. I need this to run for each TEST and TEST_F in a directory so I am looking if I can apply a global test fixture if possible to the main.
I can apply a global environment but this runs at the setup and tear down of the test runner. And I can get this working by adding the code to each of my many standard test fixtures but I was hoping for a global solution rather than changing each fixture.
struct dummyFixture : public ::testing::Test
{
// --- Need to apply this globally ---
void SetUp()
{
backup = std::cout.rdbuf();
std::cout.rdbuf(testingSink.rdbuf());
}
void TearDown()
{
std::cout.rdbuf(backup);
if (::testing::Test::HasFailure())
std::cout << testingSink.str() << std::endl;
testingSink.str(std::string());
}
private:
std::stringstream testingSink;
std::streambuf *backup;
};
TEST(dummyTest, test_pass)
{
// should not print log to console
std::cout << "DUMMY TEST" << std::endl;
EXPECT_TRUE(true);
}
TEST_F(dummyFixture, test_fail)
{
// should print log to console
std::cout << "DUMMY TEST FIXTURE" << std::endl;
EXPECT_TRUE(false);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Since you don't want to modify any of the text fixtures and you want to run this just like the SetUp() & TearDown() of the test fixture, you can try with below approach.
class Logger
{
Logger()
{
backup = std::cout.rdbuf();
std::cout.rdbuf(testingSink.rdbuf());
}
~Logger()
{
std::cout.rdbuf(backup);
if (::testing::Test::HasFailure())
std::cout << testingSink.str() << std::endl;
testingSink.str(std::string());
}
private:
std::stringstream testingSink;
std::streambuf *backup;
};
You can now derive all of your test classes(deriving from ::testing::test) from this Logger class.
struct dummyFixture : public ::testing::Test, **public Logger**
{
};
GTest also has methods CaptureStdout() & GetCapturedStdout() to get the captured stdout string, you can use them as well.
This will make sure that you achieve what you are trying to do with minimal code changes.