4、自动化测试框架:Selenium/Appium在座舱系统中的应用、Pytest框架搭建、测试脚本编写规范
自动化测试,说白了就是让机器替你干活。座舱系统的UI测试,手动点来点去太慢了,而且容易漏掉细节。我这些年带团队,最深的体会就是——没有自动化,迭代就是空谈。
这一章,我重点聊聊Selenium和Appium怎么用在座舱系统上,Pytest框架怎么搭,以及脚本怎么写才规范。嗯,都是实战中踩过的坑,希望能帮你少走弯路。
4.1 Selenium与Appium在座舱系统中的应用
先说说这两个工具的区别。Selenium是给Web页面用的,Appium是给原生App用的。座舱系统呢?它俩都用得上。
为什么?因为现在的座舱系统,很多是混合架构——既有Web页面(比如HMI的某些设置界面),也有原生组件(比如仪表盘、导航)。我遇到过的一个项目,中控屏的娱乐系统是Web的,但车辆控制模块是原生的。你想想看,只用一种工具根本搞不定。
核心思路:Web部分用Selenium,原生部分用Appium。两者可以配合使用,通过同一个测试脚本来调度。
具体怎么用?我举个例子。座舱系统的中控屏,有一个“空调温度调节”功能。如果是Web实现,Selenium可以这样定位元素:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://192.168.1.100:8080/hmi")
# 定位温度滑块
temp_slider = driver.find_element(By.ID, "temperature-slider")
temp_slider.send_keys("24") # 设置温度为24度
如果是原生App,Appium的写法类似,但定位方式不同:
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
desired_caps = {
"platformName": "Android",
"deviceName": "emulator-5554",
"appPackage": "com.cockpit.hmi",
"appActivity": ".MainActivity"
}
driver = webdriver.Remote("http://localhost:4723/wd/hub", desired_caps)
# 定位温度调节按钮
temp_up = driver.find_element(AppiumBy.ID, "com.cockpit.hmi:id/temp_up")
temp_up.click()
这里有个坑,我提醒一下。座舱系统的屏幕分辨率、DPI和手机不一样,元素定位时容易偏移。我建议用相对坐标或者XPath的文本匹配,别死磕ID。
4.2 Pytest框架搭建
Pytest是我个人最常用的测试框架。为什么?因为它简洁、灵活,而且插件生态好。座舱系统的测试用例多,用Pytest管理起来很顺手。
搭建步骤其实不复杂,我拆解一下:
- 安装Pytest:
pip install pytest - 安装相关插件:比如pytest-html(生成报告)、pytest-xdist(并行执行)
- 创建测试文件:文件名以
test_开头,或者以_test结尾 - 编写测试函数:函数名以
test_开头
一个典型的Pytest项目结构是这样的:
cockpit_tests/
├── conftest.py # 全局配置,比如driver初始化
├── test_home.py # 主页测试
├── test_navigation.py # 导航测试
├── test_climate.py # 空调测试
└── reports/ # 测试报告存放
conftest.py里,我习惯放fixture。比如初始化driver:
import pytest
from selenium import webdriver
@pytest.fixture(scope="module")
def driver():
# 启动浏览器
driver = webdriver.Chrome()
driver.maximize_window()
yield driver
# 测试结束后关闭
driver.quit()
这样写的好处是,每个测试用例都不用重复写启动和关闭的代码。我在项目中遇到过,有人把driver初始化写在每个测试函数里,结果代码冗余得一塌糊涂。嗯,千万别这么干。
4.3 测试脚本编写规范
规范这东西,一开始觉得麻烦,但真遇到问题你就知道它的好了。我见过太多团队,脚本写得随心所欲,结果维护成本比手动测试还高。
我总结了几条核心规范,你照着做基本不会出大问题:
| 规范项 | 说明 | 示例 |
|---|---|---|
| 命名规范 | 测试函数名要清晰表达测试意图 | test_temperature_set_to_24_degrees |
| 断言规范 | 每个测试至少有一个断言 | assert "24°C" in driver.page_source |
| 数据分离 | 测试数据不要硬编码在脚本里 | 用JSON或YAML文件存储数据 |
| 等待策略 | 不要用sleep,用显式等待 | WebDriverWait(driver, 10).until(...) |
| 日志记录 | 关键步骤要打印日志 | logging.info("设置温度成功") |
举个例子,一个规范的测试脚本大概长这样:
import pytest
import logging
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
logging.basicConfig(level=logging.INFO)
class TestClimateControl:
"""空调控制模块测试"""
def test_temperature_set_to_24(self, driver):
"""测试设置温度为24度"""
logging.info("开始测试:设置温度为24度")
# 定位温度滑块
slider = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "temperature-slider"))
)
slider.clear()
slider.send_keys("24")
# 验证温度显示
display = driver.find_element(By.ID, "temp-display")
assert "24" in display.text, f"温度显示异常,期望24,实际{display.text}"
logging.info("温度设置成功,显示正确")
小技巧:我习惯在脚本里加一个@pytest.mark.smoke标记,用来区分冒烟测试和全量测试。这样每次提交代码后,先跑冒烟测试,没问题再跑全量。效率高很多。
4.4 避坑指南
做座舱系统的自动化测试,有几个坑我踩过,分享给你:
- 元素定位不稳定:座舱系统的UI经常变,ID可能被改。我建议多用data-*属性或者文本匹配,少用XPath的绝对路径。
- 模拟器与真机差异:在模拟器上跑得好好的,一上真机就崩。我曾经被这个问题折腾了两天,后来发现是分辨率不同导致的。解决方案是,测试环境尽量和真机一致。
- 并发执行冲突:多个测试用例同时操作同一个界面元素,容易出问题。我建议用pytest-xdist时,给每个worker分配独立的测试数据。
注意:座舱系统的某些功能(比如导航、语音)依赖网络或硬件。自动化测试时,一定要做好mock或者条件判断。否则,测试失败了你都不知道是代码问题还是环境问题。
好了,这一章的内容就这些。自动化测试框架的搭建和脚本规范,说白了就是“把重复的事情交给机器,把规范的事情交给流程”。你按我说的做,至少能省下一半的测试时间。
下一章,我会聊聊测试报告的生成和结果分析。嗯,那也是个有意思的话题。