如何为Nginx自定义模块添加单元测试及构建check目标?
为Nginx自定义模块添加Check单元测试并集成到构建流程
我刚好折腾过给Nginx自定义模块加单元测试的事儿,用Check框架完全可行,下面一步步给你说怎么把测试集成到Nginx的构建流程里,新增check目标:
1. 先搞定Check框架的依赖
首先得确保你的系统上装了Check库和开发文件,比如在Debian/Ubuntu上:
sudo apt-get install check libcheck-dev
RHEL/CentOS的话:
sudo yum install check check-devel
2. 组织测试代码结构
在你的自定义模块目录下,新建一个tests文件夹,用来放测试相关的文件,目录结构大概是这样:
your_module/ ├── ngx_http_your_module.c ├── config └── tests/ ├── test_your_module.c └── Makefile.test
3. 编写Check测试用例
假设你的模块里有个函数ngx_http_your_module_calculate(int a, int b),我们写个简单的测试用例来验证它的逻辑:
// tests/test_your_module.c #include <check.h> #include "../../src/core/ngx_core.h" // 根据你的Nginx源码路径调整 #include "../ngx_http_your_module.c" // 引入模块核心代码 START_TEST(test_calculate) { ck_assert_int_eq(ngx_http_your_module_calculate(2, 3), 5); ck_assert_int_eq(ngx_http_your_module_calculate(-1, 1), 0); ck_assert_int_eq(ngx_http_your_module_calculate(0, 0), 0); } END_TEST Suite* your_module_suite(void) { Suite *s = suite_create("YourModule"); TCase *tc_core = tcase_create("CoreFunctions"); tcase_add_test(tc_core, test_calculate); suite_add_tcase(s, tc_core); return s; } int main(void) { int number_failed; Suite *s = your_module_suite(); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; }
4. 修改模块的config文件
在模块自带的config文件末尾,添加一段逻辑,让Nginx的构建系统能识别并执行check目标:
# 原有的模块config内容... # 新增测试相关配置逻辑 if [ "$MODULE_TEST" = "YES" ]; then TESTS_DIR=$ngx_addon_dir/tests # 配置Nginx核心头文件路径和测试编译参数 NGX_TEST_CFLAGS="-I$TESTS_DIR -I$NGX_PREFIX/src/core -I$NGX_PREFIX/src/event -I$NGX_PREFIX/src/http" # 链接Check框架及依赖库 NGX_TEST_LIBS="-lcheck -pthread -lrt -lm -lsubunit" fi # 注册check目标,关联编译和运行测试的步骤 add_custom_target check check: build_test run_test build_test: cd $TESTS_DIR && make -f Makefile.test NGX_PREFIX=$NGX_PREFIX CFLAGS="$NGX_TEST_CFLAGS" LIBS="$NGX_TEST_LIBS" run_test: cd $TESTS_DIR && ./test_your_module
5. 编写tests/Makefile.test
这个Makefile负责单独编译测试程序,不用和Nginx主构建混在一起:
NGX_PREFIX ?= ../.. # 默认指向Nginx源码根目录,可通过configure参数覆盖 CFLAGS += $(NGX_TEST_CFLAGS) -Wall -Wextra LIBS += $(NGX_TEST_LIBS) test_your_module: test_your_module.o $(CC) $(CFLAGS) -o $@ $^ $(LIBS) test_your_module.o: test_your_module.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f test_your_module *.o
6. 编译并运行测试
在Nginx源码根目录,先配置模块时开启测试开关,然后直接运行make check:
./configure --add-module=path/to/your_module --with-module-tests=YES make check
如果一切正常,你会看到Check框架输出的测试报告,清晰显示每个测试用例的通过/失败状态。
一些实用小贴士
- 如果你的模块依赖Nginx的内部核心函数,一定要确保头文件路径配置正确,不然编译会出现未定义引用的错误。
- 对于Nginx未对外暴露的内部函数,你可以在模块代码里新增测试专用的封装接口,或者把测试代码和模块核心代码放在同一编译单元里。
- 可以在模块的config文件里加自动检测逻辑,比如检查系统是否安装了Check库,自动决定是否开启测试支持,不用每次手动加
--with-module-tests=YES。
内容的提问来源于stack exchange,提问作者Jesse Weigert
相关产品推荐
相关产品推荐

