今年夏天,我用直接C编写了一个嵌入式系统。这是我工做的公司接管的现有项目。 我已经习惯于使用JUnit在Java中编写单元测试,可是对于为现有代码(须要重构)编写单元测试的最佳方法以及添加到系统中的新代码感到茫然。 linux
是否有任何项目使单元测试普通C代码与使用JUnit进行单元测试Java代码同样简单? 任何专门针对嵌入式开发(交叉编译到arm-linux平台)的看法都将很是感激。 git
我我的喜欢Google Test框架 。 程序员
测试C代码的真正困难在于打破了对外部模块的依赖性,所以您能够将代码单独隔离。 当您尝试围绕遗留代码进行测试时,这可能会特别成问题。 在这种状况下,我常常发现本身使用连接器在测试中使用存根函数。 github
这是人们在谈论“ 接缝 ”时所指的。 在C中,您惟一的选择就是使用预处理器或连接器来模拟您的依赖项。 shell
个人一个C项目中的典型测试套件可能以下所示: api
#include "myimplementationfile.c" #include <gtest/gtest.h> // Mock out external dependency on mylogger.o void Logger_log(...){} TEST(FactorialTest, Zero) { EXPECT_EQ(1, Factorial(0)); }
请注意,您其实是包含C文件而不是头文件 。 这提供了访问全部静态数据成员的优点。 在这里,我模拟了个人记录器(可能在logger.o中并给出一个空实现。这意味着测试文件独立于代码库的其他部分进行编译和连接并单独执行。 架构
至于交叉编译代码,为了使它工做,你须要在目标上有良好的设施。 我已经经过googletest交叉编译到PowerPC架构上的Linux来完成此操做。 这是有道理的,由于你有一个完整的shell和os来收集你的结果。 对于不太丰富的环境(我将其归类为没有完整操做系统的任何东西),您应该只在主机上构建和运行。 不管如何你应该这样作,这样你就能够在构建过程当中自动运行测试。 框架
我发现测试C ++代码一般要容易得多,由于OO代码一般比程序更少耦合(固然这在很大程度上取决于编码风格)。 一样在C ++中,您可使用依赖注入和方法覆盖等技巧将接缝转换为以其余方式封装的代码。 wordpress
Michael Feathers有一本关于测试遗留代码的优秀书籍 。 在一章中,他介绍了处理非面向对象代码的技巧,我强烈推荐。 函数
编辑 :我写了一篇关于单元测试程序代码的博客文章 , 在GitHub上提供了源代码。
编辑 : 实用程序员出版了一本专门针对单元测试C代码的新书 , 我强烈推荐 。
Michael Feather的书“有效地使用遗留代码”提供了许多特定于C开发期间单元测试的技术。
有一些与C相关的依赖注入相关的技术,我尚未在其余任何地方看到过。
C版有一个优雅的单元测试框架,支持名为cmocka的模拟对象。 它只须要标准的C库,适用于各类计算平台(包括嵌入式)和不一样的编译器。
它还支持不一样的消息输出格式,如Subunit,Test Anything Protocol和jUnit XML报告。
cmocka已经建立,也能够在嵌入式平台上运行,而且还支持Windows。
一个简单的测试看起来像这样:
#include <stdarg.h> #include <stddef.h> #include <setjmp.h> #include <cmocka.h> /* A test case that does nothing and succeeds. */ static void null_test_success(void **state) { (void) state; /* unused */ } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(null_test_success), }; return cmocka_run_group_tests(tests, NULL, NULL); }
API已完整记录,而且几个示例是源代码的一部分。
要开始使用cmocka,您应该阅读LWN.net上的文章: 在C中使用模拟对象进行单元测试
cmocka 1.0已于2015年2月发布。
我很惊讶没有人提到Cutter(http://cutter.sourceforge.net/)你能够测试C和C ++,它能够与autotools无缝集成,并提供了一个很是好的教程。
若是您的目标是Win32平台或NT内核模式,您应该看一下cfix 。