c++ - 用于集成测试的模拟库

标签 c++ c testing mocking integration-testing

我有一个现有的 C/C++ 应用程序,它通过多个接口(interface)(TCP、DB、共享内存)与其他应用程序/系统通信。我想在真实环境中运行一次应用程序并“记录”所有函数调用及其返回值(或对作为参数传递的缓冲区的更改)。我只会用“ spy ”记录与外部接口(interface)(TCP、DB)相关的调用。然后我可以再次运行该应用程序,但使用应该返回以前记录的值的“假”函数。这样我就可以“重放”一次执行,并检查结果是否与原始执行相匹配。

一个重要的特性是模拟时间函数( sleep 、时间、GetLocalTime),因为(例如)对数据库的调用可能在选择中有当前日期或时间。能够比原始执行更快地“重放”所有调用会更好(一天的执行可以在几分钟内重放)。例如,对 sleep(1000) 的调用应该在不等待的情况下返回,但是对 GetLocalTime 的连续调用应该多返回 1 秒。这应该考虑到其他线程应该具有一致的时间值(例如,库应该允许一个线程对 sleep(1000) 调用 1 次,在另一个线程中对 sleep(100) 调用 10 次)。

理想情况下,它不需要对应用程序进行大量更改或重构,只需重新定义对时间函数的调用以及对外部接口(interface)(DB、TCP)库的调用。

我想知道是否存在实现这些功能的库或框架,或者什么是一个好的起点。

我已经为类似的问题实现了多次解决方案,但是对于非常简单的模块,例如模拟 TCP 连接以测试协议(protocol)实现,但我每次都感觉像是在重新发明轮子,而且这些简单的解决方案无法很好地扩展与更多线程或与更多接口(interface)的交互。

最佳答案

既然你提到你的应用程序是 C/C++,我假设你有能力使用 C 框架。我将在这个答案中讨论 CMock 和 Unity。如果面向对象的原则在您的任务中更为普遍,那么您可以看看类似于 CMock 的 googlemock,但它是为 C++ 开发的,并且考虑了类。

--

CMock 结合 Unity 可以为您的测试需求提供一个框架。

CMock 为您提供了轻松模拟公共(public)接口(interface)的能力。例如,如果您要测试以下简单代码:

void sendPacket(char * packet, int packetLen, int tcpSocket)
{
    if (packet)
    {
        send(tcpSocket, packet, packetLen, 0);
    }
}

您可以使用 CMock 创建发送调用的模拟。这将允许您验证传递给发送的参数,从而验证缓冲区中的内容。您还可以验证发送返回的大小。模拟发送函数的 CMock 的 ExpectAndReturn 变体将允许您执行这两个验证。

CMock 还允许您通过 StubWithCallback 变体为模拟函数提供回调。 StubWithCallback 除了进行特殊检查外,还允许您手动验证每个调用。您将能够利用 StubWithCallback 来记录函数被调用的次数,或者您能想到的几乎任何其他东西。您还可以使用 StubWithCallback 来满足您对时间、 sleep 等的需求。您可以使用不同的 stub 回调模拟单个调用——一些线程将以一个立即返回的 stub sleep 回调开始,而您指定用于测试的线程可以使用执行完整 sleep 的 stub sleep 回调。

您可以在此处找到有关 CMock 的更多信息:http://throwtheswitch.org/white-papers/cmock-intro.html

关于c++ - 用于集成测试的模拟库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21376939/

相关文章:

c++ - Mingw 'std::function' 还没有声明?

c++ - 便于调试的编码

c++ - 如果我在 C++ 中使用堆,我做错了什么吗?

c - 在 C 中解析 CSV 文件

testing - 使用 Jest 进行测试时模拟 native 模块

html - 棱 Angular 分明。从 html 标记中删除属性的构建步骤

c++ - FreeType OpenGL 动态文本 = 糟糕的性能

c - 如何在 C 中对 int* 指针使用 free 函数

R: test_that 多个对象是否相等

c - C语言如何读取包含空格的字符串