首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言單元測試框架 CUnit 完整實戰指南

     編輯:關於C語言

為什麼選 CUnit?

  • 純 C 實現,零依賴,嵌入式/跨平台友善。
  • 提供豐富斷言宏(`CU_ASSERT`、`CU_ASSERT_EQUAL`、`CU_ASSERT_PTR_NOT_NULL`...)。
  • 支援四種執行模式:Automated (XML)、Basic (文本)、Console (互動)、Curses (終端 GUI)。
  • 結構清晰:Registry → Suite(s) → Test(s),映射專案模組化結構。

架構模型

Test Registry (單例,進程僅一個)
   │
   ├─ Suite "ModuleA"     ← init/cleanup 可選
   │    ├─ Test "test_add"
   │    ├─ Test "test_sub"
   │    └─ ...
   ├─ Suite "ModuleB"
   │    └─ ...
   └─ ...

核心 API 流程

  1. CU_initialize_registry():初始化註冊表,回傳 `CUE_SUCCESS` 或錯誤碼。
  2. CU_add_suite(name, init_fn, cleanup_fn):新增測試套件,回傳 `CU_pSuite`。
  3. CU_add_test(suite, name, test_fn):新增測試用例,函式簽名 `void test_fn(void)`。
  4. 選擇執行介面:
    • CU_automated_run_tests():輸出 XML,適合 CI/CD。
    • CU_basic_run_tests():標準輸出摘要。
    • CU_console_run_tests():互動式選單。
  5. CU_cleanup_registry():釋放資源,回傳錯誤碼。

完整範例:測試 `sum(int a, int b)`

被測代碼 (math.h / math.c)

/* math.h */
#ifndef MATH_H
#define MATH_H
int sum(int a, int b);
#endif
/* math.c */
#include "math.h"
int sum(int a, int b) { return a + b; }

測試代碼 (test_math.c)

#include <CUnit/Basic.h>
#include "math.h"

/* --- 測試用例函式 --- */
void test_sum_positive(void) {
    CU_ASSERT_EQUAL(sum(3, 4), 7);
}
void test_sum_negative(void) {
    CU_ASSERT_EQUAL(sum(-5, 3), -2);
}
void test_sum_zero(void) {
    CU_ASSERT_EQUAL(sum(0, 0), 0);
}
void test_sum_overflow(void) {
    /* 有號溢位屬 UB,此處僅示範斷言寫法 */
    CU_ASSERT(sum(INT_MAX, 0) == INT_MAX);
}

/* --- Suite 初始化/清理 (可選) --- */
int init_suite(void) { return 0; }   // 分配共享資源
int clean_suite(void) { return 0; }  // 釋放共享資源

/* --- 註冊入口 --- */
int register_math_tests(void) {
    CU_pSuite suite = CU_add_suite("MathSuite", init_suite, clean_suite);
    if (!suite) return CU_get_error();

    if (!CU_add_test(suite, "test_sum_positive", test_sum_positive) ||
        !CU_add_test(suite, "test_sum_negative", test_sum_negative) ||
        !CU_add_test(suite, "test_sum_zero", test_sum_zero) ||
        !CU_add_test(suite, "test_sum_overflow", test_sum_overflow)) {
        return CU_get_error();
    }
    return CUE_SUCCESS;
}

測試執行主程式 (test_runner.c)

#include <CUnit/Automated.h>
#include <CUnit/Basic.h>
#include <CUnit/Console.h>
#include <stdio.h>

extern int register_math_tests(void);

int main(void) {
    if (CU_initialize_registry() != CUE_SUCCESS) return CU_get_error();

    if (register_math_tests() != CUE_SUCCESS) {
        CU_cleanup_registry();
        return CU_get_error();
    }

    /* 1. Automated → XML 報告 (CI 友善) */
    CU_set_output_filename("test_report");
    CU_list_tests_to_file();
    CU_automated_run_tests();

    /* 2. Basic → 控制台摘要 */
    CU_basic_set_mode(CU_BRM_VERBOSE);
    CU_basic_run_tests();

    /* 3. Console → 互動模式 (手動除錯用) */
    // CU_console_run_tests();

    CU_cleanup_registry();
    return CU_get_error();
}

建置與執行

# Makefile
CC = gcc
CFLAGS = -std=c99 -Wall -Wextra -I/usr/local/include
LDFLAGS = -L/usr/local/lib -lcunit

all: test_runner

test_runner: math.o test_math.o test_runner.o
    $(CC) $^ -o $@ $(LDFLAGS)

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f *.o test_runner test_report.xml
  1. 上一篇文章:
  2. 下一篇文章:
欄目導航
Copyright © 程式碼之家 All Rights Reserved