前端基础教程(软件测试人员专用)¶
教程简介
本教程面向软件测试工程师,讲解测试工作中需要了解的前端基础知识:HTML 结构、CSS 选择器、JavaScript 语法、浏览器调试工具。
前置要求¶
| 项目 | 要求 | 获取方式 |
|---|---|---|
| HTML/CSS 基础概念 | 了解网页由标签组成,能区分 HTML 和 CSS 的作用 | 自行搜索"HTML 入门"或参考 W3School |
新手导读¶
测试人员学前端,不是为了转前端开发,而是为了看懂页面结构、定位元素、判断问题发生在前端还是后端。
第一遍重点掌握:
- HTML 标签表示页面结构。
- CSS 选择器可以帮助自动化定位元素。
- JavaScript 会触发页面交互和接口请求。
- 浏览器开发者工具可以查看元素、网络请求和控制台错误。
学完后,你应该能打开浏览器 DevTools,找到按钮或输入框对应的 HTML,并能在 Network 面板里找到一次接口请求。
一、为什么要学前端基础¶
| 场景 | 用途 |
|---|---|
| 元素定位 | Selenium/Playwright 定位元素需要理解 HTML 结构 |
| 接口分析 | 看懂前端请求/响应数据格式 |
| Bug 定位 | 判断问题是前端还是后端 |
| 抓包分析 | 理解请求头、Cookie、存储 |
| 自动化测试 | 编写更稳定的定位表达式 |
| 安全测试 | 理解 XSS、CSRF 等漏洞原理 |
二、HTML 基础¶
2.1 什么是 HTML¶
HTML(HyperText Markup Language)是网页的骨架,用标签描述页面结构。
<!DOCTYPE html>
<html>
<head>
<title>页面标题</title>
</head>
<body>
<h1>一级标题</h1>
<p>这是一个段落。</p>
<a href="https://example.com">链接</a>
<img src="photo.jpg" alt="图片描述">
</body>
</html>
2.2 常用标签¶
| 标签 | 用途 | 示例 |
|---|---|---|
<div> |
块级容器 | <div class="header">...</div> |
<span> |
行内容器 | <span class="error">错误信息</span> |
<a> |
链接 | <a href="/login">登录</a> |
<button> |
按钮 | <button id="submit">提交</button> |
<input> |
输入框 | <input type="text" name="username"> |
<select> |
下拉框 | <select name="city">...</select> |
<form> |
表单 | <form action="/api/login">...</form> |
<table> |
表格 | <table><tr><td>单元格</td></tr></table> |
<img> |
图片 | <img src="logo.png" alt="Logo"> |
<ul> / <ol> |
列表 | <ul><li>项目1</li></ul> |
<h1>-<h6> |
标题 | <h1>一级标题</h1> |
<p> |
段落 | <p>文本内容</p> |
2.3 元素属性¶
属性是标签的附加信息,测试中最重要的是 id、class、name。
<input
type="text"
id="username"
class="form-control"
name="username"
placeholder="请输入用户名"
data-testid="login-input"
value="testuser"
disabled
>
| 属性 | 说明 |
|---|---|
type |
输入类型 |
id |
唯一标识(测试首选) |
class |
样式类名(可多个) |
name |
表单字段名 |
placeholder |
占位符 |
data-testid |
测试专用属性(推荐) |
value |
值 |
disabled |
禁用 |
测试定位优先级:
2.4 表单元素¶
<!-- 文本输入 -->
<input type="text" name="username">
<input type="password" name="password">
<input type="email" name="email">
<input type="number" name="age">
<input type="tel" name="phone">
<!-- 多行文本 -->
<textarea name="comment"></textarea>
<!-- 复选框 -->
<input type="checkbox" name="agree" value="yes">
<!-- 单选框 -->
<input type="radio" name="gender" value="male"> 男
<input type="radio" name="gender" value="female"> 女
<!-- 下拉框 -->
<select name="city">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
<!-- 文件上传 -->
<input type="file" name="avatar">
<!-- 隐藏字段 -->
<input type="hidden" name="token" value="abc123">
<!-- 按钮 -->
<button type="submit">提交</button>
<button type="button">普通按钮</button>
<input type="submit" value="提交">
2.5 iframe¶
iframe 是页面中嵌套的另一个页面:
测试时需要切换到 iframe 内部才能操作元素。
2.6 Shadow DOM¶
Web Components 使用 Shadow DOM 封装内部结构:
Playwright 原生支持 Shadow DOM,Selenium 需要特殊处理。
三、CSS 选择器¶
CSS 选择器是 Selenium/Playwright 定位元素的基础。
3.1 基本选择器¶
| 选择器 | 含义 | 示例 |
|---|---|---|
#id |
按 ID | #username |
.class |
按类名 | .form-control |
tag |
按标签 | button |
tag.class |
标签+类 | button.btn-primary |
tag#id |
标签+ID | input#username |
3.2 属性选择器¶
| 选择器 | 含义 | 示例 |
|---|---|---|
[attr] |
有该属性 | [disabled] |
[attr="val"] |
属性等于 | [type="submit"] |
[attr~="val"] |
属性包含词 | [class~="active"] |
[attr^="val"] |
属性以...开头 | [href^="https"] |
[attr$="val"] |
属性以...结尾 | [href$=".pdf"] |
[attr*="val"] |
属性包含 | [href*="login"] |
3.3 关系选择器¶
| 选择器 | 含义 | 示例 |
|---|---|---|
A B |
A 的后代 B | div p(div 内所有 p) |
A > B |
A 的直接子 B | ul > li |
A + B |
A 紧邻的兄弟 B | h1 + p |
A ~ B |
A 后面的所有兄弟 B | h1 ~ p |
3.4 伪类选择器¶
| 选择器 | 含义 | 示例 |
|---|---|---|
:first-child |
第一个子元素 | li:first-child |
:last-child |
最后一个子元素 | li:last-child |
:nth-child(n) |
第 n 个子元素 | tr:nth-child(2) |
:not(selector) |
排除 | input:not([disabled]) |
:checked |
选中的复选框 | input:checked |
:enabled |
可用的 | button:enabled |
:focus |
获得焦点的 | input:focus |
3.5 测试常用 CSS 选择器¶
/* 登录按钮 */
#login-btn
button[type='submit']
.form-actions button.btn-primary
/* 错误消息 */
.error-message
.alert-danger
span.error
/* 表格第一行 */
table tbody tr:first-child
/* 导航菜单项 */
nav ul > li > a
/* 输入框 */
input[name='username']
input.form-control:not([disabled])
四、JavaScript 基础¶
4.1 为什么要了解 JS¶
- 理解前端逻辑(页面交互、接口调用)
- 在自动化中执行 JS(Playwright
page.evaluate()) - 看懂控制台报错
- 理解前端存储(Cookie、localStorage、sessionStorage)
4.2 基础语法¶
// 变量
let name = "张三"; // 可变
const age = 25; // 不可变
var old = "旧语法"; // 避免使用
// 数据类型
let str = "hello"; // 字符串
let num = 123; // 数字
let bool = true; // 布尔
let arr = [1, 2, 3]; // 数组
let obj = {name: "张三"}; // 对象
let nullVal = null; // 空值
let undef; // undefined
// 字符串
`hello ${name}` // 模板字符串
"hello" + name // 拼接
str.length // 长度
str.includes("ell") // 包含
str.replace("l", "L") // 替换
// 数组
arr.push(4); // 添加
arr.pop(); // 删除最后一个
arr.length; // 长度
arr.includes(2); // 包含
arr.map(x => x * 2); // 映射
arr.filter(x => x > 1); // 过滤
// 对象
obj.name // 访问
obj["name"] // 等价
obj.age = 30; // 修改/添加
4.3 函数¶
// 普通函数
function greet(name) {
return `你好, ${name}`;
}
// 箭头函数
const greet = (name) => `你好, ${name}`;
// 异步函数
async function getData() {
const response = await fetch("/api/data");
const data = await response.json();
return data;
}
4.4 DOM 操作¶
// 获取元素
document.getElementById("username")
document.querySelector(".form-control") // 第一个匹配
document.querySelectorAll("input[type='text']") // 所有匹配
// 操作元素
el.textContent = "新文本";
el.value = "新值";
el.style.display = "none"; // 隐藏
el.classList.add("active"); // 添加类
el.classList.remove("active"); // 删除类
el.setAttribute("disabled", ""); // 设置属性
// 事件
el.addEventListener("click", () => {
console.log("被点击了");
});
4.5 浏览器存储¶
// Cookie(每次请求自动携带)
document.cookie = "sessionId=abc123; path=/";
document.cookie // 读取所有
// localStorage(永久存储,除非手动清除)
localStorage.setItem("token", "eyJ...");
localStorage.getItem("token");
localStorage.removeItem("token");
localStorage.clear();
// sessionStorage(会话存储,关闭标签页清除,同源新标签页不共享)
sessionStorage.setItem("key", "value");
sessionStorage.getItem("key");
4.6 网络请求¶
// fetch API
fetch("/api/user", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({name: "张三"})
})
.then(response => response.json())
.then(data => console.log(data));
// 异步版本
const response = await fetch("/api/user");
const data = await response.json();
五、浏览器开发者工具¶
5.1 打开方式¶
- F12
- Ctrl+Shift+I(Windows)
- Cmd+Option+I(Mac)
- 右键 → 检查
5.2 核心面板¶
Elements(元素): - 查看/修改 HTML 结构 - 查看/修改 CSS 样式 - 右键元素 → Copy → Copy selector(获取 CSS 选择器) - 右键元素 → Copy → Copy XPath
Console(控制台):
- 执行 JavaScript
- 查看错误信息
- 测试选择器:document.querySelector("#btn")
Network(网络): - 查看所有 HTTP 请求 - 查看请求/响应详情 - 过滤:XHR(接口)、JS、CSS、Img - 查看请求头、响应体、Cookie
Application(应用): - 查看 Cookie - 查看 localStorage / sessionStorage - 查看缓存
5.3 测试常用操作¶
获取元素选择器: 1. Elements 面板选中元素 2. 右键 → Copy → Copy selector 3. 在 Selenium/Playwright 中使用
查看接口请求: 1. Network 面板 → 筛选 XHR 2. 点击请求 → Headers/Preview/Response 3. 查看请求参数、响应数据
模拟网络条件: 1. Network 面板 → Throttling 2. 选择 Slow 3G / Fast 3G / Offline
清除缓存: 1. Application 面板 → Storage → Clear site data
六、测试场景实战¶
6.1 场景一:定位元素¶
问题: Selenium 找不到元素。
排查: 1. F12 → Elements 面板 2. Ctrl+F 搜索选择器 3. 检查元素是否在 iframe 中 4. 检查元素是否被 Shadow DOM 封装 5. 检查元素是否动态生成(需等待)
6.2 场景二:判断前端还是后端 Bug¶
前端 Bug 特征: - 页面显示异常但接口数据正确 - 按钮点击无反应(JS 报错) - 样式错乱 - 控制台有红色错误
后端 Bug 特征: - 接口返回错误状态码 - 接口返回数据不正确 - 页面显示的是接口返回的错误信息
排查步骤: 1. F12 → Network 面板 2. 找到对应接口请求 3. 查看请求参数是否正确 4. 查看响应数据是否正确 5. 请求正确但显示异常 → 前端 Bug 6. 请求本身就有问题 → 后端 Bug
6.3 场景三:查看接口请求详情¶
- F12 → Network → 筛选 XHR
- 触发操作(如点击按钮)
- 点击对应的请求
- 查看:
- Headers:请求方法、URL、请求头、Cookie
- Payload:请求参数
- Preview/Response:响应数据
- Timing:耗时分析
6.4 场景四:修改页面元素¶
临时修改页面用于测试:
// 在 Console 中执行
// 修改文本
document.querySelector(".price").textContent = "¥0.01";
// 修改按钮状态
document.querySelector("#submit").removeAttribute("disabled");
// 修改隐藏元素为可见
document.querySelector(".hidden-panel").style.display = "block";
// 模拟登录态
localStorage.setItem("token", "test-token-123");
6.5 场景五:抓取动态加载的数据¶
- F12 → Network → 筛选 XHR
- 刷新页面或触发操作
- 找到数据接口
- 查看请求参数和响应格式
- 在 Postman 中重建该请求
七、常见问题排查¶
7.1 元素找不到¶
- 检查是否在 iframe 中
- 检查是否是动态生成的(需等待)
- 检查是否有 Shadow DOM
- 用
document.querySelectorAll()在控制台验证选择器
7.2 控制台报错¶
常见错误:
| 错误 | 含义 |
|---|---|
Uncaught TypeError |
类型错误(如调用 undefined 的方法) |
Uncaught ReferenceError |
变量未定义 |
CORS error |
跨域请求被阻止 |
404 Not Found |
资源不存在 |
500 Internal Server Error |
服务器错误 |
7.3 接口请求看不到¶
- 确认 Network 面板是否在录制(红色圆点)
- 检查是否被筛选条件排除
- 检查是否是 WebSocket 请求(WS 标签)
- 检查是否在 Service Worker 中
7.4 页面加载慢¶
- Network 面板查看瀑布图
- 找到耗时最长的请求
- 检查是否是大文件(图片、JS)
- 检查是否是接口响应慢
- 检查是否有阻塞渲染的资源
附录:常用快捷键¶
| 快捷键 | 功能 |
|---|---|
| F12 | 打开开发者工具 |
| Ctrl+Shift+I | 打开开发者工具 |
| Ctrl+Shift+C | 选择元素模式 |
| Ctrl+F | 在 Elements 中搜索 |
| Ctrl+L | 清空 Console |
| Ctrl+R | 刷新页面 |
| Ctrl+Shift+R | 强制刷新(跳过缓存) |
建议
不需要精通前端开发,但要能看懂 HTML 结构、理解 CSS 选择器、会用浏览器开发者工具。这些技能在元素定位、Bug 定位、接口分析中非常实用。
推荐下一步¶
根据你的学习进度,选择下一步:
- 如果你想深入 JS:学习 JavaScript 基础教程,掌握 DOM 操作和异步
- 如果你想学 TypeScript:学习 TypeScript 基础教程,为 Playwright 做准备
- 如果你想直接进入自动化:学习 Selenium Web 自动化,用代码操控浏览器
通关检查¶
完成本阶段后,使用 第1阶段-测试入门通关 检查是否可以进入下一阶段。