1. 首页
  2. 教程
  3. 软件测试
  4. 单元测试
  5. CUnit教程

CUnit用户手册(4)测试及测试套管理

为了让CUnit运行一个测试用例,必须将其添加到由测试注册表注册的测试集(套)中。

4.1简介

#include <CUnit/TestDB.h> (included automatically by <CUnit/CUnit.h>)

 

typedef struct CU_Suite

{

char*             pName;                /**< Suite name. */

CU_pTest          pTest;                /**< Pointer to the 1st test in the suite. */

CU_InitializeFunc pInitializeFunc;      /**< Pointer to the suite initialization function. */

CU_CleanupFunc    pCleanupFunc;         /**< Pointer to the suite cleanup function. */

 

unsigned int      uiNumberOfTests;      /**< Number of tests in the suite. */

struct CU_Suite*  pNext;                /**< Pointer to the next suite in linked list. */

struct CU_Suite*  pPrev;                /**< Pointer to the previous suite in linked list. */

 

} CU_Suite;

typedef CU_Suite* CU_pSuite;              /**< Pointer to a CUnit suite. */

 

typedef struct CU_Test

{

char*           pName;                  /**< Test name. */

CU_TestFunc     pTestFunc;              /**< Pointer to the test function. */

jmp_buf*        pJumpBuf;   /**< Jump buffer for setjmp/longjmp test abort mechanism. */

 

struct CU_Test* pNext;                  /**< Pointer to the next test in linked list. */

struct CU_Test* pPrev;                  /**< Pointer to the previous test in linked list. */

 

} CU_Test;

typedef CU_Test* CU_pTest;                /**< Pointer to a CUnit test case. */

 

typedef void (*CU_TestFunc)(void)

typedef int  (*CU_InitializeFunc)(void)

typedef int  (*CU_CleanupFunc)(void)

 

CU_pSuite CU_add_suite(const char* strName,

CU_InitializeFunc pInit,

CU_CleanupFunc pClean);

 

CU_pTest  CU_add_test(CU_pSuite pSuite,

const char* strName,

CU_TestFunc pTestFunc);

 

typedef struct CU_SuiteInfo {

char             *pName;         /**< Suite name. */

CU_InitializeFunc pInitFunc;     /**< Suite initialization function. */

CU_CleanupFunc    pCleanupFunc;  /**< Suite cleanup function */

CU_TestInfo      *pTests;        /**< Test case array – must be NULL terminated. */

} CU_SuiteInfo;

typedef CU_SuiteInfo* CU_pSuiteInfo;  /**< Pointer to CU_SuiteInfo type. */

 

typedef struct CU_TestInfo {

char       *pName;      /**< Test name. */

CU_TestFunc pTestFunc;  /**< Test function. */

} CU_TestInfo;

typedef CU_TestInfo* CU_pTestInfo;  /**< Pointer to CU_TestInfo type. */

 

CU_ErrorCode CU_register_suites(CU_SuiteInfo suite_info[]);

CU_ErrorCode CU_register_nsuites(int suite_count, …);

 

4.2往注册表中添加测试套

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

创建一个新的测试集(套),具有指定的名称、构造函数和析构函数功能。新的测试套通过测试注册表(拥有者)注册的,所以注册表必须进行初始化,然后再添加任何测试套。目前CUnit的实现并不支持创建独立于测试注册表的测试套。该函数不能在执行测试时调用。

在注册表中所有测试套的名称必须是唯一的。初始化和清理功能函数是可选的,传送运行测试套之前和之后调用的函数指针。这使得该测试套可以临时建立和拆除固定装置,以支持运行测试用例。这些函数没有参数,如果他们执行成功应返回零(否则返回非零值)。如果一测试套并不需要这些功能中的一个或两个则对应传递给CU_add_suite()的参数设为NULL。

该函数返回一个指向到新测试套的指针,当往该测试套添加测试用例时将会用到该指针。如果发生错误,则返回NULL,框架错误代码被设置为下列之一:

CUE_SUCCESS 测试套创建成功。
CUE_NOREGISTRY 测试注册表仍未初始化。
CUE_NO_SUITENAME 测试套名(strName)为空NULL
CUE_DUP_SUITE 测试套名不唯一。
CUE_NOMEMORY 内存申请失败。

 

4.3 往测试套中添加测试用例

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

创建一个新的具有指定名称和测试功能的测试用例,并注册到指定的测试套中。所指定的测试套必须是已经调用CU_add_suite()创建好了的。CUnit目前的实现并不支持创建独立于测试套的测试用例。该函数不能在执行测试时调用。

添加到同一个测试套的所有测试用例的名称必须是唯一的。测试函数不能为空,须指向一个运行测试时被调用函数。测试函数既没有参数也没有返回值。

该函数返回一个指针新的测试用例的指针。如果创建测试过程中发生错误则返回NULL,框架错误代码被设置为下列之一:

