# Ceedling-CodeUnity **Repository Path**: End-ING/ceedling-code-unity ## Basic Information - **Project Name**: Ceedling-CodeUnity - **Description**: Ceedling-CodeUnity 单元测试框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-05 - **Last Updated**: 2025-12-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Ceedling MCU 传感器示例项目 ## 1. 项目概述 这是一个基于 Ceedling 框架的 C 语言测试项目,用于演示如何在 MCU(微控制器单元)环境中使用测试驱动开发(TDD)方法开发传感器相关功能。项目展示了如何使用 Unity 测试框架和 CMock 模拟库进行单元测试,特别是针对依赖硬件接口的代码。 ### 1.1 主要功能 - 传感器初始化功能 - 传感器数据读取功能 - 基本的加法运算功能(用于演示) - 完整的单元测试示例 - 批量模块创建和删除功能 - 可视化测试工具 ### 1.2 技术栈 - **Ceedling** - 1.0.1:C 语言的测试中心化构建系统 - **Unity**:C 语言的单元测试框架 - **CMock**:C 语言的模拟库,用于模拟硬件接口 ## 2. 项目结构 ``` ceedling-mcu-sensor-example/ ├── build/ # 构建输出目录 │ ├── artifacts/ # 构建产物 │ ├── logs/ # 日志文件 │ ├── test/ # 测试相关构建输出 │ └── vendor/ # 第三方库(Unity、CMock) ├── Makefile # 项目构建脚本 ├── MOCK_USAGE_GUIDE.md # Mock 使用指南 ├── project.yml # Ceedling 项目配置文件 ├── README.md # 项目说明文档 ├── src/ # 源代码目录 │ ├── add.c # 加法函数实现 │ ├── add.h # 加法函数头文件 │ ├── bsp_i2c.h # I2C 板级支持包接口 │ ├── sensor.c # 传感器功能实现 │ └── sensor.h # 传感器功能头文件 ├── test/ # 测试代码目录 │ ├── support/ # 测试支持文件 │ ├── test_add.c # 加法函数测试 │ └── test_sensor.c # 传感器功能测试 └── UNITY_MOCK_USAGE.md # Unity 与 CMock 使用详解 ``` ## 3. 核心功能说明 ### 3.1 传感器模块(sensor.c/sensor.h) 传感器模块提供了与硬件传感器交互的高层接口,封装了底层 I2C 通信细节。 #### 3.1.1 主要函数 ```c int sensor_init(void); ``` - **功能**:初始化传感器 - **返回值**:0 表示成功,其他值表示失败 - **实现**:调用 `bsp_i2c_init()` 进行 I2C 初始化 ```c int sensor_read_data(uint8_t address, uint8_t reg_addr, uint8_t *data, uint16_t len); ``` - **功能**:从传感器读取数据 - **参数**: - `address`:传感器 I2C 地址 - `reg_addr`:寄存器地址 - `data`:数据缓冲区指针 - `len`:数据长度 - **返回值**:0 表示成功,其他值表示失败 - **实现**:调用 `bsp_i2c_read()` 进行 I2C 读取操作 ### 3.2 I2C 板级支持包(bsp_i2c.h) 定义了底层 I2C 通信的接口,实际实现通常由硬件平台提供。在本项目中,该文件仅包含接口声明,没有实现,通过 CMock 进行模拟。 #### 3.2.1 主要函数 ```c int bsp_i2c_init(void); ``` - **功能**:初始化 I2C 总线 - **返回值**:0 表示成功,其他值表示失败 ```c int bsp_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len); ``` - **功能**:从 I2C 设备读取数据 - **参数**: - `dev_addr`:设备 I2C 地址 - `reg_addr`:寄存器地址 - `data`:数据缓冲区指针 - `len`:数据长度 - **返回值**:0 表示成功,其他值表示失败 ### 3.3 加法模块(add.c/add.h) 提供了简单的加法运算功能,用于演示基本的单元测试方法。 #### 3.3.1 主要函数 ```c int add(int a, int b); ``` - **功能**:计算两个整数的和 - **参数**: - `a`:第一个整数 - `b`:第二个整数 - **返回值**:两个整数的和 ## 4. 测试框架与用例 ### 4.1 测试框架配置 项目使用 Ceedling 作为构建和测试系统,配置文件为 `project.yml`。主要配置包括: - Ceedling 版本:1.0.1 - 启用 Mock 功能 - Unity 测试框架配置 - CMock 模拟库配置 - 测试和源代码路径 ### 4.2 传感器模块测试(test_sensor.c) 传感器模块测试展示了如何使用 CMock 模拟硬件接口,并测试传感器功能的各种场景。 #### 4.2.1 测试用例 1. **test_sensor_init**:测试传感器初始化功能,验证不同返回值的处理 2. **test_sensor_init_ignore**:测试忽略某些调用的场景 3. **test_sensor_read_data_ret**:测试数据读取的返回值处理 4. **test_sensor_read_data_content**:测试数据读取的内容验证 5. **test_sensor_read_data_callback**:测试使用回调函数的场景 #### 4.2.2 Mock 技术应用 - 模拟 `bsp_i2c_init()` 函数的返回值 - 模拟 `bsp_i2c_read()` 函数的行为和返回数据 - 使用回调函数自定义模拟行为 #### 4.2.3 详细使用说明 关于 Unity 框架与 CMock 结合使用的详细说明,请参考 [UNITY_MOCK_USAGE.md](UNITY_MOCK_USAGE.md) 文件。该文档详细介绍了: - Unity 断言宏的使用 - CMock 自动生成的 Mock 功能 - test_sensor.c 中的 Mock 功能应用示例 - 测试运行机制和最佳实践 ### 4.3 加法模块测试(test_add.c) 加法模块测试展示了基本的单元测试方法。 #### 4.3.1 测试用例 1. **test_add_NeedToImplement**:测试加法函数的基本功能 ## 5. 项目使用方法 ### 5.1 安装依赖 确保已安装 Ruby 和 Ceedling: ```bash gem install ceedling ``` ### 5.2 运行测试 在项目根目录下运行: ```bash ceedling test:all ``` ### 5.3 使用 Makefile 项目提供了一个简化的 Makefile 来方便地执行测试、生成报告以及管理模块。以下是可用的命令: #### 5.3.1 显示帮助信息 ```bash make ``` - 显示所有可用的 Makefile 命令 - 适合快速了解项目支持的操作 #### 5.3.2 运行所有测试 ```bash make test ``` - 等价于 `ceedling test:all` - 运行项目中所有的测试用例 - 包含 sensor 和 add 模块的测试 #### 5.3.3 运行指定测试 ```bash make test_xxx ``` - 其中 `xxx` 是测试文件名(不包含 `.c` 扩展名) - 例如:`make test_sensor` 仅运行传感器相关测试 - 例如:`make test_add` 仅运行加法功能相关测试 #### 5.3.4 清理测试产物 ```bash make test_clean ``` - 等价于 `ceedling clean` - 删除所有测试过程中生成的中间文件和构建产物 - 适合在测试环境出现问题时重新开始 #### 5.3.5 生成覆盖率报告(全部测试) ```bash make test_gcov ``` - 等价于 `ceedling gcov:all` - 运行所有测试并生成代码覆盖率报告 - 覆盖率报告位于 `build/artifacts/gcov/gcovr` 目录 - 包含 HTML 格式的详细覆盖率信息 #### 5.3.6 生成单个测试的覆盖率报告 ```bash make test_gcov_xxx ``` 该命令会生成指定测试的覆盖率报告,其中`xxx`是测试文件的名称(不包含`.c`扩展名)。例如: ```bash make test_gcov_sensor # 生成sensor测试的覆盖率报告 make test_gcov_add # 生成add测试的覆盖率报告 ``` 覆盖率报告同样位于 `build/artifacts/gcov/gcovr` 目录下。 #### 5.3.7 创建新模块 ```bash make create_xxx ``` - 创建新的模块,包括源文件、头文件和测试文件 - 其中 `xxx` 是模块名称 - 例如:`make create_new_module` 会创建: - `src/new_module.h`:模块头文件 - `src/new_module.c`:模块源文件 - `test/test_new_module.c`:模块测试文件 - 自动生成标准化的文件结构和基本函数框架 #### 5.3.8 批量创建多个模块 ```bash make create_multiple MODULES="module1 module2 module3" ``` - 一次性创建多个模块 - 使用空格分隔多个模块名称 - 自动为每个模块生成源文件、头文件和测试文件 - 生成标准化的文件结构和基本函数框架 #### 5.3.9 删除模块 ```bash make del_xxx ``` - 删除指定模块的源文件、头文件和测试文件 - 其中 `xxx` 是模块名称 - 例如:`make del_old_module` 会删除: - `src/old_module.h`:模块头文件 - `src/old_module.c`:模块源文件 - `test/test_old_module.c`:模块测试文件 #### 5.3.10 批量删除多个模块 ```bash make del_multiple MODULES="module1 module2 module3" ``` - 一次性删除多个模块 - 使用空格分隔多个模块名称 - 自动删除每个模块的源文件、头文件和测试文件 #### 5.3.11 列出所有测试文件 ```bash make testlist ``` - 列出项目中所有可用的测试文件 - 显示测试文件的详细信息,包括修改时间和大小 - 方便查看当前项目中有哪些测试可以运行 #### 5.3.12 运行可视化测试工具 ```bash make gui ``` - 启动基于Python Tkinter的可视化测试工具 - 提供图形界面,方便执行各种测试操作 ### 5.4 测试结果 运行测试后,将看到类似以下输出: ``` ----------- TEST OUTPUT ----------- [test/test_sensor.c] - "dev_addr:96, reg_addr:3, len:5, cmock_num_calls:0" - "dev_addr:96, reg_addr:4, len:5, cmock_num_calls:1" -------------------- OVERALL TEST SUMMARY -------------------- TESTED: 6 PASSED: 6 FAILED: 0 IGNORED: 0 ``` ### 5.5 查看覆盖率报告 生成覆盖率报告后,可以通过以下方式查看: 1. 打开 `build/artifacts/gcov/gcovr/index.html` 文件 2. 在浏览器中查看代码覆盖率的详细信息 3. 报告显示每个源文件的行覆盖率和函数覆盖率 ### 5.6 示例命令使用 ```bash # 显示帮助信息 make # 运行所有测试 make test # 仅运行传感器测试 make test_sensor # 仅运行加法功能测试 make test_add # 清理测试产物 make test_clean # 生成所有测试的覆盖率报告 make test_gcov # 生成传感器测试的覆盖率报告 make test_gcov_sensor # 创建新模块 make create_new_module # 批量创建多个模块 make create_multiple MODULES="mod1 mod2 mod3" # 删除模块 make del_old_module # 批量删除多个模块 make del_multiple MODULES="mod1 mod2 mod3" # 运行可视化测试工具 make gui ``` ## 6. 可视化测试工具 项目提供了一个基于Python Tkinter的可视化测试工具,用于替代命令行操作,提供更友好的图形界面。 ### 6.1 功能特性 - **运行所有测试**:一键执行项目中所有的测试用例 - **运行指定测试**:输入测试名称,仅运行特定的测试用例 - **清理测试产物**:删除所有测试过程中生成的中间文件和构建产物 - **生成覆盖率报告**:运行测试并生成代码覆盖率报告 - **打开覆盖率报告**:在浏览器中查看HTML格式的覆盖率报告 - **实时输出显示**:在界面中实时显示测试执行的输出信息 ### 6.2 使用方法 1. 确保已安装Python 3.x(项目使用Tkinter,通常Python标准库已包含) 2. 在项目根目录下运行: ```bash python test_gui.py ``` 3. 在弹出的界面中,点击相应的按钮执行所需操作 ### 6.3 界面说明 - **标题栏**:显示工具名称"Ceedling测试可视化工具" - **按钮区域**:包含运行测试、清理测试、生成报告等功能按钮 - **测试名称输入框**:用于输入要运行的特定测试名称 - **输出区域**:实时显示命令执行的输出信息 - **状态栏**:显示当前操作的状态信息 ### 6.4 操作示例 1. **运行所有测试**:点击"运行所有测试"按钮 2. **运行特定测试**:在"测试名称"输入框中输入"sensor",然后点击"运行指定测试"按钮 3. **清理测试产物**:点击"清理测试产物"按钮 4. **生成并查看全部测试覆盖率报告**:点击"生成覆盖率报告(全部)"按钮,然后点击"打开覆盖率报告"按钮 5. **生成并查看单个测试覆盖率报告**:在"测试名称"输入框中输入"sensor",然后点击"生成覆盖率报告(单个)"按钮,最后点击"打开覆盖率报告"按钮查看 可视化工具为用户提供了更直观、更便捷的操作方式,特别适合不熟悉命令行操作的用户。 ## 7. 扩展与定制 ### 7.1 添加新功能 #### 使用命令行创建新模块(推荐) 1. 使用 `make create_xxx` 命令创建新模块(如 `make create_new_feature`) 2. 该命令会自动创建: - `src/new_feature.h`:模块头文件 - `src/new_feature.c`:模块源文件 - `test/test_new_feature.c`:模块测试文件 3. 在生成的文件中实现具体功能 4. 更新测试用例,添加适当的断言 5. 运行测试验证功能 #### 手动创建新模块 1. 在 `src/` 目录下创建新的源文件和头文件 2. 在 `test/` 目录下创建对应的测试文件 3. 更新 `project.yml` 中的路径配置(如果需要) 4. 运行测试验证功能 #### 批量添加多个功能模块 1. 使用 `make create_multiple MODULES="module1 module2 module3"` 命令 2. 为每个生成的模块实现具体功能 3. 更新测试用例 4. 运行测试验证功能 ### 7.2 定制测试 - 修改 `project.yml` 中的 CMock 配置以调整模拟行为 - 使用 Unity 的断言宏扩展测试覆盖范围 - 利用 CMock 的插件功能增强模拟能力 ## 8. 最佳实践 ### 8.1 测试驱动开发(TDD)流程 1. **编写测试**:首先编写失败的测试用例,定义所需的功能 2. **运行测试**:验证测试确实失败(红色) 3. **编写代码**:实现最少量的代码使测试通过(绿色) 4. **重构代码**:优化代码结构,保持测试通过 5. **重复**:为新功能或边缘情况重复上述步骤 ### 8.2 Mock 使用建议 - 仅模拟外部依赖(如硬件接口、操作系统 API) - 不要模拟同一模块内的函数 - 使用 CMock 的回调功能处理复杂的模拟行为 - 为模拟函数设置合理的默认返回值 ### 8.3 测试文件命名规范 - 测试文件以 `test_` 开头,后跟被测试模块的名称 - 测试函数以 `test_` 开头,后跟被测试功能的描述 - 使用下划线分隔单词,提高可读性 ## 9. 常见问题与解决方案 ### 9.1 测试失败 - **问题**:测试运行失败,显示断言错误 - **解决方案**: 1. 检查测试用例中的期望结果是否正确 2. 检查被测试函数的实现是否符合预期 3. 查看测试输出中的详细信息,定位问题所在 ### 9.2 Mock 函数未被调用 - **问题**:测试显示 Mock 函数未被调用 - **解决方案**: 1. 检查被测试函数是否正确调用了 Mock 函数 2. 检查 Mock 函数的名称是否与预期一致 3. 确保测试用例中没有忽略该 Mock 函数的调用 ### 9.3 覆盖率报告生成失败 - **问题**:运行 `make test_gcov` 后没有生成覆盖率报告 - **解决方案**: 1. 确保已安装 gcov 和 gcovr 工具 2. 检查 `project.yml` 中的覆盖率配置是否正确 3. 先运行 `make test_clean` 清理旧的构建产物,然后重新运行测试 ## 10. 总结 本项目展示了如何在 MCU 环境中使用 Ceedling、Unity 和 CMock 进行测试驱动开发。通过模拟硬件接口,开发人员可以在没有实际硬件的情况下测试代码逻辑,提高代码质量和可靠性。项目提供了完整的示例,包括传感器功能的实现和测试,可以作为 MCU 项目测试的参考模板。 ## 11. 注意事项 - 项目中的 `bsp_i2c.h` 仅包含接口声明,没有实际实现,需要根据目标硬件平台提供实现 - 测试文件中使用了 `#ifdef TEST` 条件编译,确保测试代码不会被包含在最终产品中 - 项目使用了中文注释,便于中文开发者理解 ## 12. 许可证 本项目基于 MIT 许可证开源,详细信息请参考项目中的 LICENSE 文件。