当前位置: 首页 > 知识库问答 >
问题:

使用GTest多次重复多线程测试的正确方法是什么?

姬阳曜
2023-03-14

使用googletest,我想测试<code>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 次测试?

共有1个答案

詹杰
2023-03-14

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

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

 类似资料:
  • 我的程序使用ZMQ进行通信。也就是说,服务器(C、linux)创建一个XPUB套接字,然后在一个线程中读取它,在另一个线程中发布数据(写入)。 客户端(java、jzmq、linux)创建一个SUB套接字,并订阅使用它。 一段时间后,服务器端在读取线程中接收SIGABRT。 什么可能是问题的根源?在不同的线程中读/写或创建XPUB/SUB对? 如果问题是在多线程中,那么使用XPUB套接字的正确范例

  • 问题内容: 假设我有多个继承方案: 有编写的两个典型方法的: (老式) (较新的样式) 但是,无论哪种情况,如果父类(和)没有遵循相同的约定,则代码将无法正常工作(某些代码可能会丢失,或被多次调用)。 那么又是什么正确的方法呢?说“保持一致,遵循一个或另一个”很容易,但是如果或来自第三方图书馆,那又如何呢?有没有一种方法可以确保所有父类构造函数都被调用(以正确的顺序,并且只能调用一次)? 编辑:看

  • 问题内容: 即使在使用Java Swing一年以上之后,对我来说,它仍然像魔术一样。如何正确使用BufferStrategy,尤其是方法? 我想添加一个JFrame和一个Canvas,然后进行绘制。我还希望能够调整()画布的大小。每次我调整Canvas的大小时,似乎都会被浪费掉,或者变得毫无用处,因为在上使用并没有真正做任何事情。另外,它具有怪异的不确定性行为,我不知道如何正确同步它。 这就是我的

  • 问题内容: 我想在Linux上使用该机制。我希望我的应用程序知道何时更改了文件。能否请您提供给我一个示例,该怎么做? 问题答案: 文档(来自具有inotify的Monitor文件系统活动) 在C API 提供了三个系统调用来构建各种文件系统监视器: 在内核中创建子系统的实例,并在成功和失败时返回文件描述符。与其他系统调用一样,如果失败,请检查诊断。 顾名思义,它增加了一块 手表 。每个监视都必须提

  • 问题内容: 需要帮助,以了解如何在UIKit中使用prepareForReuse()。该文件说 您只应重置与内容无关的单元格属性,例如Alpha,编辑和选择状态 但是如何重置单个属性属性(例如isHidden)呢? 假设我的单元格有2个标签,我应该在哪里重置: 标签文本 label.numberOfLines label.isHidden 我的tableView(_:cellForRowAt :)

  • 一段时间以来,我一直试图将我的tableview工作作为一种电子表格,通过背景线程进行更新,当单元格更新时,它会亮起几秒钟(更改样式),然后返回到原始样式。我已经知道,我不能直接在表格单元格中存储和设置样式,我需要某种支持类来保存这些数据。但是tableview“重用”单元格(使用相同的单元格处理不同的数据)的行为真的很奇怪。当所有单元格都适合屏幕时,它对我来说完美无瑕,但一旦我放置大约100个单