使用 GTest 多次重复多线程测试的正确方法是什么?
What's the proper way using GTest to repeat a multi-threaded test multiple times?
使用 Google 测试,我想测试 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();});
};
该方法接受客户端请求,将其排队,阻塞等待结果,returns 可用时结果。
当后台线程处理队列中的相应请求时,结果可用。
我有一个测试如下:
TEST(ListenerTest, TwoRequests) {
ClientListener listener;
Result r1 = listener.AcceptClientRequest(request1);
Result r2 = listener.AcceptClientRequest(request2);
ASSERT_EQ(r1, correctResultFor1);
ASSERT_EQ(r2, correctResultFor2);
}
由于 ClientListener
class 的实施涉及多个线程,此测试可能会在一次尝试中通过但在另一次尝试中失败。为了增加捕获错误的机会,我 运行 多次测试:
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 次的单个测试测试?
简单答案:在执行测试时使用 --gtest_repeat
即可(默认为 1)。
更长的答案:单元测试不应用于此类测试。 GTest 在设计上是线程安全的(如 in their README 所述),但这并不意味着它是执行此类测试的好工具。也许这是真正开始进行真正的集成测试的一个很好的起点,为此我真的推荐 Python 的 behave
框架。
使用 Google 测试,我想测试 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();});
};
该方法接受客户端请求,将其排队,阻塞等待结果,returns 可用时结果。
当后台线程处理队列中的相应请求时,结果可用。
我有一个测试如下:
TEST(ListenerTest, TwoRequests) {
ClientListener listener;
Result r1 = listener.AcceptClientRequest(request1);
Result r2 = listener.AcceptClientRequest(request2);
ASSERT_EQ(r1, correctResultFor1);
ASSERT_EQ(r2, correctResultFor2);
}
由于 ClientListener
class 的实施涉及多个线程,此测试可能会在一次尝试中通过但在另一次尝试中失败。为了增加捕获错误的机会,我 运行 多次测试:
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 次的单个测试测试?
简单答案:在执行测试时使用 --gtest_repeat
即可(默认为 1)。
更长的答案:单元测试不应用于此类测试。 GTest 在设计上是线程安全的(如 in their README 所述),但这并不意味着它是执行此类测试的好工具。也许这是真正开始进行真正的集成测试的一个很好的起点,为此我真的推荐 Python 的 behave
框架。