今年夏天,我开发了一个用纯c语言编写的嵌入式系统。这是我所在公司接管的一个现有项目。我已经非常习惯使用JUnit在Java中编写单元测试,但不知道为现有代码(需要重构)和添加到系统中的新代码编写单元测试的最佳方法是什么。

有什么项目可以让单元测试纯C代码像使用JUnit测试Java代码一样简单吗?任何特别适用于嵌入式开发(交叉编译到arm-linux平台)的见解都将非常感谢。


当前回答

在开始寻找模拟函数的方法之前,我还没有深入测试遗留的C应用程序。我非常需要mock来将我想测试的C文件与其他C文件隔离开来。我试过cmock,我想我会采用它。

Cmock扫描头文件,并根据它找到的原型生成模拟函数。mock将允许您在完全隔离的情况下测试C文件。您所要做的就是将您的测试文件链接到模拟对象,而不是真正的对象文件。

cmock的另一个优点是,它将验证传递给模拟函数的参数,并允许您指定模拟函数应该提供的返回值。这对于在函数中测试不同的执行流非常有用。

测试由典型的testA()、testB()函数组成,您可以在其中构建期望、调用函数来测试和检查断言。

最后一步是为unity的测试生成一个运行器。Cmock绑定到统一测试框架。Unity和其他单元测试框架一样容易学习。

很值得一试,而且很容易掌握:

http://sourceforge.net/apps/trac/cmock/wiki

更新1

我正在研究的另一个框架是cmock。

http://code.google.com/p/cmockery/

它是一个支持单元测试和模拟的纯C框架。它不依赖于ruby(与Cmock相反),也很少依赖于外部库。

它需要更多的手工工作来设置模拟,因为它不生成代码。这并不代表现有项目的大量工作,因为原型不会有太大的变化:一旦有了mock,就暂时不需要更改它们(这是我的例子)。额外的类型提供了对模拟的完全控制。如果有什么你不喜欢的,你只需改变你的mock。

不需要特别的测试人员。您只需要创建一个测试数组,并将其传递给run_tests函数。这里也有更多的手工工作,但我绝对喜欢自包含自治框架的想法。

此外,它还包含了一些我不知道的漂亮的C技巧。

总的来说,cmock需要对mock有更多的理解才能开始。例子可以帮助你克服这个问题。看起来它可以用更简单的机制来完成这项工作。

其他回答

如果你还在寻找测试框架,CUnitWin32是Win32/NT平台的一个。

这解决了我在其他测试框架中遇到的一个基本问题。也就是说,全局/静态变量处于确定性状态,因为每个测试都是作为单独的进程执行的。

除了我明显的偏见

http://code.google.com/p/seatest/

是一个很好的简单的方法来单元测试C代码。模仿xUnit

CppUTest—强烈推荐用于单元测试C代码的框架。

书中提到的嵌入式C线程TDD中的示例是使用CppUTest编写的。

尝试lcut !- http://code.google.com/p/lcut

您可能还想看看libtap,这是一个输出任何测试协议(TAP)的C测试框架,因此可以很好地与用于该技术的各种工具集成。它主要用于动态语言领域,但它易于使用,并且变得非常流行。

一个例子:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}