⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testrun.c

📁 CUNIT c 测试框架,类似大名鼎鼎的junit,很有用的,这里是原代码,可以编译生成lib文件
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/*------------------------------------------------------------------------*/
/** 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 + -