1. C语言单元测试框架CuTest设计与实现1.1 框架概述CuTest是一款轻量级C语言单元测试框架整个框架仅包含两个文件CuTest.c和CuTest.h总代码量不足1000行。该框架实现了完整的单元测试功能包括多种类型的断言机制测试用例(Test Case)管理测试套件(Test Suite)组织测试结果汇总与报告2. 核心架构设计2.1 断言机制实现CuTest提供了多种类型的断言宏用于比较测试值与期望值#define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac))以整数比较断言CuAssertIntEquals为例其底层实现如下void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, int expected, int actual) { char buf[STRING_MAX]; if (expected actual) return; sprintf(buf, expected %d but was %d, expected, actual); CuFail_Line(tc, file, line, message, buf); }当测试失败时框架会收集以下信息测试文件路径失败行号用户自定义错误消息期望值与实际值2.2 错误处理机制CuTest采用setjmp/longjmp实现错误处理流程void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string) { char buf[HUGE_STRING_LEN]; sprintf(buf, %s:%d: , file, line); CuStringInsert(string, buf, 0); tc-failed 1; tc-message string-buffer; if (tc-jumpBuf ! 0) longjmp(*(tc-jumpBuf), 0); }错误处理流程拼接完整的错误消息字符串设置测试用例失败标志(tc-failed)保存错误消息到测试用例结构体通过longjmp跳转到测试执行点3. 测试组织与管理3.1 测试用例定义测试用例函数原型为typedef void (*TestFunction)(CuTest *);示例测试用例void test_add(CuTest* tc) { CuAssert(tc, test not pass, 2 AddInt(1, 0)); }3.2 测试套件实现测试套件用于组织相关测试用例CuSuite* TestAdd(void) { CuSuite* suite CuSuiteNew(); SUITE_ADD_TEST(suite, test_add); return suite; }测试套件内部使用数组管理测试用例void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) { assert(testSuite-count MAX_TEST_CASES); testSuite-list[testSuite-count] testCase; testSuite-count; }3.3 多级测试套件组织支持将多个测试套件合并为更大的测试套件CuSuite* suite CuSuiteNew(); CuSuiteAddSuite(suite, CuGetSuite()); CuSuiteAddSuite(suite, CuStringGetSuite()); CuSuiteAddSuite(suite, TestAdd());4. 测试执行流程4.1 测试运行机制测试套件执行流程void CuSuiteRun(CuSuite* testSuite) { int i; for (i 0; i testSuite-count ; i) { CuTest* testCase testSuite-list[i]; CuTestRun(testCase); if (testCase-failed) { testSuite-failCount 1; } } }单个测试用例执行流程void CuTestRun(CuTest* tc) { jmp_buf buf; tc-jumpBuf buf; if (setjmp(buf) 0) { tc-ran 1; (tc-function)(tc); } tc-jumpBuf 0; }4.2 测试结果汇总测试执行完成后生成汇总报告void RunAllTests(void) { CuString *output CuStringNew(); CuSuite* suite CuSuiteNew(); CuSuiteAddSuite(suite, TestAdd()); CuSuiteRun(suite); CuSuiteSummary(suite, output); CuSuiteDetails(suite, output); printf(%s\n, output-buffer); }5. 完整使用示例5.1 定义测试用例void test_add(CuTest* tc) { CuAssert(tc, test not pass, 2 1 1); }5.2 创建测试套件CuSuite* TestAdd(void) { CuSuite* suite CuSuiteNew(); SUITE_ADD_TEST(suite, test_add); return suite; }5.3 执行测试int main() { RunAllTests(); getchar(); return 0; }6. 设计特点分析极简设计核心功能仅需两个文件便于集成到项目中零依赖不依赖任何外部库纯C语言实现灵活的组织结构支持多级测试套件适合大型项目详细的错误报告提供文件、行号等调试信息跨平台基于标准C语言特性可移植性强CuTest框架虽然小巧但完整实现了单元测试所需的核心功能特别适合嵌入式系统和资源受限环境下的C语言项目测试需求。
C语言单元测试框架CuTest设计与实现详解
发布时间:2026/6/14 19:42:52
1. C语言单元测试框架CuTest设计与实现1.1 框架概述CuTest是一款轻量级C语言单元测试框架整个框架仅包含两个文件CuTest.c和CuTest.h总代码量不足1000行。该框架实现了完整的单元测试功能包括多种类型的断言机制测试用例(Test Case)管理测试套件(Test Suite)组织测试结果汇总与报告2. 核心架构设计2.1 断言机制实现CuTest提供了多种类型的断言宏用于比较测试值与期望值#define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac))以整数比较断言CuAssertIntEquals为例其底层实现如下void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, int expected, int actual) { char buf[STRING_MAX]; if (expected actual) return; sprintf(buf, expected %d but was %d, expected, actual); CuFail_Line(tc, file, line, message, buf); }当测试失败时框架会收集以下信息测试文件路径失败行号用户自定义错误消息期望值与实际值2.2 错误处理机制CuTest采用setjmp/longjmp实现错误处理流程void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string) { char buf[HUGE_STRING_LEN]; sprintf(buf, %s:%d: , file, line); CuStringInsert(string, buf, 0); tc-failed 1; tc-message string-buffer; if (tc-jumpBuf ! 0) longjmp(*(tc-jumpBuf), 0); }错误处理流程拼接完整的错误消息字符串设置测试用例失败标志(tc-failed)保存错误消息到测试用例结构体通过longjmp跳转到测试执行点3. 测试组织与管理3.1 测试用例定义测试用例函数原型为typedef void (*TestFunction)(CuTest *);示例测试用例void test_add(CuTest* tc) { CuAssert(tc, test not pass, 2 AddInt(1, 0)); }3.2 测试套件实现测试套件用于组织相关测试用例CuSuite* TestAdd(void) { CuSuite* suite CuSuiteNew(); SUITE_ADD_TEST(suite, test_add); return suite; }测试套件内部使用数组管理测试用例void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) { assert(testSuite-count MAX_TEST_CASES); testSuite-list[testSuite-count] testCase; testSuite-count; }3.3 多级测试套件组织支持将多个测试套件合并为更大的测试套件CuSuite* suite CuSuiteNew(); CuSuiteAddSuite(suite, CuGetSuite()); CuSuiteAddSuite(suite, CuStringGetSuite()); CuSuiteAddSuite(suite, TestAdd());4. 测试执行流程4.1 测试运行机制测试套件执行流程void CuSuiteRun(CuSuite* testSuite) { int i; for (i 0; i testSuite-count ; i) { CuTest* testCase testSuite-list[i]; CuTestRun(testCase); if (testCase-failed) { testSuite-failCount 1; } } }单个测试用例执行流程void CuTestRun(CuTest* tc) { jmp_buf buf; tc-jumpBuf buf; if (setjmp(buf) 0) { tc-ran 1; (tc-function)(tc); } tc-jumpBuf 0; }4.2 测试结果汇总测试执行完成后生成汇总报告void RunAllTests(void) { CuString *output CuStringNew(); CuSuite* suite CuSuiteNew(); CuSuiteAddSuite(suite, TestAdd()); CuSuiteRun(suite); CuSuiteSummary(suite, output); CuSuiteDetails(suite, output); printf(%s\n, output-buffer); }5. 完整使用示例5.1 定义测试用例void test_add(CuTest* tc) { CuAssert(tc, test not pass, 2 1 1); }5.2 创建测试套件CuSuite* TestAdd(void) { CuSuite* suite CuSuiteNew(); SUITE_ADD_TEST(suite, test_add); return suite; }5.3 执行测试int main() { RunAllTests(); getchar(); return 0; }6. 设计特点分析极简设计核心功能仅需两个文件便于集成到项目中零依赖不依赖任何外部库纯C语言实现灵活的组织结构支持多级测试套件适合大型项目详细的错误报告提供文件、行号等调试信息跨平台基于标准C语言特性可移植性强CuTest框架虽然小巧但完整实现了单元测试所需的核心功能特别适合嵌入式系统和资源受限环境下的C语言项目测试需求。