使用CUnit對庫做單元測試

前言:

博主目前手頭上管理着幾個設備的跨平臺庫,對外接口大概有七八十個,平常寫測試用例的test文件就有幾十個。趁着最近版本發佈後的空閒時間,對接口庫進行單元測試。與CppUnit類似,CUnit爲C程序員提供了基本的測試功能。

安裝:

博主根據源碼內部工程進行winodw平臺庫編譯時,遇到各種問題,修改了少許源碼後,方能正常運行,已將庫文件上傳

Cunit源碼的下載地址是:https://sourceforge.net/projects/cunit/postdownload

Windows庫文件下載地址: https://download.csdn.net/download/wjb123sw99/12311601

使用文檔:http://cunit.sourceforge.net/doc/index.html

使用:

使用CUnit官網所提供的Demo,讓我們快速熟悉CUnit整體操作。

#include <stdio.h>
#include <string.h>
#include "CUnit/Basic.h"
#include "CUnit/Automated.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.
 */
int init_suite1(void)
{
   if (NULL == (temp_file = fopen("temp.txt", "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.
 */
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];

   if (NULL != temp_file) {
      rewind(temp_file);
      CU_ASSERT(9 == fread(buffer, sizeof(unsigned char), 20, temp_file));
      CU_ASSERT(0 == strncmp((char *)buffer, "Q\ni1 = 10", 9));
   }
}

/* 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 */
   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)))
   {
      CU_cleanup_registry();
      return CU_get_error();
   }

   /* Run all tests using the CUnit Basic interface */
   CU_basic_set_mode(CU_BRM_VERBOSE);
   CU_list_tests_to_file();
   CU_automated_run_tests();
   CU_cleanup_registry();
   return CU_get_error();
}


上述程序運行完後,生成CUnitAutomated-Listing.xml、CUnitAutomated-Results.xml文件,將CUnit-List.dtd、CUnit-List.xsl、CUnit-Run.dtd、CUnit-Run.xsl(這幾個文件在CUnit的源碼包可以找到)和XML文件放到同一級目錄,使用window自帶的IE瀏覽器打開,即可看到單元測試結果。

下面講解下Demo中所使用到的CUnit函數。

函數:

CU_ErrorCode CU_initialize_registry(void);

用戶使用CUnit前,必須運行CU_initialize_registry接口進行測試框架初始化。

錯誤碼:

CUE_SUCCESS 初始化成功。
CUE_NOMEMORY 內存分配失敗。

void  CU_cleanup_registry(void);

 用戶使用CUnit後,必須運行CU_cleanup_registry接口用於釋放測試框架

CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean);

CU_add_suite函數用於用戶向測試框架註冊一個單元測試;strName【入參】:單元測試的名稱,必須在框架內唯一;pInit【入參】:單元測試初始化程序,類似於構造函數;pClean【入參】:單元測試結束程序,類似於析構函數。CU_InitializeFunc 函數格式定義如下:

typedef int  (*CU_InitializeFunc)(void);  /**< Signature for suite initialization function. */

如果該註冊函數不需要pInit或者pClean函數,則可以設爲NULL。該函數成功返回單元測試指針CU_pSuite,失敗則返回NULL。

CU_pTest  CU_add_test(CU_pSuite pSuite, const char* strName, CU_TestFunc pTestFunc);

CU_add_test函數用於用戶向單元測試中增加一個測試用例,pSuite【入參】:單元測試指針。strName【入參】:測試用例名稱;

pTestFunc【入參】:測試用例函數。CU_TestFunc 函數格式定義如下:

typedef void (*CU_TestFunc)(void);        /**< Signature for a testing function in a test case. */

CU_add_test函數成功則返回測試用例指針,失敗則返回NULL。

void  CU_basic_set_mode(CU_BasicRunMode mode);

設置基本運行模式,該模式在測試運行期間控制輸出,mode【入參】:可選擇下列參數值

CU_BRM_NORMAL 打印失敗和運行摘要。
CU_BRM_SILENT 除錯誤消息外,不輸出任何輸出。
CU_BRM_VERBOSE 運行詳細信息的最大輸出。

CU_ErrorCode CU_list_tests_to_file(void);

如果用戶想使用Automated模式輸出XML報表,則調用該函數。

void  CU_automated_run_tests(void);

使用Automated模式運行測試用例

CU_ErrorCode   CU_get_error(void);

由於CUnit部分函數錯誤時,返回NULL。如果用戶想獲取具體錯誤碼,則需要調用CU_get_error函數。

const char*    CU_get_error_msg(void);

由於CUnit部分函數錯誤時,返回NULL。如果用戶想獲取具體錯誤信息,則需要調用CU_get_error_msg函數。

斷言:

CUnit提供了一組用於測試邏輯條件的斷言。這些斷言的成功或失敗由框架跟蹤,可以在測試運行完成時查看。

CU_ASSERT(int expression)
CU_ASSERT_FATAL(int expression)
CU_TEST(int expression)
CU_TEST_FATAL(int expression)

Assert that expression is TRUE (non-zero)

CU_ASSERT_TRUE(value)
CU_ASSERT_TRUE_FATAL(value)

Assert that value is TRUE (non-zero)

CU_ASSERT_FALSE(value)
CU_ASSERT_FALSE_FATAL(value)

Assert that value is FALSE (zero)

CU_ASSERT_EQUAL(actual, expected)
CU_ASSERT_EQUAL_FATAL(actual, expected)

Assert that actual = = expected

CU_ASSERT_NOT_EQUAL(actual, expected))
CU_ASSERT_NOT_EQUAL_FATAL(actual, expected)

Assert that actual != expected

CU_ASSERT_PTR_EQUAL(actual, expected)
CU_ASSERT_PTR_EQUAL_FATAL(actual, expected)

Assert that pointers actual = = expected

CU_ASSERT_PTR_NOT_EQUAL(actual, expected)
CU_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected)

Assert that pointers actual != expected

CU_ASSERT_PTR_NULL(value)
CU_ASSERT_PTR_NULL_FATAL(value)

Assert that pointer value == NULL

CU_ASSERT_PTR_NOT_NULL(value)
CU_ASSERT_PTR_NOT_NULL_FATAL(value)

Assert that pointer value != NULL

CU_ASSERT_STRING_EQUAL(actual, expected)
CU_ASSERT_STRING_EQUAL_FATAL(actual, expected)

Assert that strings actual and expected are equivalent

CU_ASSERT_STRING_NOT_EQUAL(actual, expected)
CU_ASSERT_STRING_NOT_EQUAL_FATAL(actual, expected)

Assert that strings actual and expected differ

CU_ASSERT_NSTRING_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_EQUAL_FATAL(actual, expected, count)

Assert that 1st count chars of actual andexpected are the same

CU_ASSERT_NSTRING_NOT_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_NOT_EQUAL_FATAL(actual, expected, count)

Assert that 1st count chars of actual andexpected differ

CU_ASSERT_DOUBLE_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_EQUAL_FATAL(actual, expected, granularity)

Assert that |actual - expected| <= |granularity|
Math library must be linked in for this assertion.

CU_ASSERT_DOUBLE_NOT_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_NOT_EQUAL_FATAL(actual, expected, granularity)

Assert that |actual - expected| > |granularity|
Math library must be linked in for this assertion.

CU_PASS(message)

Register a passing assertion with the specified message. No logical test is performed.

CU_FAIL(message)
CU_FAIL_FATAL(message)

Register a failed assertion with the specified message. No logical test is performed.

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章