今年夏天,我开发了一个用纯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有更多的理解才能开始。例子可以帮助你克服这个问题。看起来它可以用更简单的机制来完成这项工作。

其他回答

API完整性检查器- C/ c++库的测试框架:

An automatic generator of basic unit tests for a shared C/C++ library. It is able to generate reasonable (in most, but unfortunately not all, cases) input data for parameters and compose simple ("sanity" or "shallow"-quality) test cases for every function in the API through the analysis of declarations in header files. The quality of generated tests allows to check absence of critical errors in simple use cases. The tool is able to build and execute generated tests and detect crashes (segfaults), aborts, all kinds of emitted signals, non-zero program return code and program hanging.

例子:

fontconfig 2.8.0测试套件 FreeType 2.4.8的测试套件

首先,看看这里:http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

我的公司有一个客户使用的C库。我们使用CxxTest(一个c++单元测试库)来测试代码。CppUnit也可以工作。如果你被C卡住了,我推荐RCUNIT(但CUnit也很好)。

Minunit是一个非常简单的单元测试框架。 我用它来单元测试c微控制器代码avr。

LibU (http://koanlogic.com/libu)有一个单元测试模块,允许显式测试套件/用例依赖、测试隔离、并行执行和可定制的报告格式化器(默认格式是xml和txt)。

这个库是BSD许可的,包含许多其他有用的模块——网络、调试、常用的数据结构、配置等等——如果你的项目需要它们的话……

我不使用框架,我只是使用自动工具“检查”目标支持。实现一个“main”并使用assert。

我的测试目录Makefile.am(s)看起来像这样:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp