C 语⾔单元测试框架——CUnit 安装(windows 和Linux )及使⽤
⽬录
昨天把软件测试基础基本上看完了,因为我最近⼯作问题,需要着重研究下Cunit这个单元测试框架,上午把之前学的基础整理出来了。 刚刚研究了下Cunit除了基本 (Basic)接⼝,还有三个接⼝没使⽤过,我也会经量都尝试下。
下个星期我的任务是写⼀个墨⽔屏的驱动,测试的学习估摸着会⽐较慢了,不会像前⾯⼀天⼀篇道两篇的笔记记录,咱尽量嗷。CUnit
上⾯纯属瞎扯淡嗷,接下来本来也想着cv⼀些简介什么的,想了想算了,⼏乎每篇⽂章都有,咱直接附上⼀个具有代表性的⼀个⾃⼰看吧。看过这篇⽂章的应该也看过了,这篇⽂章整理汇总了下。
CUnit Windows 安装
CUnit Linux(Ubuntu) 安装
软件源中与CUnit相关的包有:使⽤apt-get install安装即可。
安装步骤
cunit安装成功后会⽣成4个⽂件夹:doc、include、lib、share。cunit 在windows 下安装:https ://blog .csdn /godmaycry /article /details /77480549 (已验证可⽤)https ://cloud .tencent /developer /article /1648952 ⽂章中提到以下问题 (但我没遇到错误,以及提到了使⽤VS  Code IDE )安装完毕把C :\mingw -w64\x86_64-8.1.0-posix -seh -rt_v6-rev0\mingw64\msys\mingw\lib\libcunit .a 拷贝到C :\mingw -w64\x86_64-8.1.0-posix -seh -rt_v6-rev0\mingw64\lib 。(不拷贝在下⾯gcc 或者clang 运⾏中,加⼊-lcunit 参数会提⽰..lib : can’t find -lcunit 的错误)接下来把C :\mingw -w64\x86_64-8.1.0-posix -seh -rt_v6-rev0\mingw64\msys\mingw\include\CUnit\⽬录中的所有.h ⽂件拷贝到C :\mingw -w64\x86_64-8.1.0-posix -seh -rt_v6-rev0\mingw64\include 中去。注意:编译的时候需要连接cunit
⽰例:gcc -o test test .c -lcunit
1
2
3
4
5
6
7
8
linux系统安装步骤csdn9
10
11
12libcunit1 libcunit1-dev libcunit1-doc libcunit1-ncurses libcunit1-ncurses-dev
1tar -jxvf CUnit-2.1-3.tar.bz2cd CUnit-2.1-3libtoolize -f -c -i aclocal autoconf autoheader automake chmod u+x configure ./configure –prefix=/opt/cunit make make install
1
2
3
4
5
6
7
8
9
10
11
doc⽬录是⼀些简介以及使⽤说明。include和lib⽬录中是我们需要的头⽂件以及库⽂件。
share⽬录中有Automated模式下需要的⽂件。
⼀键把cunit 测试结果(Basic)和gcov 覆盖率结果合并
gcov
python 代码
main.py
bat 代码
cunit 测试代码(拿官⽅历程改了下)gcc -fprofile -arcs -ftest -coverage -o test test .c    编译⽣成可执⾏⽂件(test )和.gcno ⽂件执⾏可执⾏⽂件./test ⽣成⽂件gcda
gcov test .c ⽣成gcov ⽂件,该⽂件有代码覆盖率和每⾏代码执⾏次数
1
2
3print ("Hello World %d " % 2)flist = ['','']ofile = open ('','w')for  fr in  flist :    for  txt in  open (fr , 'r'):        print (txt )        ofile .write (txt )ofile .close ()
1
2
3
4
5
6
7
8gcc -fprofile -arcs -ftest -coverage -o test _4_book .c -lcunit test .exe => gcov _4_book .c => ren _4_book .c . main .py
1
2
3
4
5
6
7/* *  Simple example of a CUnit unit test. * *  This program (crudely) demonstrates a very simple "black box" *  test of the standard library functions fprintf() and fread(). *  It uses suite initialization and cleanup functions to open  *  and close a common temporary file used by the test functions. *  The test functions then write to and read from the temporary  *  file in the course of testing the library functions. * *  The 2 test functions are added to a single CUnit suite, and  *  then run using the CUnit Basic interface.  The output of the  *  program (on CUnit version 2.0-2) is: * *          CUnit : A Unit testing framework for C. *          cunit.sourceforge/ * *      Suite: Suite_1 *        Test: test of fprintf() ... passed  *        Test: test of fread() ... passed  * *      --Run Summary: Type      Total    Ran  Passed  Failed  *                      suites        1      1    n/a      0 *                      tests        2      2      2      0 *                      asserts      5      5      5      0 *//* 根据书上程序流图编写 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* 根据书上程序流图编写 */#include <stdio .h >#include <string .h >#include "CUnit/Basic.h"/* Pointer
to the file used by the tests. */static  FILE  *temp_file = NULL ;/* The suite initialization function. * Opens the temporary file used by the tests. * Returns zero on success, non-zero otherwise. *//* 第⼀步 套件初始化 编写init 套件*/int init_suite1(void ){  if  (NULL  == (temp_file = fopen ("", "w+")))  {      return  -1;  }  else    {      return  0;  }}/* The suite cleanup function. * Closes the temporary file used by the tests. * Returns zero on success, non-zero otherwise. *//* 第⼀步 套件初始化 编写clean 套件*/int clean_suite1(void ){  if  (0 != fclose (temp_file ))  {      return  -1;  }  else    {      temp_file = NULL ;      return  0;  }}/* Simple test of fprintf(). * Writes test data to the temporary file and checks  * whether the expected number of bytes were written. */void  testFPRINTF (void ){  int i1 = 10;  if  (NULL  != temp_file )  {      CU_ASSERT (0 == fprintf (temp_file , ""));      CU_ASSERT (2 == fprintf (temp_file , "Q\n"));      CU_ASSERT (7 == fprintf (temp_file , "i1 = %d", i1));  }}/* Simple test of fread(). * Reads the data previously written by testFPRINTF() * and checks whether the expected characters are present. * Must be run after testFPRINTF(). */void  testFREAD (void ){  unsigned char buffer [20];
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
if  (NULL  != temp_file )  {      rewind (temp_file );      CU_ASSERT (9 == fread (buffer , sizeof (unsigned char ), 20, temp_file ));      CU_ASSERT (0 == strncmp (buffer , "Q\ni1 = 10", 9));  }}float bookExample (float x ,float y ,float z ){  if  ((y >1) && (z ==0))  {      x = x /y ;  }  if  ((y ==2) || (x >1))  {      x = x +1;  }      return  x ;}void  testBookExample (void ){  //满⾜判定覆盖标准的测试⽤例  CU_ASSE
RT (2 == bookExample (1,2,1))  CU_ASSERT (1 == bookExample (3,3,0))  //满⾜条件覆盖标准的测试⽤例  CU_ASSERT (1.5 == bookExample (1,2,0))  CU_ASSERT (3 == bookExample (2,1,1))  //满⾜判定/条件覆盖标准的测试⽤例  CU_ASSERT (3 == bookExample (4,2,0))  CU_ASSERT (1 == bookExample (1,1,1))  //满⾜条件组合覆盖标准的测试⽤例  CU_ASSERT (3 == bookExample (4,2,0))  CU_ASSERT (2 == bookExample (1,2,1))  CU_ASSERT (3 == bookExample (2,1,0))  CU_ASSERT (1 == bookExample (1,1,1))  //满⾜路径覆盖标准的测试⽤例  CU_ASSERT (3 == bookExample (4,2,0))  CU_ASSERT (1 == bookExample (3,3,0))  CU_ASSERT (3 == bookExample (2,1,0))  CU_ASSERT (1 == bookExample (1,1,1))}/* The main() function for setting up and running the tests. * Returns a CUE_SUCCESS on successful running, another  * CUnit error code on failure. */int main (){  CU_pSuite pSuite = NULL ; //初始化结构体  /* initialize the CUnit test registry */  /* 第⼆步 初始化注册表 */  if  (CUE_SUCCESS  != CU_initialize_registry ())      return  CU_get_error ();  /* add a suite to the registry */  /* 第三步 添加套件到测试注册表 */
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
Automated
上⾯的CUnit的输出⽅式是Basic(基本)
怎么将输出模式换成Automated?
常规的6个步骤还是不变,只需要在最后那加两个函数:CU_automated_run_tests();
CU_list_tests_to_file();
想了解细节的看⽂档
开始我尝试Automated的输出⽅式时⽣成了两个XML⽂件,死活显⽰不出来像官⽅截图那样的,如何我错误的去查如何查看XML⽂件以及XML转Markdown等等,到最后我看到了⼀篇⽂章,原来是我少了⼏个⽂件。
⽂章中提到  /* 第三步 添加套件到测试注册表 */  pSuite = CU_add_suite ("Suite_1", init_suite1, clean_suite1);  if  (NULL  == pSuite )  {                        // 如果添加套件失败      CU_cleanup_registry (); // 清理注册表并报错      return  CU_get_error ();  }  /* add the tests to the suite */  /* 第四步 添加测试套件 */  /* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */  if  ((NULL  ==
CU_add_test (pSuite , "test of fprintf()", testFPRINTF )) ||      (NULL  == CU_add_test (pSuite , "test of fread()", testFREAD )) ||      (NULL  == CU_add_test (pSuite , "test of BookExample()", testBookExample )))  { // 如果添加测试套件失败清理注册表并报错      CU_cleanup_registry ();      return  CU_get_error ();  }  /* Run all tests using the CUnit Basic interface */  /* 第五步 使⽤适当的接⼝运⾏测试 */  /*    CU_BRM_NORMAL    Normal 模式-失败和运⾏摘要打印[default]  CU_BRM_SILENT    静默模式-除了框架错误消息外,不输出任何输出。  CU_BRM_VERBOSE  详细模式——运⾏详细信息的最⼤输出。  */  CU_basic_set_mode (CU_BRM_VERBOSE ); // 设置基本接⼝的运⾏模式  CU_basic_run_tests (); // 使⽤基本接⼝运⾏所有注册的CUnit 测试  /* 第六步 清理测试注册表 */  CU_cleanup_registry ();  return  CU_get_error ();}
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186