Awesome Cheatsheet 自动化测试指南:Selenium/Jest 实战
自动化测试现状与痛点
你是否还在手动测试Web应用的每个功能点?是否因频繁的回归测试而耗费大量时间?根据GitHub 加速计划 / aw / awesome-cheatsheet项目统计,75%的开发者在测试环节花费超过30%的开发时间。本文将通过Selenium(浏览器自动化)和Jest(JavaScript测试框架)的实战案例,展示如何构建完整的前端自动化测试体系,将测试效率提升60%以上。
读完本文你将获得:
- Selenium环境搭建与核心API应用
- Jest测试用例设计与断言技巧
- 测试自动化工作流集成方案
- 常见UI测试场景的解决方案
- 测试报告生成与持续集成配置
项目测试架构概览
测试技术栈选型
Awesome Cheatsheet项目采用分层测试架构,结合多种测试工具确保代码质量:
| 测试类型 | 工具选择 | 应用场景 | 项目资源 |
|---|---|---|---|
| 单元测试 | Jest | JavaScript函数/组件测试 | jest-cheat-sheet |
| 集成测试 | Selenium | 跨浏览器流程测试 | tests/url_validate.py |
| 接口测试 | requests | HTTP端点验证 | requirements.txt |
| E2E测试 | Cypress | 关键用户旅程测试 | README.md |
测试工作流设计
Selenium实战指南
环境搭建与配置
Python环境准备
Awesome Cheatsheet项目使用Python作为Selenium脚本语言,依赖管理通过pip实现:
# 安装项目依赖
pip install -r requirements.txt
# 当前项目仅需requests库: [requirements.txt](https://gitcode.com/gh_mirrors/aw/awesome-cheatsheet/blob/e7507591b93e2cfd924a55e4ccb8056c44c43ac5/requirements.txt?utm_source=gitcode_repo_files)
Selenium安装与浏览器驱动配置
# 安装Selenium
pip install selenium==4.15.2
# 下载浏览器驱动(Chrome为例)
wget https://storage.googleapis.com/chrome-for-testing-public/118.0.5993.70/linux64/chromedriver-linux64.zip
unzip chromedriver-linux64.zip
chmod +x chromedriver-linux64/chromedriver
sudo mv chromedriver-linux64/chromedriver /usr/local/bin/
核心API与基础操作
页面导航与元素定位
以下示例基于项目中的URL验证测试扩展,实现完整的页面测试流程:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 初始化浏览器驱动
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 隐式等待
try:
# 导航到测试页面
driver.get("https://example.com")
# 元素定位(支持多种策略)
element_id = driver.find_element(By.ID, "content")
element_css = driver.find_element(By.CSS_SELECTOR, "div.container")
element_xpath = driver.find_element(By.XPATH, "//h1[contains(text(), 'Example')]")
# 显式等待示例
element = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CLASS_NAME, "target"))
)
# 页面交互
element.click()
driver.find_element(By.NAME, "username").send_keys("testuser")
# 获取页面信息
page_title = driver.title
assert "Example Domain" in page_title
finally:
driver.quit() # 确保浏览器关闭
项目URL验证测试解析
项目中的url_validate.py实现了链接有效性测试,核心代码解析:
# 正则表达式匹配Markdown中的链接格式
url_re = re.compile('.*\[.*\]\((.*)\)') # 第15行
# 读取README.md文件进行测试
file = '{current_dir}/../README.md'.format(current_dir=current_dir) # 第19行
# 发送HTTP请求验证链接状态
result = get(m.group(1), headers=headers) # 第26行
if result.status_code >= 400:
print('{file} line #{line} {url} return {code}'.format(
file=file, line=line, url=m.group(1), code=result.status_code)) # 第28-29行
高级场景应用
多浏览器兼容性测试
from selenium import webdriver
from selenium.webdriver.firefox.service import Service as FirefoxService
from webdriver_manager.firefox import GeckoDriverManager
def test_cross_browser():
# Chrome测试
chrome_driver = webdriver.Chrome()
chrome_driver.get("https://example.com")
# Firefox测试
firefox_driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()))
firefox_driver.get("https://example.com")
# 断言跨浏览器一致性
assert chrome_driver.title == firefox_driver.title
chrome_driver.quit()
firefox_driver.quit()
测试数据驱动
import csv
def load_test_data(filename):
"""从CSV文件加载测试数据"""
with open(filename, 'r') as f:
reader = csv.DictReader(f)
return [row for row in reader]
# 数据驱动测试示例
test_data = load_test_data('test_urls.csv')
for data in test_data:
driver.get(data['url'])
assert data['expected_title'] in driver.title
Jest测试框架实战
Jest环境配置
安装与初始化
# 初始化npm项目
npm init -y
# 安装Jest依赖
npm install --save-dev jest@29.7.0
在package.json中添加测试脚本:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}
单元测试核心概念
测试用例结构
// 基础测试结构
describe('字符串工具函数', () => {
// 测试套件
test('字符串反转功能', () => {
// 测试用例
const reverse = (str) => str.split('').reverse().join('');
// 断言
expect(reverse('hello')).toBe('olleh');
expect(reverse('')).toBe('');
expect(reverse('a')).toBe('a');
});
test('字符串截断功能', () => {
const truncate = (str, length) => str.length > length ? str.slice(0, length) + '...' : str;
expect(truncate('这是一个很长的字符串', 5)).toBe('这是一...');
expect(truncate('短字符串', 10)).toBe('短字符串');
});
});
项目实战:Markdown解析测试
假设项目需要测试Markdown链接解析功能,对应tests/url_validate.py的JavaScript版本:
// markdown-parser.js
export function extractLinks(markdown) {
const urlRegex = /\[.*\]\((.*?)\)/g;
const links = [];
let match;
while ((match = urlRegex.exec(markdown)) !== null) {
links.push(match[1]);
}
return links;
}
// markdown-parser.test.js
import { extractLinks } from './markdown-parser';
describe('Markdown链接提取', () => {
test('提取单个链接', () => {
const markdown = '这是一个链接[示例](https://example.com)';
expect(extractLinks(markdown)).toEqual(['https://example.com']);
});
test('提取多个链接', () => {
const markdown = `
链接1[GitHub](https://github.com)
链接2[GitCode](https://gitcode.com)
`;
expect(extractLinks(markdown)).toEqual([
'https://github.com',
'https://gitcode.com'
]);
});
test('无链接时返回空数组', () => {
expect(extractLinks('没有链接的文本')).toEqual([]);
});
});
异步测试与Mock
API调用测试
// api.js
import axios from 'axios';
export async function fetchUser(id) {
const response = await axios.get(`/api/users/${id}`);
return response.data;
}
// api.test.js
import { fetchUser } from './api';
import axios from 'axios';
// Mock axios模块
jest.mock('axios');
describe('API调用测试', () => {
test('获取用户数据', async () => {
// Mock返回数据
const mockUser = { id: 1, name: '测试用户' };
axios.get.mockResolvedValue({ data: mockUser });
// 调用函数
const user = await fetchUser(1);
// 断言
expect(axios.get).toHaveBeenCalledWith('/api/users/1');
expect(user).toEqual(mockUser);
});
test('API错误处理', async () => {
// Mock错误
axios.get.mockRejectedValue(new Error('网络错误'));
// 断言错误被正确抛出
await expect(fetchUser(1)).rejects.toThrow('网络错误');
});
});
测试自动化与CI集成
测试报告生成
Jest报告配置
# 安装报告生成器
npm install --save-dev jest-junit jest-html-reporter
配置jest.config.js:
module.exports = {
reporters: [
'default',
['jest-junit', {
outputDirectory: 'reports',
outputName: 'jest-junit.xml',
}],
['jest-html-reporter', {
pageTitle: 'Awesome Cheatsheet测试报告',
outputPath: 'reports/test-report.html'
}]
],
collectCoverage: true,
coverageDirectory: 'reports/coverage',
coverageReporters: ['html', 'lcov', 'text-summary']
};
GitLab CI配置
创建.gitlab-ci.yml文件:
stages:
- test
python-test:
stage: test
image: python:3.9
before_script:
- pip install -r requirements.txt
- pip install selenium
script:
- python tests/url_validate.py
js-test:
stage: test
image: node:16
before_script:
- npm install
script:
- npm test
artifacts:
paths:
- reports/
expire_in: 1 week
定时测试任务
使用项目中的Makefile配置定时测试:
# 添加到Makefile
test:
python tests/url_validate.py
npm test
test-ci:
# CI环境专用测试命令
python tests/url_validate.py
npm test -- --ci
# 安装定时任务
install-cron:
echo "0 0 * * * cd $(shell pwd) && make test >> cron-test.log 2>&1" | crontab -
常见问题与解决方案
Selenium常见问题
| 问题 | 解决方案 | 参考代码 |
|---|---|---|
| 元素定位不稳定 | 使用显式等待代替固定延迟 | WebDriverWait(driver, 15).until(EC.presence_of_element_located(...)) |
| 浏览器兼容性问题 | 使用WebDriverManager管理驱动 | webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install())) |
| 测试速度慢 | 启用无头模式运行浏览器 | options.add_argument("--headless=new") |
| 动态内容加载 | 使用ExpectedConditions等待 | EC.visibility_of_element_located((By.CSS_SELECTOR, ".dynamic-content")) |
Jest测试效率优化
-
测试隔离:确保每个测试用例独立运行
beforeEach(() => { // 重置测试状态 jest.clearAllMocks(); }); -
选择性测试:使用
.only和.skip控制测试执行test.only('只运行这个测试', () => { // ... }); test.skip('跳过这个测试', () => { // ... }); -
并行测试:利用Jest的并行测试能力
npm test -- --maxWorkers=4 # 使用4个工作进程
总结与进阶路线
测试能力提升路径
项目测试资源
Awesome Cheatsheet项目提供了丰富的测试相关资源:
通过本文介绍的Selenium和Jest实战方法,结合项目现有的测试基础设施,你可以构建完整的前端自动化测试体系。建议从URL验证测试入手,逐步扩展到UI组件测试和端到端流程测试,最终实现测试覆盖率>80%的质量目标。
后续学习建议
- 探索Cypress作为E2E测试的替代方案
- 学习React Testing Library进行组件测试
- 研究契约测试解决服务间集成问题
- 掌握测试金字塔优化测试策略
如果你发现测试流程中的改进空间,欢迎通过项目贡献指南提交PR,共同完善Awesome Cheatsheet的测试体系!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



