unittest
单元测试也称为白盒测试,是一种对程序模块进行正确性检验的测试方法。
方案对比
测试方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
直接写测试代码 | 1. 简单直接,无需额外库或框架 | 1. 测试代码和主代码混杂,难以维护 | 1. 小型项目 |
2. 快速验证功能或修复bug | 2. 测试覆盖率难以保证 | 2. 快速原型开发 | |
3. 重复代码多,不利于复用 | 3. 临时验证 | ||
assert | 1. C语言标准库支持,使用简单 | 1. 主要用于调试,发布时通常关闭 | 1. 调试阶段 |
2. 能在开发和调试阶段捕获逻辑错误 | 2. 不适合作为长期测试方案 | 2. 快速检查代码中的假设条件 | |
3. 无需编写额外测试函数 | 3. 复杂逻辑支持不足 | ||
单元测试框架 | 1. 测试代码和主代码分离,结构清晰 | 1. 需要引入额外库或框架,增加复杂性 | 1. 中大型项目 |
2. 提供丰富的断言和测试工具 | 2. 可能需要额外学习成本 | 2. 高测试覆盖率需求 | |
3. 支持复杂的测试逻辑和场景 | 3. 框架可能具有自己的限制和约定 | 3. 自动化测试和回归测试 | |
4. 易于与持续集成工具集成 | 4. 需要长期维护和测试保证的项目 | ||
5. 提高代码质量和稳定性 |
单元测试框架
框架名称 | 特点 | 适用场景 | 源码 |
---|---|---|---|
Unity | 小型且开源(MIT) | 非常适合资源受限的环境,如嵌入式系统 | Unity |
Google Test | - Google推出的C++测试框架,但支持C语言 - 跨平台,具有丰富的断言库和Mocks - 支持复杂的测试场景和集成测试 | 适用于大型项目和需要高度自定义测试的场景 | Google Test |
CUnit | 由NASA开发,支持自动化测试和手动测试 | 适用于PC软件,特别是需要标准C语言测试的场景 | CUnit |
Check | - 轻量级的C单元测试框架 - 基于TAP(测试任意语言)设计理念 - 支持测试套件、测试用例的管理,便于维护测试组件 | 适用于需要灵活测试框架和详细失败消息的场景 | Check |
MinUnit | - 非常小型的单元测试框架 - 编译时不占用额外内存 - 非常适合资源极其受限的环境 | 适用于小型项目或需要最小化资源占用的场景 | MinUnit |
ctest | 轻量级C语言测试框架,支持断言和mocks | 适用于小型项目或需要最小化资源占用的场景 | ctest |
CTest | CTest是CMake的测试工具,它允许开发者在CMake配置文件中添加测试用例,非常适合与CMake一起使用的项目。 | 适用于CMake项目 | CTest |
unity
基础测试框架,简单易用。
void setUp(void)
{
// before function test
}
void tearDown(void)
{
// after function test
}
int main(int argc, char const *argv[])
{
printf("----- Unit Test -----\n");
UNITY_BEGIN();
RUN_TEST(test_stack_num);
return UNITY_END();;
}
添加配置文件
在unity_internals.h文件中添加了宏定义,方便使用unity_config.h文件。
#define UNITY_INCLUDE_CONFIG_H
多文件测试路径
问题 多文件打印测试文件,路径都显示UNITY_BEGIN
所在文件。 修改RUN_TEST
宏,先调用UnitySetTestFile(__FILE__);
函数,再调用其他。借助UnitySetTestFile
函数,实现在不同文件下的打印信息路径的切换。
#define RUN_TEST(...) RUN_TEST_AT_LINE(__VA_ARGS__, __LINE__, throwaway)
#define RUN_TEST_AT_LINE(func, line, ...) UnitySetTestFile(__FILE__);UnityDefaultTestRun(func, #func, line)
备注:__FILE__
是预处理宏,表示当前文件名。放在头文件中,在编译时会被替换为对应的文件名。