第二章 自动化测试基础概念
各位同学好,我是老张。今天咱们聊聊自动化测试的基础概念。说实话,我见过太多人一上来就搞自动化,结果搞得一团糟。为什么?因为基础没打牢。这一章,我就把自动化测试的底裤给你扒干净。
什么是自动化测试
自动化测试,说白了就是用代码代替手工去执行测试。你想想看,一个剃须刀要测试开关机1000次,手动按得手都抽筋了。自动化测试就是写个脚本,让机器替你按这1000次。
我个人习惯把自动化测试分成三个层次:
- 单元测试:测试单个函数、单个模块。比如测试一个电压读取函数是否返回正确值。
- 集成测试:测试多个模块配合工作。比如测试电机驱动和PWM控制能否协同工作。
- 系统测试:测试整个产品功能。比如模拟用户从开机到充电完成的全流程。
我在项目中遇到过最典型的例子:一个同事写了2000行测试代码,结果发现连最基本的GPIO初始化都没测到。嗯,这就是典型的「为了自动化而自动化」。
嵌入式测试的挑战
嵌入式测试和纯软件测试不一样。为什么?因为嵌入式系统有硬件!我刚开始做嵌入式测试时,觉得和Web测试差不多,结果被现实狠狠打脸。
嵌入式测试的主要挑战有:
| 挑战 | 说明 | 我的经验 |
|---|---|---|
| 硬件依赖 | 测试必须依赖真实硬件或仿真器 | 我曾经因为仿真器驱动版本不对,浪费了整整两天 |
| 资源受限 | MCU内存小、Flash小,跑不了大型测试框架 | 我建议用轻量级框架,比如Unity、CMock |
| 实时性要求 | 很多功能有严格的时间约束 | 比如PWM波形必须精确到微秒级 |
| 调试困难 | 出问题很难定位是硬件还是软件 | 我习惯先隔离硬件,用模拟器跑一遍 |
避坑指南: 我曾经接手过一个项目,测试代码里直接操作了硬件寄存器。结果换了一个芯片型号,所有测试全部失效。记住:测试代码也要考虑可移植性!
自动化测试 vs 手动测试
很多新手问我:「老张,是不是自动化测试能完全替代手动测试?」我的回答是:想得美!
咱们来对比一下:
- 自动化测试的优势:
- 跑得快:一秒能跑几百个测试用例
- 重复性好:每次执行结果一致
- 适合回归测试:改完代码一键跑
- 手动测试的优势:
- 探索性强:能发现意想不到的问题
- 适合用户体验测试:比如剃须刀握持手感
- 初期成本低:不用写代码
我个人习惯是:核心功能用自动化,边缘场景用手动。举个例子,剃须刀的电机启停功能,我肯定写自动化脚本跑1000次。但用户实际使用时的各种奇葩操作,比如一边充电一边用,这种我建议手动测一测。
小技巧: 我建议把自动化测试和手动测试的比例控制在7:3左右。自动化覆盖核心功能,手动覆盖异常场景。这样既高效又全面。
测试金字塔模型
测试金字塔这个概念,说白了就是告诉你测试应该怎么分层。我见过太多人把精力全放在UI测试上,结果底层逻辑一堆bug。你想想看,地基都没打好,装修再漂亮有什么用?
经典的测试金字塔分三层:
- 底层:单元测试(占比约70%)
这是金字塔的基石。测试单个函数、单个模块。比如测试一个计算电池电量的函数:
// 测试电池电量计算函数 void test_battery_level(void) { // 输入电压3.7V,应该返回100% TEST_ASSERT_EQUAL(100, calculate_battery_level(3.7)); // 输入电压3.0V,应该返回0% TEST_ASSERT_EQUAL(0, calculate_battery_level(3.0)); // 输入电压3.3V,应该返回50% TEST_ASSERT_EQUAL(50, calculate_battery_level(3.3)); } - 中间层:集成测试(占比约20%)
测试多个模块的配合。比如测试电机驱动和PWM控制能否协同工作:
// 测试电机启动流程 void test_motor_start(void) { // 设置PWM占空比为50% pwm_set_duty(50); // 启动电机 motor_start(); // 验证电机转速是否在预期范围内 uint32_t speed = motor_get_speed(); TEST_ASSERT_TRUE(speed > 1000 && speed < 2000); } - 顶层:系统测试(占比约10%)
测试整个产品功能。比如模拟用户操作全流程:
// 测试用户完整使用流程 void test_user_scenario(void) { // 1. 按下电源键 press_power_button(); delay_ms(100); // 2. 验证电机启动 TEST_ASSERT_TRUE(motor_is_running()); // 3. 使用5秒后关机 delay_ms(5000); press_power_button(); // 4. 验证电机停止 TEST_ASSERT_FALSE(motor_is_running()); }
核心要点: 测试金字塔告诉我们,底层测试要写得多,顶层测试要写得少。我见过最离谱的项目,系统测试写了500个用例,单元测试只有20个。结果每次改代码,系统测试跑一遍要3小时,而且出了问题还不好定位。后来我帮他们重构,把重心放到单元测试上,问题定位效率提升了10倍。
嗯,这一章的内容就到这里。记住:自动化测试不是万能药,但用好了绝对是利器。下一章咱们聊聊嵌入式测试框架的选择,我会分享一些我踩过的坑和总结的经验。