#ifndef INCLUDED_C_TEST_H #define INCLUDED_C_TEST_H #include #include #include #include #include #include // ========================================== // ANSI 终端颜色宏定义 // ========================================== #define COLOR_RESET "\033[0m" #define COLOR_GREEN "\033[32m" #define COLOR_RED "\033[31m" #define COLOR_YELLOW "\033[33m" #define COLOR_BLUE "\033[34m" #define COLOR_CYAN "\033[36m" #define COLOR_BOLD "\033[1m" // ========================================== // 核心测试框架结构 // ========================================== typedef struct { int passed_count; int failed_count; double total_time_ms; } TestRegistry; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ static TestRegistry g_test_registry = {0, 0, 0.0}; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define ASSERT_MSG(condition, message) \ do { \ if (!(condition)) { \ printf(" " COLOR_RED "[FAIL] %s:%d: Assertion failed: (%s). Message: %s" COLOR_RESET "\n", __FILE__, __LINE__, #condition, message); \ g_test_registry.failed_count++; \ return; \ } \ } while(0) #define ASSERT_INT_EQ_MSG(expected, actual, message) \ do { \ if ((expected) != (actual)) { \ printf(" " COLOR_RED "[FAIL] %s:%d: Expected %d, but got %d. Message: %s" COLOR_RESET "\n", __FILE__, __LINE__, (int)(expected), (int)(actual), message); \ g_test_registry.failed_count++; \ return; \ } \ } while(0) #ifndef TEST_EPSILON #define TEST_EPSILON 1e-6 #endif #define ASSERT_DOUBLE_EQ_MSG(expected, actual, message) \ do { \ double __exp = (double)(expected); \ double __act = (double)(actual); \ /* 计算两个浮点数差值的绝对值,并与允许的误差进行比较 */ \ if (fabs(__exp - __act) > TEST_EPSILON) { \ printf(" " COLOR_RED "[FAIL] %s:%d: Expected %.6f, but got %.6f. Message: %s" COLOR_RESET "\n", \ __FILE__, __LINE__, __exp, __act, (message) ? (message) : "No message"); \ g_test_registry.failed_count++; \ return; \ } \ } while(0) /* ------------------------------------------------------------------------------------------------------------------ */ /* */ // 基础断言宏 #define ASSERT_TRUE(condition) \ do { \ if (!(condition)) { \ printf(" " COLOR_RED "[FAIL] %s:%d: Assertion failed: (%s)" COLOR_RESET "\n", __FILE__, __LINE__, #condition); \ g_test_registry.failed_count++; \ return; \ } \ } while(0) #define ASSERT_INT_EQ(expected, actual) \ do { \ if ((expected) != (actual)) { \ printf(" " COLOR_RED "[FAIL] %s:%d: Expected %d, but got %d" COLOR_RESET "\n", __FILE__, __LINE__, (int)(expected), (int)(actual)); \ g_test_registry.failed_count++; \ return; \ } \ } while(0) #define ASSERT_LL_EQ(expected, actual) \ do { \ if ((expected) != (actual)) { \ printf(" " COLOR_RED "[FAIL] %s:%d: Expected %"PRId64", but got %"PRId64 COLOR_RESET "\n", __FILE__, __LINE__, (uint64_t)(expected), (uint64_t)(actual)); \ g_test_registry.failed_count++; \ return; \ } \ } while(0) #define ASSERT_PTR_NOT_NULL(ptr) ASSERT_TRUE(ptr!=NULL) // ========================================== // 核心运行宏(支持自定义配置环境) // ========================================== // 核心通用运行宏(内部使用) #define _RUN_TEST_CORE(test_func, setup, teardown) \ do { \ printf(COLOR_BLUE "[RUN ]" COLOR_RESET " %s\n", #test_func); \ \ /* 1. 执行专属启动函数 */ \ void (*st)(void) = (setup); \ if (st) st(); \ \ int initial_failed = g_test_registry.failed_count; \ clock_t start_time = clock(); \ \ /* 2. 执行测试函数 */ \ test_func(); \ \ clock_t end_time = clock(); \ double elapsed_ms = ((double)(end_time - start_time) / CLOCKS_PER_SEC) * 1000.0; \ g_test_registry.total_time_ms += elapsed_ms; \ \ /* 3. 执行专属关闭函数 */ \ void (*td)(void) = (teardown); \ if (td) td(); \ \ /* 4. 带颜色状态输出 */ \ if (g_test_registry.failed_count == initial_failed) { \ printf(COLOR_GREEN "[ OK]" COLOR_RESET " %s (%.2f ms)\n", #test_func, elapsed_ms); \ g_test_registry.passed_count++; \ } else { \ printf(COLOR_RED "[FAIL]" COLOR_RESET " %s (%.2f ms)\n", #test_func, elapsed_ms); \ } \ printf("-------------------------------------------\n"); \ } while(0) // 宏 1:支持绑定专属环境的运行宏 #define RUN_TEST_FIXTURE(test_func, setup, teardown) _RUN_TEST_CORE(test_func, setup, teardown) // 宏 2:普通运行宏(无需任何启动/关闭环境) #define RUN_TEST(test_func) _RUN_TEST_CORE(test_func, NULL, NULL) /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define TEST_START(Name) do{ \ printf(COLOR_BOLD "===========================================\n"); \ printf(" %s \n", #Name);\ printf("===========================================\n" COLOR_RESET); }while(0) #define TEST_REPORT()\ do{ \ printf(COLOR_BOLD "===========================================\n"); \ printf("TEST SUMMARY:\n" COLOR_RESET); \ printf(" Total Executed : %d\n", g_test_registry.passed_count + g_test_registry.failed_count); \ printf(COLOR_GREEN " Passed : %d\n" COLOR_RESET, g_test_registry.passed_count); \ printf(COLOR_RED " Failed : %d\n" COLOR_RESET, g_test_registry.failed_count); \ printf(" Total Time : %.2f ms\n", g_test_registry.total_time_ms); \ printf(COLOR_BOLD "===========================================\n" COLOR_RESET);\ }while (0) #define RETURN_TEST_STATUS return (g_test_registry.failed_count > 0 ? 1 : 0) #define TEST_CASE(name) static void name(void) #endif /*INCLUDED_C_TEST_H*/