/** * @file test_on_pc.c * @brief 自动化测试 — 模拟完整的按键时序序列 * * 编译: * gcc -I inc -DAPP_DEBUG_LOG \ * tests/test_on_pc.c src/hal_mock.c src/led_driver.c src/btn_fsm.c src/app_controller.c \ * -o test_smart_led && ./test_smart_led * * 自动运行以下测试: * TEST 1: 单击 → OFF → ON * TEST 2: 双击 → ON → BLINK_SLOW * TEST 3: 长按 → 任意 → BREATHING * TEST 4: 单击退出呼吸灯 → BREATHING → OFF */ #ifndef APP_DEBUG_LOG #define APP_DEBUG_LOG #endif #include #include #include #include "hal_gpio.h" #include "led_driver.h" #include "btn_fsm.h" #include "app_controller.h" extern void mock_set_button(uint8_t pressed); static uint8_t btn_read_pin(uint8_t button_id) { (void)button_id; return HAL_GPIO_ReadPin(GPIO_PORT_A, GPIO_PIN_0); } /* 模拟 N 个 Tick(每个 5ms) */ static void run_ticks(int n) { for (int i = 0; i < n; i++) { Btn_Tick(); } } /* 模拟按下 */ static void press(void) { mock_set_button(1); run_ticks(4); /* 20ms > 15ms 去抖 */ } /* 模拟释放 */ static void release(void) { mock_set_button(0); run_ticks(4); } /* 模拟等待 N ms */ static void wait_ms(int ms) { run_ticks(ms / 5); } /* ======== 测试用例 ======== */ static void test_single_click(AppCtrl_S* app) { printf("\n========== TEST 1: Single Click (OFF → ON) ==========\n"); assert(AppCtrl_GetState(app) == APP_STATE_OFF); press(); release(); wait_ms(400); /* 等双击超时 */ AppState_E s = AppCtrl_GetState(app); printf("Result: %s\n", AppCtrl_StateName(s)); assert(s == APP_STATE_ON); printf("✅ PASS\n"); } static void test_double_click(AppCtrl_S* app) { printf("\n========== TEST 2: Double Click (ON → BLINK_SLOW) ==========\n"); assert(AppCtrl_GetState(app) == APP_STATE_ON); /* 第一次按下释放 */ press(); release(); wait_ms(100); /* 第二次按下释放(在 300ms 内) */ press(); release(); wait_ms(400); /* 等双击超时 */ AppState_E s = AppCtrl_GetState(app); printf("Result: %s\n", AppCtrl_StateName(s)); assert(s == APP_STATE_BLINK_SLOW); printf("✅ PASS\n"); } static void test_long_press(AppCtrl_S* app) { printf("\n========== TEST 3: Long Press (BLINK_SLOW → BREATHING) ==========\n"); assert(AppCtrl_GetState(app) == APP_STATE_BLINK_SLOW); press(); wait_ms(1200); /* 长按 1.2s > 1s 阈值 */ release(); wait_ms(100); AppState_E s = AppCtrl_GetState(app); printf("Result: %s\n", AppCtrl_StateName(s)); assert(s == APP_STATE_BREATHING); printf("✅ PASS\n"); } static void test_exit_breathing(AppCtrl_S* app) { printf("\n========== TEST 4: Single Click Exit (BREATHING → OFF) ==========\n"); assert(AppCtrl_GetState(app) == APP_STATE_BREATHING); press(); release(); wait_ms(400); AppState_E s = AppCtrl_GetState(app); printf("Result: %s\n", AppCtrl_StateName(s)); assert(s == APP_STATE_OFF); printf("✅ PASS\n"); } /* ======== 主测试入口 ======== */ int main(void) { printf("╔══════════════════════════════════════════╗\n"); printf("║ Smart LED — Automated Test Suite ║\n"); printf("╚══════════════════════════════════════════╝\n"); /* 初始化 */ LedDriver_S* led = Led_Create(GPIO_PORT_B, GPIO_PIN_0, 1); static Btn_FSM btn; Btn_Init(&btn, btn_read_pin, 0, 0); Btn_Start(&btn); AppCtrl_S* app = AppCtrl_Create(led, &btn); AppCtrl_Init(app); /* 运行测试 */ test_single_click(app); test_double_click(app); test_long_press(app); test_exit_breathing(app); /* 清理 */ Btn_Stop(&btn); AppCtrl_Destroy(app); Led_Destroy(led); printf("\n╔══════════════════════════════════════════╗\n"); printf("║ ALL TESTS PASSED ✅ ║\n"); printf("╚══════════════════════════════════════════╝\n"); return 0; }