2. 车载测试基础

写自动化测试脚本,说白了就是在写代码。但很多人把它当成一次性工具,跑通就扔。我见过太多项目,脚本跑三个月就全崩了——不是因为被测系统变了,而是脚本自己先烂了。

为什么会这样?因为大家只关注「能不能跑」,忽略了脚本的「体质」。这一章我们就聊聊测试脚本设计的五个核心原则。我个人习惯把它们简称为「五可原则」:可维护、可读、可重用、稳定、独立。

核心观点: 自动化测试脚本不是消耗品,而是长期资产。设计阶段的投入,决定了脚本能活多久。
测试脚本设计五可原则 测试脚本设计原则 可维护性 可读性 可重用性 稳定性 独立性 五个原则相互支撑:可读性降低维护成本,独立性提升稳定性,可重用性减少重复代码 忽略任何一个,脚本都会在迭代中快速腐烂

2.1 可维护性:让脚本活得更久

可维护性是我最看重的一条。你想想看,一个自动化项目通常要跑几个月甚至几年。如果脚本改不动,那还不如不写。

我在项目中遇到过最典型的反面教材:一个登录脚本里硬编码了数据库连接字符串、测试账号密码、甚至还有页面元素的 XPath。结果 UI 一改,整个脚本直接报废。改一个地方要翻遍几十个文件。

怎么提升可维护性?记住三点:

  • 配置与代码分离——环境地址、账号密码、超时时间,全部抽到配置文件里
  • 页面元素集中管理——用 Page Object 模式,一个页面只维护一套元素定位
  • 减少硬编码——能用枚举就别写死字符串,能用变量就别重复数字
我的习惯: 每个脚本开头都问自己一句——「如果明天 UI 变了,我改几行代码?」答案超过 3 行,说明设计有问题。

2.2 可读性:脚本是写给人看的

很多人觉得脚本能跑就行,管它好不好看。但你想过没有——三个月后你自己回来看这段代码,还能一眼看懂吗?

可读性差带来的后果很直接:新人不敢改,老人不想改,最后整个脚本库变成「黑盒遗产」。我记得有一次接手一个项目,一个测试方法写了 300 行,没有注释,变量名全是 a、b、c。我花了整整两天才搞清楚它在测什么。

提升可读性的几个实操建议:

  • 命名要有意义——testLoginWithValidCredentials 比 test_01 强一百倍
  • 一个方法只做一件事——超过 20 行就考虑拆分
  • 加注释,但别废话——解释「为什么这么做」,而不是「做了什么」
  • 保持一致的代码风格——缩进、空行、括号位置,团队统一
// ❌ 不推荐:看不懂在测什么
@Test
public void t1() {
    driver.findElement(By.id("u")).sendKeys("admin");
    driver.findElement(By.id("p")).sendKeys("123456");
    driver.findElement(By.id("b")).click();
    Assert.assertTrue(driver.getTitle().contains("欢迎"));
}

// ✅ 推荐:一目了然
@Test
public void testLoginWithValidCredentials() {
    loginPage.enterUsername("admin");
    loginPage.enterPassword("123456");
    loginPage.clickLoginButton();
    String actualTitle = dashboardPage.getPageTitle();
    Assert.assertTrue("登录后应跳转到仪表盘", actualTitle.contains("欢迎"));
}

2.3 可重用性:别重复造轮子

你想想看,一个项目里如果有 10 个测试用例都要做登录操作,你是写 10 遍登录代码,还是封装成一个方法?答案显而易见。

可重用性的核心就是「一次编写,多处调用」。我见过最高效的团队,他们的公共方法库覆盖了 80% 的常用操作——登录、注册、搜索、分页、文件上传,全部封装好。新用例只需要组合这些方法就行。

实现可重用性的常用手段:

手段 说明 示例
公共方法封装 将重复操作提取为独立方法 login(username, password)
测试数据工厂 统一管理测试数据的生成 UserFactory.createRandomUser()
基类继承 公共逻辑放在父类中 BaseTest.setup()
工具类 与业务无关的通用功能 DateUtils.format()
注意: 可重用性不是越高越好。过度抽象会让代码变得晦涩难懂。我曾经见过一个「万能方法」,参数多达 12 个,调用时根本不知道每个参数是干嘛的。适度封装,够用就好。

2.4 稳定性:别让脚本「抽风」

自动化测试最让人头疼的是什么?不是被测系统有 bug,而是脚本自己不稳定——今天跑通过,明天跑失败,后天又通过了。这种「抽风式」的脚本,谁都不敢信。

我曾经被一个脚本坑过:它每周五下午必挂一次,排查了整整两周才发现,是因为服务器在那个时间点做定时备份,响应变慢了。脚本没做等待处理,直接报超时。

提升稳定性的几个关键点:

  • 显式等待代替固定休眠——Thread.sleep(3000) 是万恶之源
  • 增加重试机制——网络抖动、页面加载延迟,重试一次往往就能解决
  • 做好异常处理——捕获具体异常,而不是笼统的 Exception
  • 记录失败现场——截图、日志、页面源码,方便排查
// ❌ 不推荐:固定等待,不稳定
Thread.sleep(5000);
driver.findElement(By.id("submit")).click();

// ✅ 推荐:显式等待,稳定可靠
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement submitBtn = wait.until(
    ExpectedConditions.elementToBeClickable(By.id("submit"))
);
submitBtn.click();

2.5 独立性:各扫门前雪

独立性原则说的是:每个测试用例应该独立运行,不依赖其他用例的执行结果。这个原则看似简单,但实际项目中经常被违反。

我见过最离谱的例子:一个测试套件里,用例 A 先注册用户,用例 B 再用这个用户登录。如果 A 失败了,B 必然失败。排查问题时,你根本分不清是 A 的 bug 还是 B 的 bug。

独立性的具体要求:

  • 不依赖执行顺序——随便打乱顺序,每个用例都能跑
  • 不共享状态——每个用例自己准备数据、自己清理数据
  • 不依赖外部环境——尽量用 Mock 或测试替身,减少对真实服务的依赖
  • 失败不影响他人——一个用例挂了,其他用例照常运行
判断标准: 如果你能随机打乱所有用例的执行顺序,并且每个用例都能独立通过,那独立性就达标了。

2.6 五可原则的优先级与取舍

五个原则都很重要,但实际项目中不可能面面俱到。我个人习惯按这个优先级排序:

  1. 稳定性——脚本跑不稳,其他都是空谈
  2. 独立性——用例互相依赖,排查成本指数级上升
  3. 可维护性——脚本要活过三个迭代,必须好改
  4. 可读性——团队协作的基础
  5. 可重用性——锦上添花,但别过度设计

当然,这不是绝对的。如果你的项目只有一个人维护,可读性可能就没那么紧迫。但如果团队有 10 个人,可读性和可维护性就得排到前面去。你想想看,是不是这个道理?

避坑指南: 我曾经在项目初期过度追求可重用性,写了一大堆抽象类和接口。结果后来需求变了,那些抽象层反而成了改动的障碍。后来我学乖了——先写能跑的脚本,再逐步重构。别一开始就想着「完美设计」。