词条 | CUnit |
释义 | 继Junit CppUnit的成功后, c语言环境下也出现了开发源码的白盒测试用例CUnit。CUnit以静态库的形式提供给用户使用,用户编写程序的时候直接链接此静态库就可以了。它提供了一个简单的单元测试框架,并且为常用的数据类型提供了丰富的断言语句支持。 结构框架在CUnit的主页上可以看到对他结构简单描述 Test Registry | ------------------------------ | | Suite '1' . Suite 'N' | | --------------- --------------- | | | | Test '11' ... Test '1M' Test 'N1' ... Test 'NM' CUnit的测试是单线程启动,只能注册一个测试用例Test Registry, 一次测试(Test Registry)可以运行多个测试包(Test Suite),而每个测试包可以包括多个测试用例(Test Case),每个测试用例又包含一个或者多个断言类的语句。具体到程序的结构上,一次测试下辖多个Test Suite,它对应于程序中各个独立模块;一个Suite管理多个Test Case,它对应于模块内部函数实现。每个Suite可以含有setup和teardown函数,分别在执行suite的前后调用。 注册一个测试用例(如果已经注册了你可以cleanup掉然后重新注册使用)然后CU_add_suite增加你的模块然后CU_add_test再在你的模块下挂载你的模块内的测试函数。所有的挂载完毕后,调用你想使用的界面进行测试。 测试模式下面是四种测试模式: 1 Automated Output to xml file Non-interactive 2 Basic Flexible programming interface Non-interactive 3 Console Console interface (ansi C) Interactive 4 Curses Graphical interface (Unix) Interact 注意1,2是没有交互功能的,4的Unix下的我是windows用户, 选择第3个介绍console而且console是可以人机交互的。 测试基本流程使用CUnit进行测试的基本流程如下所示: 1.书写代测试的函数(如果必要,需要写suite的init/cleanup函数) 2.初始化Test Registry - CU_initialize_registry() 3.把测试包(Test Suites)加入到Test Registry - CU_add_suite() 4.加入测试用例(Test Case)到测试包当中 - CU_add_test() 5.使用适当的接口来运行测试测试程序,例如 CU_console_run_tests() 6.清除Test Registry - CU_cleanup_registry() 1.4 TestCase的构成 一个CUnit TestCase的构成有以下文件:test.c、testcase.c、Main.c 与 Makefile构成。即一个测试范例由①被测函数,②测试函数(定义策识用例和测试包),③运行测试函数及④Makefile四部分构成。 CUnit Framework的下载CUnit Framework的下载 Cunit Framework的当前版本为:CUnit-2.1-0-src.tar.gz。 CUnit Framework的安装CUnit的Framework的安装环境为Fedora 5。安装命令如下: (1)解包#tar xzvf CUnit-2.1-0-src.tar.gz (2)编译与安装#cd CUnit-2.1-0 #aclocal (if necessary) #autoconf (if necessary) #automake (if necessary) #chmod u+x configure (if necessary) #./configure --prefix <Your choice of directory for installation> #make #make install (3)加载CUnit的库(only one time) #cd /usr/local/lib #ldconfig CUnit TestCase构成CUnit TestCase的构成一个CUnit TestCase的构成有以下文件:test.c、testcase.c、Main.c 与 Makefile构成。 主要构成函数说明以下以一个简单的testcase为例说明。 我要测试的是整数求最大值的函数maxi,我使用如下文件组织结构: 1.test.c:被测函数(定义maxi()函数) 2.testcase.c:测试函数(定义测试用例和测试包) 3.Main.c:运行测试函数(调用CUnit的Automated接口运行测试) 生成测试程序(1)被测函数test.c /** *file: test.c **/ int maxi(int i,int j) { return i>j?i:j; } (2)测试函数(定义测试用例和测试包)testcase.c #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <CUnit/CUnit.h> #include <CUnit/Automated.h> #include <CUnit/TestDB.h> /**//*---- functions to be tested ------*/ extern int maxi(int i, int j); /**//*---- test cases ------------------*/ void testIQJ() { CU_ASSERT_EQUAL(maxi(1,1),1); CU_ASSERT_EQUAL(maxi(0,-0),0); } void testIGJ() { CU_ASSERT_EQUAL(maxi(2,1),2); CU_ASSERT_EQUAL(maxi(0,-1),0); CU_ASSERT_EQUAL(maxi(-1,-2),-1); } void testILJ() { CU_ASSERT_EQUAL(maxi(1,2),2); CU_ASSERT_EQUAL(maxi(-1,0),0); CU_ASSERT_EQUAL(maxi(-2,-1),-1); } CU_TestInfo testcases[] = { {"Testing i equals j:", testIQJ}, {"Testing i greater than j:", testIGJ}, {"Testing i less than j:", testILJ}, CU_TEST_INFO_NULL }; /**//*---- test suites ------------------*/ int suite_success_init(void) { return 0; } int suite_success_clean(void) { return 0; } CU_SuiteInfo suites[] = { {"Testing the function maxi:", suite_success_init, suite_success_clean, testcases}, CU_SUITE_INFO_NULL }; /**//*---- setting enviroment -----------*/ void AddTests(void) { assert(NULL != CU_get_registry()); assert(!CU_is_test_running()); /**//* shortcut regitry */ if(CUE_SUCCESS != CU_register_suites(suites)){ fprintf(stderr, "Register suites failed - %s ", CU_get_error_msg()); exit(EXIT_FAILURE); } } (3)运行测试函数 Main.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include "Basic.h" int main(int argc, char* argv[]) { CU_BasicRunMode mode = CU_BRM_VERBOSE; CU_ErrorAction error_action = CUEA_IGNORE; int i; setvbuf(stdout, NULL, _IONBF, 0); for (i=1 ; i<argc ; i++) { if (!strcmp("-i", argv)) { error_action = CUEA_IGNORE; } else if (!strcmp("-f", argv)) { error_action = CUEA_FAIL; } else if (!strcmp("-A", argv)) { error_action = CUEA_ABORT; } else if (!strcmp("-s", argv)) { mode = CU_BRM_SILENT; } else if (!strcmp("-n", argv)) { mode = CU_BRM_NORMAL; } else if (!strcmp("-v", argv)) { mode = CU_BRM_VERBOSE; } else if (!strcmp("-e", argv)) { return 0; } else { printf("\Usage: BasicTest [options]\\" "Options: -i ignore framework errors [default].\" " -f fail on framework error.\" " -A abort on framework error.\\" " -s silent mode - no output to screen.\" " -n normal mode - standard output to screen.\" " -v verbose mode - max output to screen [default].\\" " -e print expected test results and exit.\" " -h print this message and exit.\\"); return 0; } } if (CU_initialize_registry()) { printf("\Initialization of Test Registry failed."); } else { AddTests(); CU_basic_set_mode(mode); CU_set_error_action(error_action); printf("\Tests completed with return value %d.\", CU_basic_run_tests()); CU_cleanup_registry(); } return 0; } (4)Makefile INC=-I/usr/local/include/CUnit LIB=-L/usr/local/lib/ all: func.c test_func.c run_test.c #gcc -o test $(INC) $(LIB) -lcunit $^ gcc -o test $(INC) $(LIB) -lcunit $^ clean: -rm -rf *.o test 测试报告CUnit - A Unit testing framework for C - Version 2.1-0 Suite: suite_success_both Test: testSuccess1 ... passed Test: testSuccess2 ... passed Test: testSuccess3 ... passed Suite: suite_success_init Test: testSuccess1 ... passed Test: testSuccess2 ... passed Test: testSuccess3 ... passed Suite: suite_success_clean Test: testSuccess1 ... passed Test: testSuccess2 ... passed Test: testSuccess3 ... passed Suite: test_failure Test: testFailure1 ... FAILED 1. ExampleTests.c:52 - 0 Test: testFailure2 ... FAILED 1. ExampleTests.c:53 - 0 Test: testFailure3 ... FAILED 1. ExampleTests.c:54 - 0 WARNING - Suite initialization failed for suite_failure_both. WARNING - Suite initialization failed for suite_failure_init. Suite: suite_success_but_failure_clean Test: testSuiteFailure1 ... FAILED 1. ExampleTests.c:49 - 0 Test: testSuiteFailure2 ... passed WARNING - Suite cleanup failed for suite_success_but_failure_clean. Suite: TestSimpleAssert Test: testSimpleAssert ... FAILED 1. ExampleTests.c:63 - 0 2. ExampleTests.c:64 - !1 3. ExampleTests.c:65 - 0 Test: testFail ... FAILED 1. ExampleTests.c:70 - CU_FAIL("This is a failure.") 2. ExampleTests.c:71 - CU_FAIL("This is another failure.") Suite: TestBooleanAssert Test: testAssertTrue ... FAILED 1. ExampleTests.c:79 - CU_ASSERT_TRUE(!CU_TRUE) 2. ExampleTests.c:80 - CU_ASSERT_TRUE(CU_FALSE) Test: testAssertFalse ... FAILED 1. ExampleTests.c:88 - CU_ASSERT_FALSE(!CU_FALSE) 2. ExampleTests.c:89 - CU_ASSERT_FALSE(CU_TRUE) Suite: TestEqualityAssert Test: testAssertEqual ... FAILED 1. ExampleTests.c:99 - CU_ASSERT_EQUAL(10,11) 2. ExampleTests.c:100 - CU_ASSERT_EQUAL(0,1) 3. ExampleTests.c:101 - CU_ASSERT_EQUAL(0,-1) 4. ExampleTests.c:102 - CU_ASSERT_EQUAL(-12,12) Test: testAssertNotEqual ... FAILED 1. ExampleTests.c:111 - CU_ASSERT_NOT_EQUAL(10,10) 2. ExampleTests.c:112 - CU_ASSERT_NOT_EQUAL(0,-0) 3. ExampleTests.c:113 - CU_ASSERT_NOT_EQUAL(0,0) 4. ExampleTests.c:114 - CU_ASSERT_NOT_EQUAL(-12,-12) Suite: TestPointerAssert Test: testAssertPtrEqual ... FAILED 1. ExampleTests.c:121 - CU_ASSERT_PTR_EQUAL((void*)0x100,(void*)0x101) Test: testAssertPtrNotEqual ... FAILED 1. ExampleTests.c:128 - CU_ASSERT_PTR_NOT_EQUAL((void*)0x100,(void*)0x100) Suite: TestNullnessAssert Test: testAssertPtrNull ... FAILED 1. ExampleTests.c:136 - CU_ASSERT_PTR_NULL((void*)0x23) Test: testAssertPtrNotNull ... FAILED 1. ExampleTests.c:143 - CU_ASSERT_PTR_NOT_NULL(NULL) 2. ExampleTests.c:144 - CU_ASSERT_PTR_NOT_NULL((void*)0x0) Suite: TestStringAssert Test: testAssertStringEqual ... FAILED 1. ExampleTests.c:155 - CU_ASSERT_STRING_EQUAL(str1,str3) 2. ExampleTests.c:156 - CU_ASSERT_STRING_EQUAL(str3,str2) Test: testAssertStringNotEqual ... FAILED 1. ExampleTests.c:168 - CU_ASSERT_STRING_NOT_EQUAL(str1,str2) Suite: TestNStringAssert Test: testAssertNStringEqual ... FAILED 1. ExampleTests.c:181 - CU_ASSERT_NSTRING_EQUAL(str2,str3,4) 2. ExampleTests.c:182 - CU_ASSERT_NSTRING_EQUAL(str1,str3,strlen(str1)) Test: testAssertNStringNotEqual ... FAILED 1. ExampleTests.c:194 - CU_ASSERT_NSTRING_NOT_EQUAL(str1,str2,2) 2. ExampleTests.c:195 - CU_ASSERT_NSTRING_NOT_EQUAL(str2,str3,2) Suite: TestDoubleAssert Test: testAssertDoubleEqual ... FAILED 1. ExampleTests.c:205 - CU_ASSERT_DOUBLE_EQUAL(10,10.0001,0.00001) 2. ExampleTests.c:206 - CU_ASSERT_DOUBLE_EQUAL(10,10.0001,-0.00001) 3. ExampleTests.c:207 - CU_ASSERT_DOUBLE_EQUAL(-10,-10.0001,0.00001) 4. ExampleTests.c:208 - CU_ASSERT_DOUBLE_EQUAL(-10,-10.0001,-0.00001) Test: testAssertDoubleNotEqual ... FAILED 1. ExampleTests.c:218 - CU_ASSERT_DOUBLE_NOT_EQUAL(10,10.001,0.01) 2. ExampleTests.c:219 - CU_ASSERT_DOUBLE_NOT_EQUAL(10,10.001,-0.01) 3. ExampleTests.c:220 - CU_ASSERT_DOUBLE_NOT_EQUAL(-10,-10.001,0.01) 4. ExampleTests.c:221 - CU_ASSERT_DOUBLE_NOT_EQUAL(-10,-10.001,-0.01) Suite: TestFatal Test: testFatal ... FAILED 1. ExampleTests.c:227 - CU_FALSE --Run Summary: Type Total Ran Passed Failed suites 16 14 n/a 3 tests 35 31 10 21 asserts 89 89 47 42 Tests completed with return value 22. 4 项目中CUnit TestCase的作成 4.1 项目中TestCase作成的指导思想 CUnit的TestCase作成的指导思想:TestCase和项目代码分开,作成的TestCase独立地放在其它目录中。 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。