How to send custom message in Google C++ Testing Framework?
Asked Answered
R

6

130

I use Google C++ Testing Framework for unit testing of my code. I use Eclipse CDT with C++ Unit testing module for output analysis.

Previously I used CppUnit it has macros family CPPUNIT*_MESSAGE that could be called like this:

CPPUNIT_ASSERT_EQUAL_MESSAGE("message",EXPECTED_VALUE,ACTUAL_VALUE)

And allows to send custom messages to test output.

Is there a way to include some custom text in google test output?

(Preferably the way that could include message to data that is read by existing programs for automated unit testing using google test.)

Resolvable answered 10/5, 2013 at 22:28 Comment(1)
I would assume the expected way to do this is by using glog, but I haven't tried (yet -- I might do that next week).Labrum
S
230

The gtest macros return a stream for outputting diagnostic messages when a test fails.

EXPECT_TRUE(false) << "diagnostic message";
Socialist answered 10/5, 2013 at 22:50 Comment(9)
@ErikAronesty Have you taken a look in the source to see if there's an easy-ish way to interface with that data?Dishonor
If you need to print the text regardless of the result, simply write it to stdout. But this usually results very noisy tests, difficult to work with.Lour
FAIL() << "diagnostic message"; works the same way, but it does reduce the generated output by a few lines as it does not tell you about actual value, expected value and so on, which it does for all EXPECT_X() macros. Just in case you want to reduce output length a little bit.Luteous
@BallisticTomato, that's the real answer right there.Beatitude
Do you know where this is at in the documentation?Tager
I don't know where it explicitly says it, but if you search this page for ) << you'll at least see a variety of examples of this feature.Tager
Take a look at SCOPED_TRACE as wellTrevino
Make sure to check Vlad's answer for a version with cleaner output, namely ADD_FAILURE() << "message"; (or just FAIL() << "message"; if you want the test to stop there.Phalange
Worth noting that stderr and stdout prints work as well. However, given my testing, they do not show up until after an EXPECT_ / FAIL_ prints something to console. Even with fflush, nothing shows up until after this happens. Idk why, but definitely confusing if you are trying to debug a hanging test.Tantra
D
68

There is no way of doing it cleanly in the current version of gtest. I looked at the code, and the only text output (wrapped in gtest "Messages") is shown if you fail a test.

gtest used to expose some of its internal color format codes (which would have been useful, because I guess it is portable) but recent versions of gtest have hidden that. So I have modified this answer to simply use ANSI escape sequences to make colors. If you want to see the old answer, click on the "edited" link at the bottom of the post.

Usage:

TEST(pa_acq,Foo)
{
  TEST_COUT << "Hello world" << std::endl;
}

Output:

Example output

Code:

// C++ stream interface
class TestCout : public std::stringstream
{
public:
    ~TestCout()
    {
        std::cout << "\u001b[32m[          ] \u001b[33m" << str() << "\u001b[0m" << std::flush;
    }
};

#define TEST_COUT  TestCout()
Decide answered 19/3, 2015 at 21:52 Comment(3)
Thanks, this is the correct solution, IMHO. But can I suggest to add a \n in the PRINTF inside the class? that's because we cannot join lines with TEST_COUT as we do with std::cout, so it is useless to let the user add his \n. Thank you anyway!Bowman
Unfortunately this approach doesn't work any longer with modern versions of Google Test - testing::internal::ColoredPrintf isn't available any longer to the public :(Origen
I have modified the answer to not use gtest internals.Decide
P
38

There is a quite simple and hacky way for doing it (without the need of diving into internal classes or creating new custom classes).

Just define a macro:

#define GTEST_COUT std::cerr << "[          ] [ INFO ]"

and use GTEST_COUT (just like cout ) in your tests :

GTEST_COUT << "Hello World" << std::endl;

And you'll see the result:

enter image description here

Credit goes to @Martin Nowak for his finding.

Peaslee answered 22/2, 2018 at 10:13 Comment(0)
I
17

From the Advanced googletest Topics you can use a few macros for that purpose.

  • SUCCEED() SUCCEED() << "success/info message"; SUCCEED() only outputs your message and proceeds. It does not mark test as passed. Its result will be determined by the following asserts.
  • FAIL() FAIL() << "test failure message"; FAIL() marks your test as failed, outputs your message and then returns from the function. Therefore can only be used in functions returning void.
  • ADD_FAILURE() ADD_FAILURE() << "test failure message"; ADD_FAILURE() marks your test as failed and outputs your message. It does not return from the calling function and execution flow continues like with EXPECT_ series of macros.
Inwards answered 24/11, 2020 at 11:37 Comment(2)
The link provided isn't alive anymore, but I found it here: google.github.io/googletest/advanced.html Also, the SUCCEED() macro explicitly doesn't print anything to the output at the moment, but they "may" add it in the future.Nonbeliever
Best answer right here.Beatitude
R
5

Refer to Mark Lakata's answer, here is my way:

Step1: create a header file, for example: gtest_cout.h

Code:

#ifndef _GTEST_COUT_H_
#define _GTEST_COUT_H_

#include "gtest/gtest.h"

namespace testing
{
namespace internal
{
enum GTestColor
{
    COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW
};
extern void ColoredPrintf(GTestColor color, const char* fmt, ...);
}
}

#define GOUT(STREAM) \
    do \
    { \
        std::stringstream ss; \
        ss << STREAM << std::endl; \
        testing::internal::ColoredPrintf(testing::internal::COLOR_GREEN, "[          ] "); \
        testing::internal::ColoredPrintf(testing::internal::COLOR_YELLOW, ss.str().c_str()); \
    } while (false); \

#endif /* _GTEST_COUT_H_ */

Step2: use GOUT in your gtest

Usage:

#include "gtest_cout.h"

TEST(xxx, yyy)
{
    GOUT("Hello world!");
}
Rachael answered 27/7, 2017 at 8:11 Comment(1)
ColoredPrintf has been made static in a recent version, so this hack will not work any more.Acridine
K
3

You should define the below:

static class LOGOUT {
public:
    LOGOUT() {}
    std::ostream&  info() {
        std::cout << "[info      ] ";
        return std::cout;
    }

} logout;

using this:

logout.info() << "test: " << "log" << std::endl;
Knorr answered 17/5, 2017 at 1:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.