使用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.

 

 

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