1

I would like to write death tests for an application where exit code is 0 and there is some message displayed on cout instead of cerr.

void display_help(){
    //std::cerr.set_rdbuf(std::cout.rdbuf());
    //std::cerr << "From display_help" << std::endl;
    std::cout << "From display_help"<< std::endl;
    std::exit(0);
}

TEST_F(CommandlineTest, help_function_test) {
    std::string exectedHelpMessage{ "" };
    exectedHelpMessage += std::string("From display_help");

    EXPECT_EXIT(display_help(),
                ::testing::ExitedWithCode(0),
                ::testing::ContainsRegex(exectedHelpMessage));
}

While using cout as stream

While using cerr as stream

The above code fails because, its unable to match the message. My observation is, when the display_help function displays a message in cerr death test is able to capture. But, when the something is done on cout it's not able to.
Is there any suggestion on how such testing can be enabled ?

cnsujeer
  • 11
  • 2
  • Huh! TIL a new term: https://stackoverflow.com/questions/3698718/what-are-google-test-death-tests – Dai Jul 06 '20 at 07:34
  • Hi Dai, Were you highlighting anything specific from the above link? As I mentioned, My concern is not regular usage. I did use death tests for capturing all the failure cases. But, this is one such situation where exit code is 0 and message is streamed to cout instead of cerr. Let me know if I missed any crucial hint from the link you posted. :-) – cnsujeer Jul 06 '20 at 15:12
  • Oh, I wasn’t posting anything useful or helpful - it’s just that I hadn’t come across the term “death test” before. – Dai Jul 06 '20 at 20:02
  • You can make output stream a parameter to this test (with default to `std::cerr`) and inject stringstream in the test and check it's content using `str()` method. – Quarra Jul 07 '20 at 06:33
  • @Quarra , Just for your information, earlier i tried the following statement as part of EXPECT_EXIT statement : std::cerr.set_rdbuf(std::cout.rdbuf()); Meanwhile, for my better understanding if you don't mind, can you provide few lines of psudo code on your suggestion :-) – cnsujeer Jul 07 '20 at 09:31
  • I tried my suggestion and it doesn't work; not sure why - `std::exit` must somehow influence this void display_help(std::ostream& os = std::cout) { // std::cerr.set_rdbuf(std::cout.rdbuf()); // std::cerr << "From display_help" << std::endl; os << "From display_help" << std::endl; std::exit(0); } TEST(CommandlineTest, help_function_test) { std::stringstream ss; EXPECT_EXIT(display_help(ss), ::testing::ExitedWithCode(0), ".*"); ASSERT_EQ("From display_help\n", ss.str()); } – Quarra Jul 07 '20 at 10:02
  • But, std::exit() happens after the flushing into the stream. But, thanks for your kind reply :-) – cnsujeer Jul 08 '20 at 17:06
  • I have experimented with using the `rdbuf()` method of the streams to redirect `cout` to a `stringstream`, and then check that the stringstream data matches. BUT this does not work with the `EXPECT_EXIT` gtest macro. It seems that cout and cerr inside the EXPECT_EXIT macro are magically handled, perhaps as a result of forking, and the cout is NOT captured by the stringstream. (This experiment was to avoid changing the API of the device under test). – Mark Lakata Mar 10 '21 at 23:57

0 Answers0