【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
今年夏天,我用直接C编写了一个嵌入式系统。这是我工作的公司接管的现有项目。 我已经习惯于使用JUnit在Java中编写单元测试,但是对于为现有代码(需要重构)编写单元测试的最佳方法以及添加到系统中的新代码感到茫然。
是否有任何项目使单元测试普通C代码与使用JUnit进行单元测试Java代码一样简单? 任何专门针对嵌入式开发(交叉编译到arm-linux平台)的见解都将非常感激。
#1楼
我个人喜欢Google Test框架 。
测试C代码的真正困难在于打破了对外部模块的依赖性,因此您可以将代码单独隔离。 当您尝试围绕遗留代码进行测试时,这可能会特别成问题。 在这种情况下,我经常发现自己使用链接器在测试中使用存根函数。
这是人们在谈论“ 接缝 ”时所指的。 在C中,您唯一的选择就是使用预处理器或链接器来模拟您的依赖项。
我的一个C项目中的典型测试套件可能如下所示:
#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 ++中,您可以使用依赖注入和方法覆盖等技巧将接缝转换为以其他方式封装的代码。
Michael Feathers有一本关于测试遗留代码的优秀书籍 。 在一章中,他介绍了处理非面向对象代码的技巧,我强烈推荐。
编辑 :我写了一篇关于单元测试程序代码的博客文章 , 在GitHub上提供了源代码。
编辑 : 实用程序员出版了一本专门针对单元测试C代码的新书 , 我强烈推荐 。
#2楼
Michael Feather的书“有效地使用遗留代码”提供了许多特定于C开发期间单元测试的技术。
有一些与C相关的依赖注入相关的技术,我还没有在其他任何地方看到过。
#3楼
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月发布。
#4楼
我很惊讶没有人提到Cutter(http://cutter.sourceforge.net/)你可以测试C和C ++,它可以与autotools无缝集成,并提供了一个非常好的教程。
#5楼
如果您的目标是Win32平台或NT内核模式,您应该看一下cfix 。
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3144397