C語言單元測試框架unit的使用
阿新 • • 發佈:2019-01-01
針對C語言的測試框架相比其他語言要少一些,本文簡單介紹一下Cunit框架的基本使用方法,權當備忘吧。Cunit的組織框架如下圖所示:
將單個測試用例打包到一個suite中,這些suite在Registry中註冊。registry中的所有suite/tests可以使用單個函式呼叫執行,也可以執行選定的套件或測試。下面看一個例子
首先我們新建檔案,寫一個待測試函式,這裡以一個字串轉換數字函式為例,這是我們的第一版實現
// convert.c // 版本1 int str_to_int(char* s) { int sum = 0; char *p = s; while (*p != 0) { sum = sum * 10 + *p -'0'; p++; } return sum; }
顯然這個函式是有很多問題的,我們寫一個測試函式來測試它。
void TEST_str_to_int() { int ans; char *p; char *ps[] = { "123", "-123", "0", "siahideib", "2147483648", "2147483647", "-1-2", " -2147483647", " -2147483648aaaa"}; int real[] = {123, -123, 0, 0, 0, 2147483647, -1, -2147483647, -2147483648}; int i = 0; for (i = 0; i < sizeof(real)/sizeof(real[0]); i++) { ans = str_to_int(ps[i]); CU_ASSERT_EQUAL(ans,real[i]); } }
測試函式和被測函式寫好之後,我們就可以定義一個registry 和一個suite,在suite中新增被測函式,並在registry中註冊。
addTestModule() { CU_pSuite pSuite = NULL; // 新增suite pSuite = CU_add_suite("str_to_int測試模組", suite_success_init, suite_success_clean); if (pSuite == NULL) { return -1; } // 在suite中新增被測函式 if (NULL == CU_add_test(pSuite,"str_to_int",TEST_str_to_int)) { return -1; } return 0; }
Cunit提供了三種模式檢視單元測試結果,分別是控制檯模式,基本模式和報表模式
void
run_test()
{
if (CU_initialize_registry()) {
printf("error");
return ;
}
assert(NULL != CU_get_registry());
assert(!CU_is_test_running());
if (0 != addTestModule()) {
CU_cleanup_registry();
return ;
}
// 報表模式
// 設定輸出檔名稱
CU_set_output_filename("str_to_int_test_report");
CU_list_tests_to_file();
CU_automated_run_tests();
// 基本模式
// CU_basic_set_mode(CU_BRM_VERBOSE);
// CU_basic_run_tests();
// 控制檯模式
// CU_console_run_tests();
// CU_console_run_tests();
CU_cleanup_registry();
}
最後寫一個main函式來呼叫測試函式
#include<stdio.h>
#include "test.h"
int
main()
{
run_test();
return 0;
}
編譯執行
gcc -g convert.c main.c test.c -lcunit
./a.out
執行完成後,在當前目錄下可以看到生成了兩個xml檔案,這兩個檔案就是得到的測試結果。
str_to_int_test_report-Listing.xml
str_to_int_test_report-Results.xml
不過這兩個檔案不能直接開啟,需要把cunit安裝目錄下的另外四個檔案複製過來。如果預設安裝的話,這四個檔案一般在/usr/local/share/CUnit目錄下
CUnit-List.dtd
CUnit-List.xsl
CUnit-Run.dtd
CUnit-Run.xsl
把這6個檔案拷貝到同一路徑下,就可以通過IE或者Edge瀏覽器檢視輸出結果。
可以看到,9個測試用例有3個沒有通過。改進一下被測函式
// convert.c
// 版本2
int
str_to_int(char* s)
{
int sign = 1;
char *p = s;
long sum = 0;
// 指標判空
if (!s) {
return 0;
}
// 排除空格
while (*p == ' ')
p++;
//控制符號
if (*p == '-') {
sign = -1;
p++;
} else if (*p == '+') {
sign = 1;
p++;
}
while (*p >= '0' && *p <= '9') {
// 左移比乘法效率高,注意優先順序
sum = (sum << 3) + (sum << 1) + *p -'0';
// 處理溢位
if ((sum > INT_MAX && sign == 1) || sum > (long)INT_MAX + 1 && sign == -1) {
sum = 0;
break;
}
p++;
}
return (int)sum * sign;
}
重新編譯,執行,看一下測試結果,這一次9個case全部通過