2026/5/23 14:33:37
网站建设
项目流程
高端网站建设青岛,长沙工作室网站建设,vps主机怎么建设网站,磁力搜索神器CMocka 是一款面向 C 语言的轻量级单元测试框架#xff0c;核心支持Mock 对象模拟#xff0c;特别适合嵌入式 / SOC 开发中的代码测试。核心定位它是从谷歌的 Cmockery 框架继承而来的工具#xff0c;主打 **“仅依赖标准 C 库”**#xff0c;能在 Linux、Windows、嵌入式等…CMocka 是一款面向 C 语言的轻量级单元测试框架核心支持Mock 对象模拟特别适合嵌入式 / SOC 开发中的代码测试。核心定位它是从谷歌的 Cmockery 框架继承而来的工具主打 **“仅依赖标准 C 库”**能在 Linux、Windows、嵌入式等多平台运行解决 C 代码尤其是硬件依赖型代码的 “单元测试难落地” 问题。关键功能Mock 对象模拟可以为依赖的硬件驱动、外部模块创建 “替身函数”预设函数的返回值 / 输出参数比如模拟uart_send()的成功返回无需真实串口硬件校验函数的调用次数、入参、调用顺序比如确认sensor_read()是否被正确调用。基础测试能力提供丰富的断言宏如assert_int_equal验证数值相等支持测试夹具Setup/Teardown统一管理测试的初始化 / 清理检测内存泄漏、缓冲区溢出等问题。适配嵌入式场景仅依赖标准 C 库可通过交叉编译适配嵌入式平台不使用fork()等系统调用适合资源受限的硬件环境。典型用法示例比如测试一个依赖 UART 的函数#include cmocka.h #include uart.h // 被依赖的模块 // 被测试函数调用uart_send发送错误码 void report_error(int code) { uart_send(code); } // Mock替身函数CMocka自动生成或手动定义 void uart_send(int code) { check_expected(code); // 校验入参是否符合预期 } // 测试用例 void test_report_error(void **state) { (void)state; expect_value(uart_send, code, 100); // 预设期望入参是100 report_error(100); // 执行被测试函数 } // 运行测试 int main(void) { const struct CMUnitTest tests[] { cmocka_unit_test(test_report_error), }; return cmocka_run_group_tests(tests, NULL, NULL); }优势轻量无依赖易集成到嵌入式项目同时支持单元测试和接口测试输出格式灵活支持 TAP、JUnit XML适配持续集成。一、环境准备核心依赖CMocka 仅依赖C 编译器gcc/clang/arm-none-eabi-gcc构建工具cmake 3.10 或 makeCMocka 源码推荐稳定版 1.1.5步骤 1下载 CMocka 源码# 方式1直接下载源码包推荐 wget https://cmocka.org/files/1.1/cmocka-1.1.5.tar.xz tar -xvf cmocka-1.1.5.tar.xz # 方式2git克隆最新版 git clone https://git.cryptomilk.org/projects/cmocka.git二、编译集成分 2 种场景场景 1Linux 主机测试x86/x64最快验证# 1. 进入源码目录创建编译目录 cd cmocka-1.1.5 mkdir build cd build # 2. cmake配置指定安装路径避免污染系统 cmake .. -DCMAKE_INSTALL_PREFIX/usr/local/cmocka \ -DCMAKE_BUILD_TYPERelease \ -DUNIT_TESTINGOFF # 关闭CMocka自身的单元测试 # 3. 编译安装 make -j4 sudo make install场景 2嵌入式交叉编译如 ARM Cortex-M# 1. 定义交叉编译工具链替换为你的工具链路径 export CROSS_COMPILEarm-none-eabi- export CC${CROSS_COMPILE}gcc export AR${CROSS_COMPILE}ar export STRIP${CROSS_COMPILE}strip # 2. cmake配置核心指定交叉编译 cmake .. -DCMAKE_INSTALL_PREFIX/your/project/cmocka-arm \ -DCMAKE_BUILD_TYPERelease \ -DUNIT_TESTINGOFF \ -DCMAKE_SYSTEM_NAMEGeneric \ # 无操作系统裸机 -DCMAKE_C_FLAGS-mthumb -mcpucortex-m4 # 适配你的MCU架构 # 3. 编译安装到项目目录 make -j4 make install关键说明安装后会生成头文件include/cmocka.h库文件lib/libcmocka.a静态库嵌入式优先用三、项目集成3 步接入你的代码假设你的嵌入式项目结构如下your_project/ ├── src/ # 业务代码如norflash_test.c ├── test/ # 测试代码 ├── cmocka/ # 存放CMocka的头文件库文件 └── CMakeLists.txt步骤 1复制 CMocka 文件到项目# 复制头文件 cp /usr/local/cmocka/include/cmocka.h your_project/cmocka/ # 复制静态库主机/嵌入式对应不同库 # 主机 cp /usr/local/cmocka/lib/libcmocka.a your_project/cmocka/ # 嵌入式 cp /your/project/cmocka-arm/lib/libcmocka.a your_project/cmocka/步骤 2编写 CMakeLists.txt核心cmake_minimum_required(VERSION 3.10) project(embedded_test) # 1. 引入CMocka include_directories(${PROJECT_SOURCE_DIR}/cmocka) # 头文件路径 link_directories(${PROJECT_SOURCE_DIR}/cmocka) # 库文件路径 # 2. 要测试的业务代码如norflash驱动 add_library(business_code STATIC src/norflash.c) # 3. 测试代码如test_norflash.c add_executable(norflash_test test/test_norflash.c) # 链接CMocka和业务代码 target_link_libraries(norflash_test business_code cmocka) # 嵌入式额外配置根据你的MCU调整 if(ARM_EMBEDDED) set(CMAKE_C_FLAGS -mthumb -mcpucortex-m4 -ffreestanding -nostdlib) # 链接脚本、启动文件等 target_link_libraries(norflash_test ${PROJECT_SOURCE_DIR}/src/link.ld) endif()步骤 3编写第一个测试用例示例NOR Flash 读写测试在test/test_norflash.c中#include cmocka.h #include norflash.h // 你的NOR Flash驱动头文件 // 测试夹具每个用例执行前初始化 static int setup_norflash_test(void **state) { // 模拟NOR Flash初始化无需真实硬件 norflash_init(); return 0; } // 测试夹具每个用例执行后清理 static int teardown_norflash_test(void **state) { // 模拟释放资源 norflash_deinit(); return 0; } // 测试用例1验证NOR Flash读操作 static void test_norflash_read(void **state) { uint8_t buf[4] {0}; // 调用被测函数读取地址0x0000的4字节 int ret norflash_read(0x0000, buf, 4); // 断言返回值应为0成功 assert_int_equal(ret, 0); // 断言读取的数据符合预期模拟场景可预设 assert_memory_equal(buf, (uint8_t[]){0x11, 0x22, 0x33, 0x44}, 4); } // 测试用例2验证Mock函数调用模拟写操作 static void test_norflash_write(void **state) { uint8_t data[] {0xaa, 0xbb}; // 预设期望norflash_erase被调用1次入参为0x1000 expect_value(norflash_erase, addr, 0x1000); expect_call_count(norflash_erase, 1); // 执行被测函数 norflash_write(0x1000, data, 2); // 校验norflash_erase确实被调用 check_expected_calls(); } // 注册测试用例 int main(void) { const struct CMUnitTest tests[] { cmocka_unit_test_setup_teardown(test_norflash_read, setup_norflash_test, teardown_norflash_test), cmocka_unit_test(test_norflash_write), }; // 运行所有测试 return cmocka_run_group_tests(tests, NULL, NULL); }四、运行验证场景 1Linux 主机运行# 编译测试程序 cd your_project mkdir build cd build cmake .. -DARM_EMBEDDEDOFF make -j4 # 运行测试 ./norflash_test✅ 成功输出示例[] Running 2 test(s). [ RUN ] test_norflash_read [ OK ] test_norflash_read [ RUN ] test_norflash_write [ OK ] test_norflash_write [] 2 test(s) passed.场景 2嵌入式运行裸机# 编译生成bin/hex文件 cmake .. -DARM_EMBEDDEDON make -j4 # 下载到硬件用你的烧录工具如openocd/jlink openocd -f interface/jlink.cfg -f target/stm32f4x.cfg -c program norflash_test.hex verify reset exit✅ 验证方式通过串口 / 调试器查看测试输出需在代码中适配 printf 到串口。总结核心步骤下载 CMocka → 编译主机 / 交叉编译→ 项目集成头文件 库 CMake→ 编写测试用例 → 运行验证嵌入式关键交叉编译时指定CMAKE_SYSTEM_NAMEGeneric和 MCU 架构参数用静态库libcmocka.a简化技巧新手可先在 Linux 主机完成测试验证再移植到嵌入式硬件。