Search code examples
c++unit-testinggoogletestfixtures

gtest: What is the best way to perform some actions only when the specific fixture must be run?


I have a class derived from ::testing::Test and several fixtures in it. I've also reimplemented SetUpTestCase method which must start the side application needed for those tests. But now I want to add a new fixture which needs that side application to be started with some additional arguments to enable logging. The problem is, I want it to be logged only if I'm sure that the new test is in the run-list and will not be missed, otherwise the logging is not necessary. So I'd like to write something like that:

class MyTest : public ::testing::Test
{
public:
    static void SetUpTestCase()
    {
        std::vector<std::string> args;
        args.push_back("--silent");

        // if (TestLogging fixture will be run)
            args.push_back("--enableLog");

        //Start the side application with arguments "args"
    }
};

TEST_F(MyTest, Test1)
{/**/}
TEST_F(MyTest, Test2)
{/**/}
TEST_F(MyTest, TestLogging)
{/**/}

Is there any way to reach the behavior I expect? Or maybe I shouldn't mess up with SetUpTestCase and there is a better way to do this?


Solution

  • If I understand correctly, at MyTest::SetUpTestCase, that is executed only once for the entire test suite, you want to check if the list of tests to be run include any TestLogging test.

    I have found the following way of doing it. It's not very elegant but it seems to work. I've separated the logic in a test_logging() function, which will return true if any TestLogging test should be run for the current MyTest test suite execution:

    • Get the current test suite.
    • Walk all the tests for that test suite.
    • Return true when you find a test whose name starts with TestLogging and should be run in this tests suite execution.
    • Return false otherwise.

    [Demo]

    class MyTest : public ::testing::Test {
    protected:
        inline static std::vector<std::string> args{};
        inline static bool test_logging() {
            auto current_test_suite{ ::testing::UnitTest::GetInstance()->current_test_suite() };
            for (int i{ 0 }; i < current_test_suite->total_test_count(); ++i) {
                auto test_info{ current_test_suite->GetTestInfo(i) };
                if (std::string{ test_info->name() }.starts_with("TestLogging") and test_info->should_run()) {
                    return true;
                }
            }
            return false;
        }
    public:
        inline static void SetUpTestCase() {
            args.push_back("--silent");
            if (test_logging()) {
                args.push_back("--enableLog");
            }
            // Start the side application with arguments "args"
        }
    };