Google测试:如何针对多个测试仅运行一次夹具?

时间:2019-06-18 23:03:13

标签: c++ unit-testing googletest

我正在尝试使用gtest测试http客户端。我想用自己的http服务器测试该客户端。我有一个小型的python服务器。测试用例是客户端向该python服务器发送各种请求。有没有办法在所有测试运行之前启动服务器并在测试之后销毁该服务器?

我正在尝试使用gtest固定装置,如下所示;通过在SetUp中创建一个新进程并在TearDown中将其杀死。但是看起来这些调用是针对每个测试进行的。

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
}

2 个答案:

答案 0 :(得分:3)

如果您希望每个测试套件具有单个连接(单个测试夹具),则可以在夹具类(documentation)中定义静态方法SetUpTestSuite()TearDownTestSuite()

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

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

如果您希望所有测试套件都具有一个实例,则可以使用全局SetUp和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() {}
};

然后,您需要在GoogleTest中注册您的环境,最好在main()中注册(在调用RUN_ALL_TESTS之前):

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

注意:该代码未经测试。

答案 1 :(得分:1)

使用数据库进行测试时遇到类似的问题。 对于每个测试执行,都将连接和断开数据库连接。除了执行测试的目的是检查特定功能内部的逻辑而不是与数据库连接/断开连接之外,测试执行还花费了太多时间。

因此,该方法已更改为创建和使用模拟对象而不是实际对象。 也许在您的情况下,您也可以模拟服务器对象并使模拟对象返回对客户端请求的响应,并对这些响应运行断言,从而检查特定请求是否获得特定的对应响应。 因此,避免为每次测试执行启动和停止实际服务器。

more about google mocks here

更新: 如果您使用的是Visual Studio,则可以利用CppUnitTestFramework,它提供了仅在模块级别(TEST_MODULE_INITIALIZE)或在类级别(TEST_CLASS_INITIALIZE)或方法级别执行一次功能的便利。 GMock也可以与Visual Studio CppUnitTestFramework一起使用。

在此处检查CppUnitTestFramework