Vibe Tutorial
功能测试流程与自动化脚本

8.6 UI测试实战

Tip

按钮如果不能点,那它就只是一幅画。很多时候,用户点不到按钮不是因为按钮坏了,而是因为被别的隐形东西挡住了。


1. 为什么要学这个?

你的用户给你发邮件:“我点那个注册按钮没反应啊!” 你打开电脑,点击注册,一切正常。你回邮件说:“是你网络问题吧?”

实际上,是因为运营团队刚刚加了一个 “Cookie 同意” 的弹窗。这个弹窗虽然设置了透明度为 0 (看不见),但它覆盖了整个屏幕。 用户以为自己在点按钮,其实是在点那层看不见的玻璃。

Playwright 的 .click() 自带防呆机制。如果元素被遮挡,它会立刻报错,而不是傻傻地通过测试。


2. 核心概念:Happy Path & Sad Path

设计测试用例时,要把用户分成两种:

1. Happy Path (快乐路径)

一切正常,用户完全按照你的预期操作。

  • 输入正确账号 -> 输入正确密码 -> 登录成功。

2. Sad Path (悲观路径)

用户各种“作死”的操作。

  • 不填必填项 -> 应提示“不能为空”。
  • 乱填格式 -> 应提示“邮箱格式错误”。
  • 断网提交 -> 应提示“网络连接中断”。

只测快乐路径的测试,就像只在晴天试飞的飞机,一遇风暴就坠毁。


3. 代码实战:测一个登录框

import { test, expect } from '@playwright/test';

// 使用 test.describe 分组,让报告更清晰
test.describe('登录功能', () => {
  
  // 钩子:每个测试前都先去登录页
  test.beforeEach(async ({ page }) => {
    await page.goto('/login');
  });

  // ✅ 场景一:快乐路径
  test('输入正确账号应跳转', async ({ page }) => {
    await page.getByLabel('Email').fill('user@example.com');
    await page.getByLabel('Password').fill('password123');
    await page.getByRole('button', { name: 'Log In' }).click();
    
    // 验证:网址变了
    await expect(page).toHaveURL('/dashboard');
  });

  // ❌ 场景二:密码错误 (悲观路径)
  test('密码错误应提示', async ({ page }) => {
    await page.getByLabel('Email').fill('user@example.com');
    await page.getByLabel('Password').fill('wrongpass'); 
    await page.getByRole('button', { name: 'Log In' }).click();
    
    // 验证:出现了红色的错误提示
    const error = page.getByText('Invalid email or password');
    await expect(error).toBeVisible();
    // 验证:还在原地,没跳转
    await expect(page).toHaveURL('/login');
  });

  // 🔍 场景三:防重复提交
  test('点击后按钮应变灰', async ({ page }) => {
    // ...填表单...
    const btn = page.getByRole('button', { name: 'Log In' });
    
    await btn.click();
    
    // 验证:防止用户狂点,按钮必须变 Disabled
    await expect(btn).toBeDisabled();
  });
});

4. 真实案例

Story

看不见的“隐形盾牌”

某知名电商在双十一前夕,给首页加了一个促销弹窗。为了不打扰用户,前端把它的透明度设为了 0,准备等活动开始那一秒再显示。 但他忘记了设置 pointer-events: none(或者 display: none)。 后果: 那个看不见的弹窗像一块巨大的玻璃,挡住了底下所有的商品链接。 用户疯狂点击“购买”,没有任何反应。当晚前 2 小时,成交额为 0

Playwright 的价值: 如果跑了 Playwright 测试,脚本在执行 await page.click('购买') 时会立刻报错: Element is intercepted by <div class="promo-popup"> (元素被弹窗遮挡)。 机器人比人类更诚实。它点不到就是点不到,绝不会因为“看着像能点”就放过 bug。


5. 本章小结

  1. 覆盖全:只测开心路径是不够的,悲观路径才是 bug 的温床。
  2. 测交互:除了测跳转,还要测按钮变灰、菊花转圈这些中间状态。
  3. 防遮挡:Playwright 天然具备检测 UI 遮挡的能力,善用它来发现那些“隐形盾牌”。