CUnit簡介
CUnit是一個通過C語言編寫單元測試框架,用於編寫、管理和執行單元測試用例的測試系統。
官網:http://cunit.sourceforge.net/
幫助文檔:http://cunit.sourceforge.net/documentation.html
有關CUnit框架的更多介紹,可以參閱CUnit用戶手冊:
官方英文版:http://cunit.sourceforge.net/doc/index.html
中文翻譯版:https://blog.csdn.net/benkaoya/article/details/95887879
原文鏈接:https://blog.csdn.net/benkaoya/article/details/95870801
編譯、安裝CUnit
安裝環境,Ubuntu 16.04
下載地址:https://sourceforge.net/projects/cunit/files/CUnit/
到官網下載最新版本的代碼,本文編寫時,最新版本爲2.1-3
。
安裝步驟:
# tar -xjvf CUnit-2.1-3.tar.bz2
# cd CUnit-2.1-3
# mv configure.in configure.ac
# aclocal
# autoconf
configure.ac:161: error: possibly undefined macro: AC_PROG_LIBTOOL
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
出現找不到libtool工具錯誤。
安裝libtool工具:
# apt-get install libtool
成功執行autoconf
# autoconf
# automake
configure.ac:4: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated. For more info, see:
configure.ac:4: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:158: error: required file './compile' not found
configure.ac:158: 'automake --add-missing' can install 'compile'
configure.ac:4: error: required file './install-sh' not found
configure.ac:4: 'automake --add-missing' can install 'install-sh'
configure.ac:4: error: required file './missing' not found
configure.ac:4: 'automake --add-missing' can install 'missing'
執行automake出現以上錯誤,根據提示,添加 --add-missing
# automake --add-missing
configure.ac:4: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated. For more info, see:
configure.ac:4: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:158: installing './compile'
configure.ac:4: installing './install-sh'
configure.ac:4: installing './missing'
CUnit/Sources/Automated/Makefile.am:4: error: Libtool library used but 'LIBTOOL' is undefined
CUnit/Sources/Automated/Makefile.am:4: The usual way to define 'LIBTOOL' is to add 'LT_INIT'
CUnit/Sources/Automated/Makefile.am:4: to 'configure.ac' and run 'aclocal' and 'autoconf' again.
CUnit/Sources/Automated/Makefile.am:4: If 'LT_INIT' is in 'configure.ac', make sure
CUnit/Sources/Automated/Makefile.am:4: its definition is in aclocal's search path.
添加--add-missing執行automark後,還有錯誤提示,根據錯誤找問題。
需要從新執行一遍autoconf。
# autoconf
# automake
configure.ac:4: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:161: error: required file './ltmain.sh' not found
CUnit/Sources/Framework/Makefile.am:20: warning: '%'-style pattern rules are a GNU make extension
CUnit/Sources/Test/Makefile.am:12: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/AutomatedTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/BasicTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/ConsoleTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/CursesTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
以上錯誤只要在configure.ac:161: error: required file './ltmain.sh' not found
這行提示中。
根據提示,百度一番,發現是libtoolize配置問題。
首先查看下libtoolize的版本,確定已安裝了。
# libtoolize --version
libtoolize (GNU libtool) 2.4.6
Written by Gary V. Vaughan <[email protected]>, 2003
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
然後執行一下命令進行配置libtoolize
libtoolize --automake --copy --debug --force
接着再執行automake
# automake --add-missing
configure.ac:4: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated. For more info, see:
configure.ac:4: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:158: installing './compile'
configure.ac:4: installing './missing'
CUnit/Sources/Automated/Makefile.am: installing './depcomp'
CUnit/Sources/Framework/Makefile.am:20: warning: '%'-style pattern rules are a GNU make extension
CUnit/Sources/Test/Makefile.am:12: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/AutomatedTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/BasicTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/ConsoleTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
Examples/CursesTest/Makefile.am:13: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
沒有錯誤之後,執行configure,並執行安裝路徑爲當前目錄的__install文件夾。
# ./configure --prefix=$PWD/__install
編譯
# make
安裝
# make install
# cd __install/
# tree ./
./
├── doc
│ └── CUnit
│ ├── CUnit_doc.css
│ ├── error_handling.html
│ ├── fdl.html
│ ├── headers
│ │ ├── Automated.h
│ │ ├── Basic.h
│ │ ├── Console.h
│ │ ├── CUCurses.h
│ │ ├── CUError.h
│ │ ├── CUnit.h
│ │ ├── CUnit_intl.h
│ │ ├── MyMem.h
│ │ ├── TestDB.h
│ │ ├── TestRun.h
│ │ ├── Util.h
│ │ └── Win.h
│ ├── index.html
│ ├── introduction.html
│ ├── managing_tests.html
│ ├── running_tests.html
│ ├── test_registry.html
│ └── writing_tests.html
├── include
│ └── CUnit
│ ├── Automated.h
│ ├── Basic.h
│ ├── Console.h
│ ├── CUError.h
│ ├── CUnit.h
│ ├── CUnit_intl.h
│ ├── MyMem.h
│ ├── TestDB.h
│ ├── TestRun.h
│ └── Util.h
├── lib
│ ├── libcunit.a
│ ├── libcunit.la
│ ├── libcunit.so -> libcunit.so.1.0.1
│ ├── libcunit.so.1 -> libcunit.so.1.0.1
│ ├── libcunit.so.1.0.1
│ └── pkgconfig
│ └── cunit.pc
└── share
├── CUnit
│ ├── CUnit-List.dtd
│ ├── CUnit-List.xsl
│ ├── CUnit-Run.dtd
│ ├── CUnit-Run.xsl
│ ├── Memory-Dump.dtd
│ └── Memory-Dump.xsl
└── man
└── man3
└── CUnit.3
11 directories, 44 files
編譯、安裝總結:
aclocal
autoheader
autoconf
automake
如果在automake過程中有文件丟失,則執行下面命令:
automake --add-missing
再次執行automake
如果出現錯誤:configure.in:161:required file './ltmain.sh' not found,則執行下面的命令:
libtoolize --automake --copy --debug --force
執行完上述步驟以後,查看是否生成了configure,如果有,則執行:
./configure
執行完上述步驟以後,查看是否生成了Makefile,如果有,則執行:
make
安裝編譯出的庫:
sudo make install
使用CUnit
測試樣例1:
使用CUnit的basic接口測試,在控制檯打印測試結果。
#include <stdio.h>
#include <string.h>
#include "CUnit/Basic.h"
static FILE* temp_file = NULL;
/* suite初始化函數
* 打開臨時文件
* 返回值:0:成功;其它:失敗
*/
int init_suite1(void)
{
if(NULL == (temp_file = fopen("temp.txt", "w+"))) {
return -1;
} else {
return 0;
}
}
/* suite清除函數
* 關閉臨時文件
* 返回值:0:成功;其它:失敗
*/
int clean_suite1(void)
{
if(0 != fclose(temp_file)) {
return -1;
} else {
temp_file = NULL;
return 0;
}
}
/* 測試函數1
* 測試fprintf()
*/
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(8 == fprintf(temp_file, "i1 = %d", i1));
}
}
/* 測試函數2
* 測試fread()
*/
void testFREAD(void)
{
unsigned char buffer[20];
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));
}
}
int main()
{
CU_pSuite pSuite = NULL;
//初始化CUnit註冊表
if(CUE_SUCCESS != CU_initialize_registry())
return CU_get_error();
//向CUnit註冊表添加單元
pSuite = CU_add_suite("Suite_1", init_suite1, clean_suite1);
if(NULL == pSuite) {
CU_cleanup_registry(); //清空註冊表,釋放內存
return CU_get_error(); //返回錯誤
}
//向單元添加測試用例
if((NULL == CU_add_test(pSuite, "test of fprintf()", testFPRINTF)) ||
(NULL == CU_add_test(pSuite, "test of fread()", testFREAD))) {
CU_cleanup_registry();
return CU_get_error();
}
//使用CUnit Basic接口運行所有測試單元
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
CU_cleanup_registry();
return CU_get_error();
}
makefile文件
all:
gcc -o test1 test1.c -I/home/mq/learn/CUnit/install/CUnit-2.1-3/__install/include -L/home/mq/learn/CUnit/install/CUnit-2.1-3/__install/lib -lcunit -static
靜態鏈接CUnit庫,引入頭文件路徑。
# make
# ./test1
CUnit - A unit testing framework for C - Version 2.1-3
http://cunit.sourceforge.net/
Suite: Suite_1
Test: test of fprintf() ...FAILED
1. test1.c:44 - 8 == fprintf(temp_file, "i1 = %d", i1)
Test: test of fread() ...passed
Run Summary: Type Total Ran Passed Failed Inactive
suites 1 1 n/a 0 0
tests 2 2 1 1 0
asserts 5 5 4 1 n/a
Elapsed time = 0.000 seconds
結果表示,在單元Suite_1
的測試fprintf()
函數,測試不通過。
測試樣例2:
使用CUnit的Automated接口測試,測試結果輸出到XML文件中。
#include <stdio.h>
#include <string.h>
//#include "CUnit/Basic.h"
#include "CUnit/Automated.h"
static FILE* temp_file = NULL;
/* suite初始化函數
* 打開臨時文件
* 返回值:0:成功;其它:失敗
*/
int init_suite2(void)
{
if(NULL == (temp_file = fopen("temp.txt", "w+"))) {
return -1;
} else {
return 0;
}
}
/* suite清除函數
* 關閉臨時文件
* 返回值:0:成功;其它:失敗
*/
int clean_suite2(void)
{
if(0 != fclose(temp_file)) {
return -1;
} else {
temp_file = NULL;
return 0;
}
}
/* 測試函數1
* 測試fprintf()
*/
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(8 == fprintf(temp_file, "i1 = %d", i1));
}
}
/* 測試函數2
* 測試fread()
*/
void testFREAD(void)
{
unsigned char buffer[20];
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));
}
}
//測試用例信息結構體
static CU_TestInfo test_infos[] = {
{"testFPRINTF", testFPRINTF},
{"testFREAD", testFREAD},
CU_TEST_INFO_NULL
};
//測試單元信息結構體
static CU_SuiteInfo suites[] = {
{"test2", init_suite2, clean_suite2, NULL, NULL, test_infos},
CU_SUITE_INFO_NULL
};
int main()
{
//CU_pSuite pSuite = NULL;
CU_ErrorCode error ;
//初始化CUnit註冊表
if(CUE_SUCCESS != CU_initialize_registry())
return CU_get_error();
error = CU_register_suites(suites);
if(CUE_SUCCESS != error) {
CU_cleanup_registry();
return CU_get_error();
}
//使用CUnit Automated interface
CU_automated_run_tests();
CU_list_tests_to_file();
CU_cleanup_registry();
return CU_get_error();
}
# make
# ./test2
執行完畢後,在同級目錄下,生成CUnitAutomated-Listing.xml
和CUnitAutomated-Results.xml
文件。文件名是在不設定的情況下,使用默認文件名。
把項目生成的CUnitAutomated-Listing.xml
和CUnitAutomated-Results.xml
,與CUnit安裝目錄下的CUnit-List.dtd
、CUnit-List.xsl
、CUnit-Run.dtd
和CUnit-Run.xsl
,共六個文件,放到一個文件夾下,拷貝到window系統下,使用IE瀏覽器打開。
注意,要用IE瀏覽器進行打開,谷歌瀏覽器和狐火瀏覽器都無法正確打開。