C语言单元测试框架——CUnit

1、CUnit简介

CUnit 是一个通过 C 语言编写的用于编写、管理和执行单元测试用例的C语言单元测试框架。

它往往被编成库的形式(静态库或动态库)提供给用户测试代码进行使用,用户编写程序的时候直接链接此静态库就可以了。

它提供了一个简单的单元测试框架,并且为常用的数据类型提供了丰富的断言语句支持。
CUnit是平台无关的框架与各种用户接口的组合。核心框架为管理测试注册表,套件和测试用例提供了基本支持。用户接口便于与框架交互以运行测试和查看结果。CUnit的组织结构与传统的单元测试框架类似:
在这里插入图片描述

2、CUnit安装

CUnit的首页
https://cunit.sourceforge.net/
CUnit 的文档手册地址
https://cunit.sourceforge.net/doc/index.html
中文翻译版
https://blog.csdn.net/benkaoya/article/details/95887879
CUnit 2-1-3下载地址
https://sourceforge.net/projects/cunit/?source=typ_redirect

2.1、安装配置——Ubuntu

软件源中与CUnit相关的包有:

libcunit1 libcunit1-dev libcunit1-doc libcunit1-ncurses libcunit1-ncurses-dev

使用apt-get install安装即可。

2.2、安装步骤

下面为ubuntu安装方法

tar -jxvf CUnit-2.1-3.tar.bz2
cd CUnit-2.1-3
libtoolize -f -c -i
aclocal
autoconf
autoheader
automake
chmod u+x configure
./configure –prefix=/opt/cunit
make
make install

sudo apt-get install ncurses-dev无法解决问题则按照下面centos下载方法
将其中的yum改为apt-get install
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
下面为centos安装方法
下载CUnit压缩包
https://sourceforge.net/projects/cunit/
上传
在这里插入图片描述

tar jxvf CUnit-2.1-3.tar.bz2
cd CUnit-2.1-3
yum install -y libtool
mv configure.in configure.ac
aclocal
autoconf
autoheader
automake --add-missing
libtoolize --version
libtoolize --automake --copy --debug --force
automake --add-missing
chmod u+x configure
./configure --prefix=$HOME/local
make
make install

2.3、/usr/bin/ld: cannot find -lcurses

sudo apt-get install ncurses-dev

2.4、centos报错

yum install ncurses*
yum -y install glibc-static

请添加图片描述

2.5、安装文件

cunit安装成功后会生成4个文件夹:doc、include、lib、share。

  • doc目录是一些简介以及使用说明。
  • includelib目录中是我们需要的头文件以及库文件。
  • share目录中有Automated模式下需要的文件。

请添加图片描述

3、CUnit使用介绍

3.1、输出方式

请添加图片描述
如上边所示,后两种主要是interactive的接口,就是我们可以交互式地指定参数,然后观察结果。在我们具体的环境下,我们通常使用上面两种接口,第一种是将结果输出到XML文档中,便于我们生成报告。第二种仅仅是每一次运行结束之后,在standard output中显示,不能保留测试结果数据。

我们可以将前两种输出结合起来,自己测试的时候,使用Basic模式,生成报告的时候,使用Automated模式。

注:在Curse输出模式下需要联接 -lncurses

3.2、输出方式对应的接口函数

请添加图片描述
配置使用Basic模式,运行的结果如下。
在这里插入图片描述
配置使用Automated模式,重新编译运行后会生成CUnitAutomated-Listing.xmlCUnitAutomated-Results.xml两个文件。文件名是在不设定的情况下,使用默认文件名。

把项目生成的CUnitAutomated-Listing.xmlCUnitAutomated-Results.xml,与CUnit安装目录下的CUnit-List.dtdCUnit-List.xslCUnit-Run.dtdCUnit-Run.xsl,共六个文件,放到一个文件夹下,拷贝到window系统下,使用IE浏览器打开。

注意,要用IE浏览器进行打开,谷歌浏览器和狐火浏览器都无法正确打开。

TestMax-Results.xml
在这里插入图片描述
TestMax-Listing.xml
在这里插入图片描述

3.3、测试函数的书写

