unittest

单元测试也称为白盒测试,是一种对程序模块进行正确性检验的测试方法。

方案对比

测试方案优点缺点适用场景
直接写测试代码1. 简单直接,无需额外库或框架1. 测试代码和主代码混杂,难以维护1. 小型项目
2. 快速验证功能或修复bug2. 测试覆盖率难以保证2. 快速原型开发
3. 重复代码多,不利于复用3. 临时验证
assert1. 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在新窗口打开
CTestCTest是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__是预处理宏,表示当前文件名。放在头文件中,在编译时会被替换为对应的文件名。