CUE_SUCCESS 测试用例创建成功。
CUE_NOREGISTRY 测试注册表仍未初始化。
CUE_NOSUITE 指定的测试套无效
CUE_NO_TESTNAME 测试套名(strName)为空NULL
CUE_NO_TEST 测试函数指针无效
CUE_DUP_TEST 测试用例名不唯一
CUE_NOMEMORY 内存申请失败。

 

4.4管理测试用例的快捷方法

#define CU_ADD_TEST(suite, test) (CU_add_test(suite, #test, (CU_TestFunc)test))

这个宏会根据测试函数名称自动生成一个唯一的测试名称,并把它添加到指定的测试套中。应该由用户检查返回值验证其成功与否。

 

CU_ErrorCode CU_register_suites(CU_SuiteInfo suite_info[])

CU_ErrorCode CU_register_nsuites(int suite_count, …)

对于有着许多测试用例和测试套的大型的测试结构,管理的测试用例或测试套之间的关系及注册工作是繁琐且容易出错的。CUnit提供了一个特殊的注册模板,以帮助管理的测试套和测试用例。它的主要优点是统一对测试套及其关联的测试用例进行注册,并最大程度地减少用户需要写的错误检查代码。

测试用例分组列表到CU_TestInfo(在<CUnit/TestDB.h>中有定义)的矩阵实例中:

CU_TestInfo test_array1[] = {

{ “testname1”, test_func1 },

{ “testname2”, test_func2 },

{ “testname3”, test_func3 },

CU_TEST_INFO_NULL,

};

矩阵中每个数组元素包含一个测试用例的的名称(唯一)和测试函数。该数组的结束元素必须为NULL,可以用由宏CU_TEST_INFO_NULL定义的NULL值。包含在一个CU_TestInfo矩阵实例下的所用测试用例被封装成了一个测试集,这个测试集将被注册到同一个测试套中。

 

测试套信息可分布在一个或多个CU_SuiteInfo(在<CUnit/TestDB.h>中有定义)矩阵实例中定义:

CU_SuiteInfo suites[] = {

{ “suitename1”, suite1_init_func, suite1_cleanup_func, test_array1 },

{ “suitename2”, suite2_init_func, suite2_cleanup_func, test_array2 },

CU_SUITE_INFO_NULL,

};

矩阵中每个数组元素包含一个测试套名称(唯一)、测试套初始化函数、测试套清理函数和测试用例集CU_TestInfo矩阵的首地址。同理,如果给定的套件并不需要初始化或清除功能则可以将对应元素置为NULL。该数组必须以全NULL的元素作为结束,也可以使用该宏CU_SUITE_INFO_NULL。

 

所有通过CU_SuiteInfo矩阵定义的测试套可以单独地注册到测试注册表中:

CU_ErrorCode error = CU_register_suites(suites);

如果注册的任何测试套或测试用例过程中出现错误,则返回错误代码。返回的错误代码和通过使用普通的测试套和测试用例注册的操作返回的错误码是一样的。CU_register_nsuites()函数的使用是当用户希望使用一条语句注册的多个CU_SuiteInfo测试套的情况下:

CU_ErrorCode error = CU_register_nsuites(2, suites1, suites2);

此函数接受可变的CU_SuiteInfo矩阵数目。第一个参加指明了实际被传递进来的矩阵的个数。

4.5 测试套和测试用例的激活

CU_ErrorCode CU_set_suite_active(CU_pSuite pSuite, CU_BOOL fNewActive)

CU_ErrorCode CU_set_test_active(CU_pTest pTest, CU_BOOL fNewActive)

这两个函数可用于禁用或激活个别的测试套和测试用例。一个测试套或测试用例如果为非激活状态则在测试执行时不会被执行。所有的测试套和测试用例在创建时默认激活状态。可以分别通过pSuite->fActive 和 pTest->fActive 标志来识别测试套和测试用例的当前激活状态。如果为激活状态该标志将CU_TRUE否则为CU_FALSE。这使客户能动态选择要执行的部分测试用例集。请注意,禁用了一个测试套或测试用例然后又指定执行它是一个框架错误操作。这些函数如果执行成功返回CUE_SUCCESS,如果相应的测试套(或测试用例)为空的则返回 CUE_NOSUITE (或CUE_NOTEST)。

4.6 修改测试套和测试用例的其它属性

通常,测试套和测试用例的属性集在创建时设置。在某些情况下,客户希望可以通过操纵这些属性动态地修改测试结构。以下功能是提供用于此目的,其可以用于替代直接设置的数据结构的成员的值的方式。这些函数如果执行成功返回CUE_SUCCESS,如果相应的测试套(或测试用例)为空的则返回 CUE_NOSUITE (或CUE_NOTEST)。

 

CU_ErrorCode CU_set_suite_name(CU_pSuite pSuite, const char *strNewName)

CU_ErrorCode CU_set_test_name(CU_pTest pTest, const char *strNewName)

这两个函数用于变更所注册的测试套和测试用例的名称。可以分别用于 pSuite->pName and pTest->pName 的数据结构成员。如果测试套或测试用例为空,将分别返回 CUE_NOSUITE 或CUE_NOTEST。如果设置的名称为空,将分别返回 CUE_NO_SUITENAME 或CUE_NO_TESTNAME。

 

CU_ErrorCode CU_set_suite_initfunc(CU_pSuite pSuite, CU_InitializeFunc pNewInit)

CU_ErrorCode CU_set_suite_cleanupfunc(CU_pSuite pSuite, CU_CleanupFunc pNewClean)

这两个函数用例改变所注册的测试套的初始化函数和清理函数。可以分别用于p pSuite->pInitializeFunc and pSuite->pCleanupFunc 数据结构的成员。如果测试套为空则返回CUE_NOSUITE。

 

CU_ErrorCode CU_set_test_func(CU_pTest pTest, CU_TestFunc pNewFunc)

这个函数用于变化已注册的测试用例的测试函数。可用于pTest->pTestFunc 数据结构成员。如果测试函数为空则返回CUE_NOTEST。

4.7 查找私有的测试套和测试用例

在大多数情况下,客户将要通过调用 CU_add_suite() 和 CU_add_test() 返回的指针来参考已经注册的测试套和测试用例。有时,客户可能需要能够检索参考测试套和测试用例。下面的函数是提供协助客户及当客户有一些关于实体的信息(名称或其它注册信息)。在对测试套或测试用例没有什么已知信息的情况下,客户端将需要迭代的内部数据结构来列举测试套和测试用例。这是不直接支持客户端的API。

 

CU_pSuite CU_get_suite(const char* strName)

CU_pSuite CU_get_suite_at_pos(unsigned int pos)

unsigned int CU_get_suite_pos(CU_pSuite pSuite)

unsigned int CU_get_suite_pos_by_name(const char* strName)

这些函数帮助在激活的测试注册表中查找已注册的测试套。前2个函数可以通过名称或位置的查找测试套,如果无法找到则返回null。位置是从1开始索引的在范围[ 1…CU_get_registry()->uiNumberOfSuites]。这可能注册有重名的测试套,在这种情况下,只能查找第一次检索对应名字的测试套。第二个2函数,帮助客户确定注册的测试套的位置。如果无法找到的测试套则直接返回NULL。此外,如果注册表未初始化,这些函数会设置CUnit的错误状态为CUE_NOREGISTRY。同理,当传入的名字为NULL时设置错误状态为 CUE_NO_SUITENAME ,当找不到对应的测试套时设置为CUE_NOSUITE。

 

CU_pTest CU_get_test(CU_pSuite pSuite, const char *strName)

CU_pTest CU_get_test_at_pos(CU_pSuite pSuite, unsigned int pos)

unsigned int CU_get_test_pos(CU_pSuite pSuite, CU_pTest pTest)

unsigned int CU_get_test_pos_by_name(CU_pSuite pSuite, const char *strName)

这些函数帮助在指定的测试套中查找测试用例。前2个函数可以通过名称或位置的查找测试套,如果无法找到则返回null。位置是从1开始索引的在范围[ 1…pSuite->uiNumberOfSuites]。这可能注册有重名的测试用例,在这种情况下,只能查找第一次检索对应名字的测试用例。第二个2函数帮助客户识别的测试用例在测试套中的位置。如果找不到测试用例则返回0。此外,如果注册表未初始化,这些函数会设置CUnit的错误状态为CUE_NOREGISTRY,如果测试套为NULL则设置为CUE_NOSUITE。同理,当传入的名字为NULL时设置错误状态为 CUE_NO_TESTNAME ,当找不到对应的测试套时设置为CUE_NOTEST。

 

4.8已过时V1数据的类型和函数

下面的数据类型和函数不建议在第2版使用。要使用这些过时的名称,用户代码必须用USE_DEPRECATED_CUNIT_NAMES进行编译定义。

#include <CUnit/TestDB.h> (included automatically by CUnit/CUnit.h>).

不建议使用的函数名 等价的新函数名
TestFunc CU_TestFunc
InitializeFunc CU_InitializeFunc
CleanupFunc CU_CleanupFunc
_TestCase CU_Test
PTestCase CU_pTest
_TestGroup CU_Suite
PTestGroup CU_pSuite
add_test_group() CU_add_suite()
add_test_case() CU_add_test()
ADD_TEST_TO_GROUP() CU_ADD_TEST()
test_case_t CU_TestInfo
test_group_t CU_SuiteInfo
test_suite_t no equivalent – use CU_SuiteInfo
TEST_CASE_NULL CU_TEST_INFO_NULL
TEST_GROUP_NULL CU_SUITE_INFO_NULL
test_group_register CU_register_suites()
test_suite_register no equivalent – useCU_register_suites()

原创文章,作者:若木成林,如若转载,请注明出处:https://www.chinaztest.com/2533.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:983512074@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息