C开发中的单元测试
官方文档:http://cunit.sourceforge.net/doc/index.html
经过仔细观赏,要借用Cunit来提高自己的编码效率和质量,有必要先搞清它的几项要点: 首先仔细观察下图:
可以看出Cunit也是有组织的,呵呵,主要分几个角色,Registry,Suite及Test方法。可以通过下面例子,体会到这种组织关系。 按官方文档说明,使用Cunit的主要步骤有: 1) Write functions for tests (and suite init/cleanup if necessary). 2) Initialize the test registry - CU_initialize_registry() 3) Add suites to the test registry - CU_add_suite() 4) Add tests to the suites - CU_add_test() 5) Run tests using an appropriate interface, e.g. CU_console_run_tests 6) Cleanup the test registry - CU_cleanup_registry
本人英文不咋地,就不献丑翻译了,直接用英文理解吧(要努力用英文). 下面我们结合一个小实例,来体验一下Cunit的便利吧(学编程,最有效的方式还是自己动手) 先编写一个具体两个简单功能的函数,然后写Testcase来测试它。 文件主要有: 1) strformat.h :字符串功能函数的接口文件 2)strformat.c :字符串功能函数的实现 3)testcase.c : 测试用例及Cunit运行环境 4)makefile : 下面直奔代码: 代码:strformat.h
#ifndef _strformat_h #define _strformat_h typedef char * string; int string_lenth(string word); string to_Upper(string word); string add_str(string word1 ,string word2); #endif代码:strformat.c
#include #include #include #include #include #include #include #include #include "strformat.h" string add_str(string word1 ,string word2){ return (strcat(word1, word2)); } string to_Upper(string word){ int i; for(i = 0;word[i] !='\0' ;i++){ if(word[i]<'z' && word[i]>'a'){ word[i] -= 32; } } return word; } int string_lenth(string word){ int i; for(i = 0 ;word[i] != '\0';i++){ } return i; }测试代码: testcase.c
#include #include #include #include #include #include #include #include #include #include #include #include #include "strformat.h" void test_string_lenth(void){ string test = "Hello"; int len = string_lenth(test); CU_ASSERT_EQUAL(len,5); } void test_to_Upper(void){ char test[] = "Hello"; CU_ASSERT_STRING_EQUAL(to_Upper(test),"HELLO"); } void test_add_str(void){ char test1[] = "Hello!"; char test2[] = "MGC"; CU_ASSERT_STRING_EQUAL(add_str(test1,test2),"Hello!MGC"); } // CU_TestInfo是Cunit内置的一个结构体,它包括测试方法及描述信息 CU_TestInfo testcase[] = { {"test_for_lenth:",test_string_lenth }, {"test_for_add:",test_add_str }, CU_TEST_INFO_NULL }; CU_TestInfo testcase2[] = { {"test for Upper :",test_to_Upper }, CU_TEST_INFO_NULL }; int suite_success_init(void){ return 0; } int suite_success_clean(void){ return 0; } //定义suite数组,包括多个suite,每个suite又会包括若干个测试方法。 CU_SuiteInfo suites[] = { {"testSuite1",suite_success_init,suite_success_clean,testcase}, {"testsuite2",suite_success_init,suite_success_clean,testcase2}, CU_SUITE_INFO_NULL }; void AddTests(){ assert(NULL != CU_get_registry()); assert(!CU_is_test_running()); if(CUE_SUCCESS != CU_register_suites(suites)){ exit(EXIT_FAILURE); } } int RunTest(){ if(CU_initialize_registry()){ fprintf(stderr, " Initialization of Test Registry failed. "); exit(EXIT_FAILURE); }else{ AddTests(); CU_cleanup_registry(); return CU_get_error(); } } int main(int argc, char * argv[]) { return RunTest(); }注: 1)注意结合上面Cunit的组织结构图,理解Cunit中几个角色的关系(CU_TestInfo,CU_SuiteInfo各以数组的形式,将多个Test和Suite组织起来)。 2)Cunit有几种运行模式,如automated,basic,console,有的是可以交互的,有的是没有交互,直接出结果的。
代码:makefile
IINC=-I/usr/local/include/CUnit LIB=-L/usr/local/lib/ all: strformat.c testcase.c gcc -o test $(INC) $(LIB) $^ -lcunit -static注: 1)Cunit安装很简单,从官方地址上下载源代码后,在本机依次执行 ./configure make sudo make install 安装成功后相关的库及头文件安装到默认路径下。编译时添加选项: -I/usr/local/include/CUnit -L/usr/local/lib/ 就如makefile中的一样。