3. 搭建测试环境:在Linux/Windows上安装CUnit、配置CMake项目集成测试框架
好,咱们进入第三章。说实话,搭建环境这事儿,看着简单,但坑是真不少。我见过太多人卡在第一步——库装不上、链接报错、CMake找不到包……折腾半天,代码一行没写,心态先崩了。
这一章,我就带你手把手把环境搭起来。咱们的目标很明确:在Linux和Windows上都能跑CUnit,并且用CMake把测试框架集成到项目里。以后你写单元测试,只需要一条命令,全部搞定。
3.1 为什么选CUnit?
C语言单元测试框架不少,比如Check、Unity、Criterion。我个人习惯用CUnit,原因有三:
- 轻量——就几个源文件,编译快,不依赖第三方库
- 稳定——我在好几个嵌入式项目里用过,没出过幺蛾子
- API直观——学过C的人,看两眼就能上手
当然,如果你项目里已经有别的框架,也没问题。但如果你是第一次接触C语言单元测试,我建议从CUnit开始。你想想看,框架本身都搞不定,后面写测试用例就更没信心了。
3.2 在Linux上安装CUnit
Linux下安装CUnit,最省事的方式是用包管理器。我用的Ubuntu,一条命令搞定:
sudo apt-get install libcunit1 libcunit1-doc libcunit1-dev
装完之后,验证一下:
dpkg -l | grep libcunit
如果看到类似 libcunit1-dev 的包名,说明装上了。
yum install cunit cunit-devel 或者 dnf install cunit cunit-devel。
那如果服务器不能联网呢?我曾经在一个内网项目里就遇到过这情况。别慌,手动编译也简单:
- 去 CUnit官网 下载源码包(比如
CUnit-2.1-3.tar.bz2) - 解压:
tar -xjf CUnit-2.1-3.tar.bz2 - 进入目录,标准三步走:
./configure
make
sudo make install
默认会装到 /usr/local/lib 和 /usr/local/include。如果你想让CMake能找到它,记得把路径加到环境变量里。
3.3 在Windows上安装CUnit
Windows下稍微麻烦一点。我建议用vcpkg来管理,省心:
vcpkg install cunit
如果你不用vcpkg,也可以手动编译。用Visual Studio打开源码里的 .sln 文件,直接生成。嗯,这里要注意:CUnit的源码里自带VS工程文件,但版本可能比较老。我试过用VS2022打开,需要升级一下工程格式,问题不大。
d 后缀,CMake找库的时候容易搞混。我踩过这个坑,排查了半天才发现是库文件不匹配。
3.4 用CMake集成CUnit
环境装好了,接下来就是集成到项目里。我习惯用CMake,跨平台,方便。
假设你的项目结构是这样的:
my_project/
├── CMakeLists.txt
├── src/
│ ├── calculator.c
│ └── calculator.h
└── tests/
├── CMakeLists.txt
└── test_calculator.c
根目录的 CMakeLists.txt 这样写:
cmake_minimum_required(VERSION 3.10)
project(MyProject C)
# 开启测试
enable_testing()
# 添加子目录
add_subdirectory(src)
add_subdirectory(tests)
然后在 tests/CMakeLists.txt 里,找到CUnit库并链接:
# 查找CUnit库
find_package(CUnit REQUIRED)
# 添加测试可执行文件
add_executable(test_calculator test_calculator.c)
# 链接CUnit
target_link_libraries(test_calculator PRIVATE CUnit::cunit)
# 注册测试
add_test(NAME test_calculator COMMAND test_calculator)
这里有个关键点:find_package(CUnit REQUIRED) 能不能找到库,取决于CUnit是否提供了 FindCUnit.cmake 模块。如果系统没自带,你可以自己写一个,或者直接用 find_library 和 find_path 手动指定路径。
3.5 验证环境是否搭好
环境搭没搭好,跑个例子就知道了。写一个最简单的测试:
#include <CUnit/CUnit.h>
#include <CUnit/Basic.h>
void test_example(void) {
CU_ASSERT(1 + 1 == 2);
}
int main() {
CU_initialize_registry();
CU_pSuite suite = CU_add_suite("demo_suite", NULL, NULL);
CU_add_test(suite, "test_example", test_example);
CU_basic_run_tests();
CU_cleanup_registry();
return 0;
}
编译运行:
mkdir build && cd build
cmake ..
make
./tests/test_calculator
如果看到类似 Run Summary: 1 run, 1 assertion, 0 failures 的输出,恭喜你,环境搭好了!
3.6 知识体系总览
这一章的内容,说白了就是三件事:装库、配CMake、跑通第一个测试。我画了个图,帮你理清整体逻辑:
3.7 避坑指南
最后,分享几个我实际踩过的坑:
- 链接报错 undefined reference:八成是库路径没配对。检查一下
CMAKE_PREFIX_PATH或者LD_LIBRARY_PATH。 - CMake找不到CUnit:试试手动指定
set(CUnit_DIR /path/to/cunit/cmake)。 - Windows下编译CUnit报错:可能是字符集问题。在源码里加一句
#define _CRT_SECURE_NO_WARNINGS就能解决。
我曾经在一个项目里,因为CUnit版本太老,导致 CU_initialize_registry 返回非零值,查了半天才发现是库和头文件版本不一致。所以,装库之前,先看看版本号。
环境搭好了,下一章咱们就开始写真正的测试用例。到时候你会发现,前面这些折腾,都是值得的。
公众号:蓝海资料掘金营,微信deep3321