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管理起来很顺手。

搭建步骤其实不复杂,我拆解一下:

  1. 安装Pytestpip install pytest
  2. 安装相关插件:比如pytest-html(生成报告)、pytest-xdist(并行执行)
  3. 创建测试文件:文件名以test_开头,或者以_test结尾
  4. 编写测试函数:函数名以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或者条件判断。否则,测试失败了你都不知道是代码问题还是环境问题。

好了,这一章的内容就这些。自动化测试框架的搭建和脚本规范,说白了就是“把重复的事情交给机器,把规范的事情交给流程”。你按我说的做,至少能省下一半的测试时间。

下一章,我会聊聊测试报告的生成和结果分析。嗯,那也是个有意思的话题。