对C语言代码进行单元测试 [已关闭]
对C语言代码进行单元测试 [已关闭]
已关闭。 这个问题不符合 Stack Overflow 的指导方针。它目前无法接受回答。
我们不允许发问寻求书籍、工具、软件库等建议。您可以编辑问题,使其可以用事实和引文回答。
社区已评估是否重新开放此问题 1年前,并将其保持关闭:
原关闭原因尚未解决
我在这个暑假中负责一个纯 C 写的嵌入式系统。 这是一个已经存在的项目,公司拥有。 我已经习惯了使用 JUnit 在 Java 中编写单元测试,但是对于对现有代码(需要重构)以及添加到系统中的新代码编写单元测试的最佳方法感到困惑。
有没有像JUnit对Java代码进行单元测试那样,对普通的C代码进行单元测试的项目? 如果能专门针对嵌入式开发(交叉编译到arm-linux平台)提供建议,将不胜感激。
个人而言,我喜欢使用Google Test框架。
在测试C代码时,真正的困难在于打破对外部模块的依赖,以便将代码分离成单元进行测试。当您尝试在旧代码中添加测试时,这可能会特别棘手。在这种情况下,我通常使用链接器在测试中使用存根函数。
当人们谈论 "接口" 时,指的是这样一种情况。在C中,您唯一的选择是使用预处理器或链接器来模拟您的依赖项。
我的一个C项目中典型的测试套件可能如下所示:
#include "myimplementationfile.c" #include// 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和操作系统来收集结果。对于不太丰富的环境(我将其归类为不具有完整操作系统的任何内容),您应该在主机上构建和运行。您应该这样做,以便在构建的一部分中自动运行测试。
我发现测试C++代码通常更容易,这是由于面向对象的代码通常比过程化代码耦合性小得多(当然这在很大程度上取决于编码风格)。此外,在C++中,您可以使用诸如依赖注入和方法重写的技巧来将接口注入到以其他方式封装的代码中。
迈克尔·菲瑟斯(Michael Feathers)有一本关于测试遗留代码的优秀书籍。 在其中一章中,他涵盖了处理非OO代码的技术,我强烈推荐。
编辑:我写了一篇关于单元测试程序代码的博客文章,并提供在GitHub上可用的源代码。
编辑:有一本由实用程序员出版的新书,专门针对C代码进行单元测试,我强烈推荐。
C语言中的一个单元测试框架是Check;这里有一份C语言中的单元测试框架清单,以下内容为复制品。根据您的运行时所具有的标准库函数数量,您可能能否使用其中之一。
AceUnit
AceUnit (Advanced C and Embedded Unit) 提供了舒适的C代码单元测试框架。它试图模仿JUnit 4.x并包括类似于反射的功能。AceUnit可以用于资源受限的环境中,例如嵌入式软件开发,而且它可以在无法包括任何标准头文件和调用ANSI/ISO C库中的任何标准C函数的环境中正常运行。它也有一个Windows移植版。它不使用fork来捕获信号,但作者已经表示有兴趣添加此功能。请参见AceUnit主页。
GNU Autounit
与Check基本相同,包括在单独的地址空间中运行单元测试的fork(事实上,Check的原始作者从GNU Autounit借鉴了这个想法)。GNU Autounit广泛使用GLib,这意味着需要特殊选项来进行链接等操作,但这可能对您不是大问题,特别是如果您已经在使用GTK或GLib。请参见GNU Autounit主页。
cUnit
也使用GLib,但不使用fork来保护单元测试的地址空间。
CUnit
标准的C语言单元测试框架,计划实现Win32 GUI界面,目前不支持fork或者保护单元测试的地址空间。处于早期开发阶段。请访问CUnit主页。
CuTest
一个简单的单元测试框架,包含一个.c和一个.h文件,只需将它们放入您的源码目录中即可。请访问 CuTest 主页 。
CppUnit
C++的主要单元测试框架;您也可以使用它来测试C代码。它是稳定的,活跃地开发中,并且带有GUI界面。不使用CppUnit进行C测试的主要原因是它相当大,而且您必须使用C++编译器编写测试,这意味着您需要一个C++编译器。如果这些不是您的顾虑,那么一定要考虑CppUnit以及其他C++单元测试框架。请访问 CppUnit 主页 。
embUnit
embUnit(嵌入式单元)是另一个嵌入式系统的单元测试框架。这个框架似乎已被AceUnit取代。请访问 嵌入式 Unit 主页 。
MinUnit
最小化的一套宏,仅此而已!它的目的是展示单元测试您的代码是多么容易。请访问 MinUnit 主页 。
CUnit for Mr. Ando
一种相当新的CUnit实现,显然仍处于早期开发阶段。请访问 CUnit for Mr. Ando 主页 。
此列表最近更新于2008年3月。
更多框架:
CMocka
CMocka是一个支持mock对象的C语言测试框架。它易于使用和设置。
请查看CMocka主页了解更多。
Criterion
Criterion是一个跨平台的C单元测试框架,支持自动测试注册、参数化测试、理论测试,并且可以输出多种格式,包括TAP和JUnit XML。每个测试都在自己的进程中运行,因此如果需要,可以报告或测试信号和崩溃。
请查看Criterion主页了解更多信息。
HWUT
HWUT是一个通用的单元测试工具,对C语言有很好的支持。它可以帮助创建Makefiles,生成被编码在最小“迭代表”中的大量测试用例,沿着状态机行走,生成C存根等。通常的方法是非常独特的:判定结果基于“好的标准输出/坏的标准输出”。尽管比较函数是灵活的,任何类型的脚本都可以用于检查。它适用于任何可以产生标准输出的语言。
请查看HWUT主页。
CGreen
CGreen是一个现代的、便携的、跨语言的C和C++单元测试和mock框架。它提供了一个可选的BDD符号、一个mock库,以及在单个进程中运行它(以方便调试)。可用的测试运行器自动发现测试函数。但是,您可以编程创建自己的测试运行器。
所有这些功能(以及更多)在CGreen手册中有详细解释。
维基百科在单位测试框架列表:C下提供了C语言单元测试框架的详细列表。