我有一个现有的C/C++应用程序,它通过几个接口(TCP、DB、共享内存)与其他应用程序/系统通信。我想在实际环境中运行一次应用程序,并“记录”所有函数调用及其返回值(或作为参数传递给缓冲区的更改)。我将只记录与外部接口(TCP,DB)相关的调用,并使用“spy”。然后我可以再次运行该应用程序,但使用的“假”函数应该返回先前记录的值。这样我就可以“重放”一个执行,并检查结果是否与原始执行相匹配。
一个重要的特性是模拟时间函数(sleep、time、GetLocalTime),因为(例如)对DB的调用可能在selects中包含当前日期或时间。如果能够比原来的执行速度更快地“重播”所有调用,那就更好了(一天的执行可以在几分钟内重播)。例如,对sleep(1000)的调用应该在不等待的情况下返回,但是对GetLocalTime的连续调用应该多返回1秒。这应该考虑到其他线程的时间值应该是一致的(例如,库应该允许一个线程的1个睡眠调用(1000)和另一个线程的10个睡眠调用(100))。
理想情况下,它不需要对应用程序进行大量更改或重构,只需重新定义对时间函数的调用以及对外部接口(DB、TCP)库的调用。
我想知道是否存在一些实现这些特征的库或框架,或者什么是一个好的起点。
对于类似的问题,我已经实现了好几次解决方案,但是对于非常简单的模块,例如模拟TCP连接来测试协议实现,但是每次我都想重新发明轮子,而且这些简单的解决方案不能很好地适应更多线程或与更多接口的交互。

最佳答案

因为你提到你的应用程序是C/C++,所以我假设你有使用C框架的能力。我将在这个答案中讨论CMock和Unity。如果面向对象的原理在您的任务中更普遍,那么您可以查看类似于CMOCK的GoGoReMoCK,但它是针对C++开发的,并对类进行说明。
--
CMock结合Unity可以为您的测试需求提供一个框架。
CMock提供了轻松模拟公共接口的能力。例如,如果要测试以下琐碎代码:

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

可以使用CMock创建发送调用的模拟。这将允许您验证传递给发送的参数,从而验证缓冲区中的内容。您还可以验证send返回的大小。CMock模拟发送函数的ExpectAndReturn变量将允许您执行这两个验证。
CMock还允许您通过StubWithCallback变量为模拟函数提供回调。StubWithCallback允许您手动验证每个调用,此外还可以执行特殊检查。您可以利用StubWithCallback来记录函数被调用的次数,或者几乎任何您可以想象的事情。您还可以使用StubWithCallback来满足时间、睡眠等方面的需要。您可以用不同的stub回调来模拟单个调用——一些线程将以立即返回的stub睡眠回调开始,而您为测试指定的线程可以使用执行完全睡眠的stub睡眠回调。
您可以在这里找到有关CMock的更多信息:http://throwtheswitch.org/white-papers/cmock-intro.html

10-08 13:29