1) 首先针对被测试的函数书写测试函数。

2) 初始化一个Registry。

3) 将特定的Suite加入到这个Registry中。可以为Suite指定初始化函数和清理函数。

4) 将测试函数加入到一个Suite中,这样,如果该测试函数的运行需要一些初始化条件,那么可以可以将代码加入到Suite的初始化函数中,当然不要忘记最后还要做对应的清理操作。

5) 使用相应的接口将测试结果输出。

6) 最后,清理Registry。

3.4、CUnit 断言

CUnit提供了大量的预定义的断言,针对几乎所有的C的标准类型,我们可以针对具体的需要检查的参数的类型进行选择。
CUnit 对断言定义如下:
请添加图片描述
请添加图片描述
请添加图片描述
可以看到,每一种类型的断言都有FATAL和非FATAL两个函数,他们的区别是,非FATAL断言失败的时候,程序继续运行,而FATAL类型的断言失败之后,程序马上中止。通常我们使用非FATAL就可以了。

注意在我们的程序中,需要对返回值,out参数进行判断,对于是否是预想结果的判断的时候,一定要使用断言,而不要使用printf等等函数,一方面printf缺乏灵活性,另一方面,只有使用断言,结果报告中才会有对应的输出项。

CU_PASSCU_FAIL这两个断言比较特殊,它们仅仅表示测试程序运行到了这个地方。比如,在某些测试函数中,被测试的函数没有任何返回值等,我们为了证明这个函数已经被运行到了,我们使用以上两个函数。它们仅仅打印出一条消息,代表执行过。还有就是,它们也被输出。

4、CUnit使用实例

#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <CUnit/Automated.h>
#include <CUnit/Basic.h>
#include <CUnit/CUnit.h>
#include <CUnit/Console.h>
#include <CUnit/TestDB.h>
#include <assert.h>

int suite_success_init(void){
    
    
    return 0;
}

int suite_success_clean(void){
    
    
    return 0;
}
void test_fun1(void){
    
    
	//测试函数编写
}
void test_fun2(void){
    
    
	//测试函数编写
}
CU_TestInfo test_cases1[] = {
    
    
    {
    
    "test1", test_fun1}, 
    {
    
    "test2", test_fun2},
    CU_TEST_INFO_NULL
};
CU_TestInfo test_cases2[] = {
    
    
    CU_TEST_INFO_NULL
};

CU_SuiteInfo suites[] = {
    
    
    {
    
    "test_cases1:", suite_success_init, suite_success_clean, NULL, NULL, test_cases1},
    {
    
    "test_cases2:", suite_success_init, suite_success_clean, NULL, NULL, test_cases2},
    CU_SUITE_INFO_NULL
};

int main(int argc, char **argv)
{
    
    
    if (CU_initialize_registry()) {
    
    
        fprintf(stderr, " Initialization of Test Registry failed. ");
        exit(EXIT_FAILURE);
    } else {
    
    
		assert(NULL != CU_get_registry());
		assert(!CU_is_test_running());
		if (CUE_SUCCESS != CU_register_suites(suites)) {
    
    
			exit(EXIT_FAILURE);
		}
#if 0
		/**** Automated Mode *****************/
		CU_set_output_filename("TestMax");
		CU_automated_run_tests();
		CU_list_tests_to_file();
#else
		//***** Basice Mode *******************
		CU_basic_set_mode(CU_BRM_VERBOSE);
		CU_basic_run_tests();
#endif
        CU_cleanup_registry();
        return CU_get_error();
    }
    return 0;
}

makefile

all:
	gcc -o test testcase.c -I./include -L./lib -lcunit

按照centos下载方法
测试文件为test.c
Makefile

all:
	gcc -o test test.c -I/root/local/include -L/root/local/lib -lcunit -lcurses -static

五、文章来源及推荐

https://blog.csdn.net/cike626/article/details/115268486
https://blog.csdn.net/dongtaintailiang/article/details/118862429
https://huaweicloud.csdn.net/63566c8dd3efff3090b5f3bf.html

猜你喜欢

转载自blog.csdn.net/weixin_46048542/article/details/127958235