首页 > 解决方案 > 使用 GTest 多次重复多线程测试的正确方法是什么?

问题描述

使用Google Test,我想测试一个ClientListener.AcceptRequest方法的行为:

class ClientListener {
public:
    // Clients can call this method, want to test that it works
    Result AcceptRequest(const Request& request) {
        queue_.Add(request);
        ... blocks waiting for result ...
        return result;
    }
private:
    // Executed by the background_thread_;
    void ProcessRequestsInQueue() {
        while (true) {
            Process(queue_.PopEarliest());
        }
    }

    MyQueue queue_;
    std::thread background_thread_ = thread([this] {ProcessRequestsInQueue();});
};

该方法接受客户端请求,将其排队,阻塞等待结果,在可用时返回结果。

当后台线程处理来自队列的相应请求时,结果可用。

我有一个如下所示的测试:

TEST(ListenerTest, TwoRequests) {
    ClientListener listener;
    Result r1 = listener.AcceptClientRequest(request1);
    Result r2 = listener.AcceptClientRequest(request2);
    ASSERT_EQ(r1, correctResultFor1);
    ASSERT_EQ(r2, correctResultFor2);
}

由于ClientListener类的实现涉及多个线程,因此此测试可能会通过一次尝试但在另一次尝试失败。为了增加捕获错误的机会,我多次运行测试:

TEST_P(ListenerTest, TwoRequests) {
  ... same as before ...
}
INSTANTIATE_TEST_CASE_P(Instantiation, ListenerTest, Range(0, 100));

但是现在make test命令将每个参数化实例化视为一个单独的测试,并且在日志中,我看到了 100 个测试:

Test 1: Instantiation/ListenerTest.TwoRequests/1
Test 2: Instantiation/ListenerTest.TwoRequests/2
...
Test 100: Instantiation/ListenerTest.TwoRequests/100

鉴于我不使用参数值,有没有办法重写测试代码,以便make test命令记录执行 100 次的单个测试,而不是 100 次测试

标签: c++multithreadingunit-testinggoogletestnon-deterministic

解决方案


简单的答案:--gtest_repeat在执行测试时使用就可以了(默认为 1)。

更长的答案:单元测试不应该用于这种测试。GTest 在设计上是线程安全的(如他们的 README中所述),但这并不意味着它是执行此类测试的好工具。也许这是真正开始进行真正的集成测试的一个很好的起点,我真的behave为此目的推荐 Python 的框架。


推荐阅读