CUNIT是一個C語言的單元測試架構,使用者可以撰寫C語言,進行以下四種測試方式。由於筆者只需要使用Console方式測試,因此後續的編譯與使用方式都只針對Console整理。
l Automated non-interactive
with output to xml files
l Basic non-interactive
with optional output to stdout
l Console interactive console
mode under user control
l Curses interactive curses
mode under user control
使用CUnit函數庫
一、直接使用CUNIT library
取得程式碼,下載連結為 http://sourceforge.net/projects/cunit/
以Win7 64bit為例,安裝好MinGW Shell之後,執行 “configure”,接著執行 “make” 即可。編譯好的函數庫會放在 \CUnit-2.1-2\CUnit\Sources\.libs\libcunit.a。其他Unix based的作業系統,編譯方式應該也相同。
以 Linux 為例,其作法如下
1. aclocal (if necessary)
2. autoconf (if necessary)
3. automake --add-missing (if necessary)
4. chmod u+x configure (if necessary)
5. ./configure --prefix=/usr
6. make
7. sudo make install
若使用較新版本的 automake,可能需要加上下列幾個指令 libtoolize, autoheader
$ gcc -g test.c -lcunit
三、若編譯 library 有困難,測試程式可與CUNIT一起編譯。
1.
將 CUnit-2.1-2\CUnit\Headers所有檔案,加入 include path。
2.
編譯時加入下列檔案
l CUnit-2.1-2\CUnit\Sources\Automated.c
l CUnit-2.1-2\CUnit\Sources\Basic.c
l CUnit-2.1-2\CUnit\Sources\Console.c
l CUnit-2.1-2\CUnit\Sources\CUError.c
l CUnit-2.1-2\CUnit\Sources\MyMem.c
l CUnit-2.1-2\CUnit\Sources\TestDB.c
l CUnit-2.1-2\CUnit\Sources\TestRun.c
l CUnit-2.1-2\CUnit\Sources\Util.c
四、測試程式與CUNIT一起編譯的可能問題 (以 Mac OSX 10.9.5為例)
以下將我在編譯程式時所遇到的問題作一整理,
1. CUnit.h file not found
解法:rename CUnit.h.in to Cunit.h
2. Conflicting types for 'getmouse'
問題在於我的系統內有多個 curse.h
a. XCode default include path 為 '/usr/include/curse.h'
Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.
b. GNU C default include path 為 '/opt/local/include/curses.h'
Copyright (c) 1998-2010,2011 Free Software Foundation, Inc.
解法:確定編譯時只採用其中一個 include path 即可解決此問題
/usr/include/curse.h
3. forward declaration of 'struct _win_st'
參考 curses.h 如下:
#ifndef NCURSES_OPAQUE
#define NCURSES_OPAQUE 1
#endif
#if !NCURSES_OPAQUE因為 NCURSES_OPAQUE 預設值為1,導致'struct _win_st'沒有正確的定義,因此 forward declaration 找不到'struct _win_st'
struct ldat;
struct _win_st
{
// ....
}
#endif
解決方式是在編譯程式時加入 '-DNCURSES_OPAQUE=0'
API用法:
所有CUnit的函數都以 “CU_”的形式出現。以下是一個簡單的使用範例:
#include "CUnit.h"
#include "Console.h"
static int TestInit(void) {return 0;}
static int TestClean(void) {return 0;}
void testAssertTrue(void)
{
CU_ASSERT_TRUE(CU_TRUE);
CU_ASSERT_TRUE(!CU_FALSE);
CU_ASSERT_TRUE(!CU_TRUE);
CU_ASSERT_TRUE(CU_FALSE);
}
void main(void)
{
CU_pSuite pSuite;
CU_initialize_registry();
pSuite = CU_add_suite("TestHello", TestInit, TestClean);
CU_add_test(pSuite, "testAssertTrue", testAssertTrue);
CU_console_run_tests();
CU_cleanup_registry();
}
執行結果如下:
若是使用者想要自動執行測試範例,只要置換 CU_console_run_tests()即可。
將自動測試結果導出至 Stdout, 使用 CU_basic_run_tests()
將自動測試結果導出至 XML, 使用 CU_automated_run_tests(),預設名稱為CUnitAutomated-Results.xml,若要更改名稱可以使用 CU_set_output_filename()設定。
上面提供了三種測試報表介面,筆者個人傾向是平常開發時使用CU_console_run_tests(),需要提供客戶報表時再改成使用CU_automated_run_tests()。
參考資料: