📄 testrun.c
字号:
}
/*------------------------------------------------------------------------*/
/** Free all memory allocated for the linked list of
* test failure records. pFailure is reset to NULL
* after its list is cleaned up.
* @param ppFailure Pointer to head of linked list of
* CU_pFailureRecords to clean.
* @see CU_clear_previous_results()
*/
static void cleanup_failure_list(CU_pFailureRecord* ppFailure)
{
CU_pFailureRecord pCurFailure = NULL;
CU_pFailureRecord pNextFailure = NULL;
pCurFailure = *ppFailure;
while (NULL != pCurFailure) {
if (NULL != pCurFailure->strCondition) {
CU_FREE(pCurFailure->strCondition);
}
if (NULL != pCurFailure->strFileName) {
CU_FREE(pCurFailure->strFileName);
}
pNextFailure = pCurFailure->pNext;
CU_FREE(pCurFailure);
pCurFailure = pNextFailure;
}
*ppFailure = NULL;
}
/*------------------------------------------------------------------------*/
/** Run all tests in a specified suite.
* Internal function to run all tests in a suite. The suite
* need not be registered in the test registry to be run.
* If the CUnit system is in an error condition after running
* a test, no additional tests are run.
* @param pSuite The suite containing the test (non-NULL).
* @param pRunSummary The CU_RunSummary to receive the results (non-NULL).
* @return A CU_ErrorCode indicating the status of the run.
* @see CU_run_suite() for public interface function.
* @see CU_run_all_tests() for running all suites.
*/
static CU_ErrorCode run_single_suite(CU_pSuite pSuite, CU_pRunSummary pRunSummary)
{
CU_pTest pTest = NULL;
CU_ErrorCode result;
CU_ErrorCode result2;
assert(NULL != pSuite);
assert(NULL != pRunSummary);
f_pCurTest = NULL;
f_pCurSuite = pSuite;
CU_set_error(result = CUE_SUCCESS);
/* call the suite initialization function, if any */
if ((NULL != pSuite->pInitializeFunc) && (0 != (*pSuite->pInitializeFunc)())) {
if (NULL != f_pSuiteInitFailureMessageHandler) {
(*f_pSuiteInitFailureMessageHandler)(pSuite);
}
pRunSummary->nSuitesFailed++;
add_failure(&f_failure_list, &f_run_summary,
0, "Suite Initialization failed - Suite Skipped", "CUnit System", pSuite, NULL);
CU_set_error(result = CUE_SINIT_FAILED);
}
/* reach here if no suite initialization, or if it succeeded */
else {
pTest = pSuite->pTest;
while ((NULL != pTest) && ((CUE_SUCCESS == result) || (CU_get_error_action() == CUEA_IGNORE))) {
result2 = run_single_test(pTest, pRunSummary);
result = (CUE_SUCCESS == result) ? result2 : result;
pTest = pTest->pNext;
}
pRunSummary->nSuitesRun++;
/* call the suite cleanup function, if any */
if ((NULL != pSuite->pCleanupFunc) && (0 != (*pSuite->pCleanupFunc)())) {
if (NULL != f_pSuiteCleanupFailureMessageHandler) {
(*f_pSuiteCleanupFailureMessageHandler)(pSuite);
}
pRunSummary->nSuitesFailed++;
add_failure(&f_failure_list, &f_run_summary,
0, "Suite cleanup failed.", "CUnit System", pSuite, pTest);
CU_set_error(CUE_SCLEAN_FAILED);
result = (CUE_SUCCESS == result) ? CUE_SCLEAN_FAILED : result;
}
}
f_pCurSuite = NULL;
return result;
}
/*------------------------------------------------------------------------*/
/** Run a specific test.
* Internal function to run a test case. This includes
* calling any handler to be run before executing the test,
* running the test's function (if any), and calling any
* handler to be run after executing a test.
* @param pTest The test to be run (non-NULL).
* @param pRunSummary The CU_RunSummary to receive the results (non-NULL).
* @return A CU_ErrorCode indicating the status of the run.
* @see CU_run_test() for public interface function.
* @see CU_run_all_tests() for running all suites.
*/
CU_ErrorCode run_single_test(CU_pTest pTest, CU_pRunSummary pRunSummary)
{
volatile unsigned int nStartFailures;
/* keep track of the last failure BEFORE running the test */
volatile CU_pFailureRecord pLastFailure = f_last_failure;
jmp_buf buf;
assert(NULL != f_pCurSuite);
assert(NULL != pTest);
assert(NULL != pRunSummary);
nStartFailures = pRunSummary->nAssertsFailed;
CU_set_error(CUE_SUCCESS);
f_pCurTest = pTest;
if (NULL != f_pTestStartMessageHandler) {
(*f_pTestStartMessageHandler)(f_pCurTest, f_pCurSuite);
}
/* set jmp_buf and run test */
pTest->pJumpBuf = &buf;
if (0 == setjmp(buf)) {
if (NULL != pTest->pTestFunc) {
(*pTest->pTestFunc)();
}
}
pRunSummary->nTestsRun++;
/* if additional assertions have failed... */
if (pRunSummary->nAssertsFailed > nStartFailures) {
pRunSummary->nTestsFailed++;
if (NULL != pLastFailure) {
pLastFailure = pLastFailure->pNext; /* was a failure before - go to next one */
}
else {
pLastFailure = f_failure_list; /* no previous failure - go to 1st one */
}
}
else {
pLastFailure = NULL; /* no additional failure - set to NULL */
}
if (NULL != f_pTestCompleteMessageHandler) {
(*f_pTestCompleteMessageHandler)(f_pCurTest, f_pCurSuite, pLastFailure);
}
pTest->pJumpBuf = NULL;
f_pCurTest = NULL;
return CU_get_error();
}
/** @} */
#ifdef CUNIT_BUILD_TESTS
#include "test_cunit.h"
typedef enum TET {
TEST_START = 1,
TEST_COMPLETE,
ALL_TESTS_COMPLETE,
SUITE_INIT_FAILED,
SUITE_CLEANUP_FAILED
} TestEventType;
typedef struct TE {
TestEventType type;
CU_pSuite pSuite;
CU_pTest pTest;
CU_pFailureRecord pFailure;
struct TE * pNext;
} TestEvent, * pTestEvent;
static int f_nTestEvents = 0;
static pTestEvent f_pFirstEvent = NULL;
static void add_test_event(TestEventType type, CU_pSuite psuite,
CU_pTest ptest, CU_pFailureRecord pfailure)
{
pTestEvent pNewEvent = (pTestEvent)malloc(sizeof(TestEvent));
pTestEvent pNextEvent = NULL;
pNewEvent->type = type;
pNewEvent->pSuite = psuite;
pNewEvent->pTest = ptest;
pNewEvent->pFailure = pfailure;
pNewEvent->pNext = NULL;
pNextEvent = f_pFirstEvent;
if (pNextEvent) {
while (pNextEvent->pNext) {
pNextEvent = pNextEvent->pNext;
}
pNextEvent->pNext = pNewEvent;
}
else {
f_pFirstEvent = pNewEvent;
}
++f_nTestEvents;
}
static void clear_test_events(void)
{
pTestEvent pCurrentEvent = f_pFirstEvent;
pTestEvent pNextEvent = NULL;
while (pCurrentEvent) {
pNextEvent = pCurrentEvent->pNext;
free(pCurrentEvent);
pCurrentEvent = pNextEvent;
}
f_pFirstEvent = NULL;
f_nTestEvents = 0;
}
static void test_start_handler(const CU_pTest pTest, const CU_pSuite pSuite)
{
TEST(CU_is_test_running());
TEST(pSuite == CU_get_current_suite());
TEST(pTest == CU_get_current_test());
add_test_event(TEST_START, pSuite, pTest, NULL);
}
static void test_complete_handler(const CU_pTest pTest, const CU_pSuite pSuite,
const CU_pFailureRecord pFailure)
{
TEST(CU_is_test_running());
TEST(pSuite == CU_get_current_suite());
TEST(pTest == CU_get_current_test());
add_test_event(TEST_COMPLETE, pSuite, pTest, pFailure);
}
static void test_all_complete_handler(const CU_pFailureRecord pFailure)
{
TEST(!CU_is_test_running());
add_test_event(ALL_TESTS_COMPLETE, NULL, NULL, pFailure);
}
static void suite_init_failure_handler(const CU_pSuite pSuite)
{
TEST(CU_is_test_running());
TEST(pSuite == CU_get_current_suite());
add_test_event(SUITE_INIT_FAILED, pSuite, NULL, NULL);
}
static void suite_cleanup_failure_handler(const CU_pSuite pSuite)
{
TEST(CU_is_test_running());
TEST(pSuite == CU_get_current_suite());
add_test_event(SUITE_CLEANUP_FAILED, pSuite, NULL, NULL);
}
void test_succeed(void) { CU_TEST(CU_TRUE); }
void test_fail(void) { CU_TEST(CU_FALSE); }
int suite_succeed(void) { return 0; }
int suite_fail(void) { return 1; }
/*-------------------------------------------------*/
/* tests:
* CU_set_test_start_handler()
* CU_set_test_complete_handler()
* CU_set_all_test_complete_handler()
* CU_set_suite_init_failure_handler()
* CU_set_suite_cleanup_failure_handler()
* CU_get_test_start_handler()
* CU_get_test_complete_handler()
* CU_get_all_test_complete_handler()
* CU_get_suite_init_failure_handler()
* CU_get_suite_cleanup_failure_handler()
*/
static void test_message_handlers(void)
{
CU_pSuite pSuite1 = NULL;
CU_pSuite pSuite2 = NULL;
CU_pSuite pSuite3 = NULL;
CU_pTest pTest1 = NULL;
CU_pTest pTest2 = NULL;
CU_pTest pTest3 = NULL;
CU_pTest pTest4 = NULL;
CU_pTest pTest5 = NULL;
pTestEvent pEvent = NULL;
CU_pRunSummary pRunSummary = NULL;
TEST(!CU_is_test_running());
/* handlers should be NULL on startup */
TEST(NULL == CU_get_test_start_handler());
TEST(NULL == CU_get_test_complete_handler());
TEST(NULL == CU_get_all_test_complete_handler());
TEST(NULL == CU_get_suite_init_failure_handler());
TEST(NULL == CU_get_suite_cleanup_failure_handler());
/* register some suites and tests */
CU_initialize_registry();
pSuite1 = CU_add_suite("suite1", NULL, NULL);
pTest1 = CU_add_test(pSuite1, "test1", test_succeed);
pTest2 = CU_add_test(pSuite1, "test2", test_fail);
pTest3 = CU_add_test(pSuite1, "test3", test_succeed);
pSuite2 = CU_add_suite("suite2", suite_fail, NULL);
pTest4 = CU_add_test(pSuite2, "test4", test_succeed);
pSuite3 = CU_add_suite("suite3", suite_succeed, suite_fail);
pTest5 = CU_add_test(pSuite3, "test5", test_fail);
TEST_FATAL(CUE_SUCCESS == CU_get_error());
/* first run tests without handlers set */
clear_test_events();
CU_run_all_tests();
TEST(0 == f_nTestEvents);
TEST(NULL == f_pFirstEvent);
TEST(2 == CU_get_number_of_suites_run());
TEST(2 == CU_get_number_of_suites_failed());
TEST(4 == CU_get_number_of_tests_run());
TEST(2 == CU_get_number_of_tests_failed());
TEST(4 == CU_get_number_of_asserts());
TEST(2 == CU_get_number_of_successes());
TEST(2 == CU_get_number_of_failures());
TEST(4 == CU_get_number_of_failure_records());
pRunSummary = CU_get_run_summary();
TEST(pRunSummary->nSuitesRun == CU_get_number_of_suites_run());
TEST(pRunSummary->nSuitesFailed == CU_get_number_of_suites_failed());
TEST(pRunSummary->nTestsRun == CU_get_number_of_tests_run());
TEST(pRunSummary->nTestsFailed == CU_get_number_of_tests_failed());
TEST(pRunSummary->nAsserts == CU_get_number_of_asserts());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -