【问题标题】:Google Test: How to run fixture only once for multiple tests?谷歌测试:如何为多个测试只运行一次夹具?
【发布时间】:2019-06-18 23:03:13
【问题描述】:

我正在尝试使用 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
}

【问题讨论】:

    标签: c++ unit-testing googletest


    【解决方案1】:

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

    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);
    

    注意:代码未经测试。

    【讨论】:

      【解决方案2】:

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

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

      more about google mocks here

      更新: 如果您使用的是 Visual Studio,那么您可以利用 CppUnitTestFramework,它提供了在模块级别(TEST_MODULE_INITIALIZE)或类级别(TEST_CLASS_INITIALIZE)或方法级别等执行一次函数的便利。 GMock 也适用于 Visual Studio CppUnitTestFramework。

      在这里查看CppUnitTestFramework

      【讨论】:

      猜你喜欢
      • 2013-10-30
      • 1970-01-01
      • 2013-10-10
      • 2011-03-10
      • 2020-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多