Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Test: How to run fixture only once for multiple tests?

I am trying to test a http client using gtest. I want to test this client with my own http server. I have a small python server. Test cases would be client sending various requests to this python server. Is there a way to start the server before all tests run and destroy that server after tests?

I am trying to use gtest fixture as shown here; by creating a new process in SetUp and killing it in TearDown. But it looks like the these calls are made for every test.

class Base: public ::testing::Test {
public:
    pid_t child_pid = 0;
    void SetUp() {
        char *cmd = "/usr/bin/python";
        char *arg[] = {cmd, "./http_server.py", NULL};
        child_pid = fork();
        if ( child_pid == 0) {
            execvp(cmd, arg);
            std::cout << "Failed to exec child: " << child_pid << std::endl;
            exit(-1);
        } else if (child_pid < 0) {
            std::cout << "Failed to fork child: " << child_pid << std::endl;
        } else {
            std::cout << "Child HTTP server pid: " << child_pid << std::endl;
        }
    }

    void TearDown() {
        std::cout << "Killing child pid: " << child_pid << std::endl;
        kill(child_pid, SIGKILL);
    }
};

TEST_F(Base, test_1) {
    // http client downloading url
}

TEST_F(Base, test_2) {
    // http client downloading url
}
like image 909
bladeWalker Avatar asked Jun 18 '19 23:06

bladeWalker


People also ask

Does Google test run tests in parallel?

gtest-parallel is a script that executes Google Test binaries in parallel, providing good speedup for single-threaded tests (on multi-core machines) and tests that do not run at 100% CPU (on single- or multi-core machines).

What is test fixture in Google test?

If you find yourself writing two or more tests that operate on similar data, you can use a test fixture. This allows you to reuse the same configuration of objects for several different tests. To create a fixture: Derive a class from ::testing::Test .

How to create test fixtures in Google Test?

Test Fixtures are easy to create in google test. You just need to create a class that is the same name as your test case and inherit from the testing::Test class. Now that you have a test fixture you need to let you tests know how to use the fixture. This is easy as well.

How do I run only specific tests in Google Test?

Sometimes, you want to run only a subset of the tests (e.g. for debugging or quickly verifying a change). If you set the GTEST_FILTER environment variable or the --gtest_filter flag to a filter string, Google Test will only run the tests whose full names (in the form of TestCaseName.TestName) match the filter.

What is googletest and how does it work?

When a test fails, googletest allows you to run it in isolation for quick debugging. Tests should be well organized and reflect the structure of the tested code. googletest groups related tests into test suites that can share data and subroutines. This common pattern is easy to recognize and makes tests easy to maintain.

What is also_run_disabled_tests in googletest?

Returns true if this test should run, that is if the test is not disabled (or it is disabled but the also_run_disabled_tests flag has been specified) and its full name matches the user-specified filter. GoogleTest allows the user to filter the tests by their full names. Only the tests that match the filter will run.


2 Answers

If you want to have single connection per test suite (single test fixture), then you can define static methods SetUpTestSuite() and TearDownTestSuite() in your fixture class (documentation)

class Base: public ::testing::Test {
public:
    static void SetUpTestSuite() {
        //code here
    }

    static void TearDownTestSuite() {
        //code here
    }
};

If you'd rather have single instance for all the tests suites, you can use global SetUp and TearDown (documentation)

class MyEnvironment: public ::testing::Environment
{
public:
  virtual ~MyEnvironment() = default;

  // Override this to define how to set up the environment.
  virtual void SetUp() {}

  // Override this to define how to tear down the environment.
  virtual void TearDown() {}
};

Then you need to register the environment of yours in GoogleTest, preferable in main() (before RUN_ALL_TESTS is called):

//don't use std::unique_ptr! GoogleTest takes ownership of the pointer and will clean up
MyEnvironment* env = new MyEnvironment(); 
::testing::AddGlobalTestEnvironment(env);

Note: The code wasn't tested.

like image 100
Yksisarvinen Avatar answered Oct 01 '22 23:10

Yksisarvinen


Faced similar issue when testing with a database. For every test execution, the database connection was connected and disconnected. Tests execution took too much time besides the intention of the tests was to check the logic inside a particular function and not to connect/disconnect from database.

So, the approach was changed to create and use mock objects instead of actual objects. Maybe in your case also you can mock the server object and make the mock object return responses to client requests and run asserts on those responses thereby checking that a particular request gets a particular corresponding response. Hence, avoiding to start and stop the actual server for every test execution.

more about google mocks here

Update: If you are using Visual Studio then you can leverage the CppUnitTestFramework which gives facility to execute functions only once at module level(TEST_MODULE_INITIALIZE ) or once at class level(TEST_CLASS_INITIALIZE ) or method level etc. GMock works with Visual Studio CppUnitTestFramework as well.

check here for CppUnitTestFramework

like image 25
dorKKnight Avatar answered Oct 01 '22 21:10

dorKKnight