Files
PlexPlaylistSync/tests/UI_TESTING_GUIDE.md
T

357 lines
7.6 KiB
Markdown

# UI 集成测试指南
## 📋 概述
UI 集成测试使用 **Playwright** 框架来测试正则路径替换功能的用户界面交互。
## 🚀 快速开始
### 1. 安装依赖
```bash
# 安装 Playwright 和浏览器驱动
pip install pytest-playwright
playwright install chromium
# 或安装所有浏览器
playwright install
```
### 2. 启动应用服务器
在运行 UI 测试前,需要先启动应用:
```bash
# 方式 1: 直接运行
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# 方式 2: 使用 Docker
docker compose up
```
### 3. 运行 UI 测试
```bash
# 无头模式(不显示浏览器)
pytest tests/test_ui_regex_rules.py -v
# 有头模式(显示浏览器,便于调试)
pytest tests/test_ui_regex_rules.py -v --headed
# 慢速模式(方便观察)
pytest tests/test_ui_regex_rules.py -v --headed --slowmo=500
# 运行特定测试
pytest tests/test_ui_regex_rules.py::TestRegexRulesUI::test_add_single_rule -v --headed
```
## 📊 测试覆盖
### 基础 UI 交互测试 (TestRegexRulesUI)
| 测试 | 描述 |
|------|------|
| `test_page_loads_successfully` | 页面成功加载 |
| `test_add_single_rule` | 添加单个规则 |
| `test_add_multiple_rules` | 添加多个规则 |
| `test_remove_rule` | 删除规则 |
| `test_save_rules` | 保存规则 |
| `test_rules_persist_after_save` | 规则持久化验证 |
| `test_empty_pattern_validation` | 空模式验证 |
| `test_rule_order_preserved` | 规则顺序保持 |
### 复杂场景测试 (TestComplexScenarios)
| 测试 | 描述 |
|------|------|
| `test_windows_to_linux_path_conversion` | Windows → Linux 路径转换 |
| `test_nas_path_normalization` | NAS 路径规范化 |
### 性能测试 (TestPerformance)
| 测试 | 描述 |
|------|------|
| `test_add_many_rules_performance` | 添加大量规则性能 |
## 🎯 测试场景示例
### 场景 1: 添加单个规则
```python
# 1. 点击"添加规则"按钮
# 2. 填写正则表达式: /old/path/
# 3. 填写替换文本: /new/path/
# 4. 验证输入框内容正确
```
### 场景 2: NAS 路径规范化
```python
# 添加三条规则:
# 1. \\koha9-nas\koha9-nas\Music → N:\Music
# 2. /music/cache/ → /data/music/
# 3. \ → /
#
# 保存并验证规则持久化
```
### 场景 3: 规则持久化验证
```python
# 1. 添加规则
# 2. 保存
# 3. 刷新页面
# 4. 验证规则仍然存在
```
## 🔧 配置选项
### pytest.ini 配置
```ini
[pytest]
# Playwright 配置
addopts =
--browser=chromium
--headed
--slowmo=100
```
### 环境变量
```bash
# 设置测试服务器地址
export TEST_SERVER_URL="http://localhost:8000"
# 设置浏览器类型
export BROWSER=chromium # 或 firefox, webkit
```
## 🐛 调试技巧
### 1. 使用有头模式
```bash
pytest tests/test_ui_regex_rules.py --headed
```
### 2. 使用慢速模式
```bash
pytest tests/test_ui_regex_rules.py --headed --slowmo=1000
```
### 3. 截图调试
在测试中添加截图:
```python
def test_something(page: Page):
page.screenshot(path="debug_screenshot.png")
```
### 4. 使用 Playwright Inspector
```bash
# 启动调试模式
PWDEBUG=1 pytest tests/test_ui_regex_rules.py::test_add_single_rule
```
### 5. 查看追踪
```python
# 在 conftest.py 中添加
@pytest.fixture
def context(browser):
context = browser.new_context()
context.tracing.start(screenshots=True, snapshots=True)
yield context
context.tracing.stop(path="trace.zip")
```
然后查看:
```bash
playwright show-trace trace.zip
```
## 📝 编写新的 UI 测试
### 基本模板
```python
def test_my_feature(page: Page):
"""测试我的功能"""
# 1. 导航到页面
page.goto("http://localhost:8000")
# 2. 与元素交互
button = page.locator("#myButton")
button.click()
# 3. 验证结果
expect(page.locator("#result")).to_have_text("Success")
```
### 等待策略
```python
# 等待元素可见
page.wait_for_selector("#element", state="visible")
# 等待网络空闲
page.wait_for_load_state("networkidle")
# 等待特定时间(尽量避免)
page.wait_for_timeout(1000) # 1 秒
```
### 选择器策略
```python
# 推荐: 使用 data-testid
page.locator("[data-testid='add-rule-btn']")
# 通过文本
page.locator("button:has-text('保存规则')")
# 通过 ID
page.locator("#addRuleBtn")
# 通过 CSS 类
page.locator(".rule-row")
# 组合选择器
page.locator(".rule-row input[name='pattern']")
```
## 🎨 最佳实践
### 1. 使用 Page Object 模式
```python
class RulesPage:
def __init__(self, page: Page):
self.page = page
self.add_button = page.locator("#addRuleBtn")
self.save_button = page.locator("button:has-text('保存规则')")
def add_rule(self, pattern: str, replacement: str):
self.add_button.click()
self.page.wait_for_timeout(100)
patterns = self.page.locator("input[name='pattern']")
replacements = self.page.locator("input[name='replacement']")
patterns.last.fill(pattern)
replacements.last.fill(replacement)
def save(self):
self.save_button.click()
self.page.wait_for_load_state("networkidle")
# 使用
def test_with_page_object(page: Page):
rules_page = RulesPage(page)
rules_page.add_rule(r"/old/", r"/new/")
rules_page.save()
```
### 2. 使用 Fixtures 清理状态
```python
@pytest.fixture
def clean_rules(page: Page):
"""清除所有规则"""
page.goto("http://localhost:8000")
while page.locator(".rule-row").count() > 0:
page.locator(".rule-row button[title='删除此规则']").first.click()
page.wait_for_timeout(50)
yield
```
### 3. 避免硬编码等待时间
```python
# ❌ 不好
page.wait_for_timeout(2000)
# ✅ 好
page.wait_for_selector("#element", state="visible")
page.wait_for_load_state("networkidle")
```
### 4. 使用断言而非 if 判断
```python
# ❌ 不好
assert page.locator("#element").count() > 0
# ✅ 好
expect(page.locator("#element")).to_be_visible()
```
## 🔄 CI/CD 集成
### GitHub Actions 示例
```yaml
name: UI Tests
on: [push, pull_request]
jobs:
ui-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest-playwright
playwright install --with-deps chromium
- name: Start application
run: |
uvicorn app.main:app --host 0.0.0.0 --port 8000 &
sleep 5
- name: Run UI tests
run: pytest tests/test_ui_regex_rules.py -v
- name: Upload screenshots on failure
if: failure()
uses: actions/upload-artifact@v2
with:
name: screenshots
path: screenshots/
```
## 📚 参考资料
- [Playwright 官方文档](https://playwright.dev/python/)
- [pytest-playwright 插件](https://github.com/microsoft/playwright-pytest)
- [Playwright 最佳实践](https://playwright.dev/python/docs/best-practices)
## 🆘 常见问题
### Q: 测试运行时找不到浏览器?
A: 运行 `playwright install chromium`
### Q: 测试失败,如何调试?
A: 使用 `--headed --slowmo=500` 参数可视化执行过程
### Q: 如何在测试中等待异步操作?
A: 使用 `page.wait_for_load_state("networkidle")``page.wait_for_selector()`
### Q: 如何处理动态加载的内容?
A: 使用 `expect().to_be_visible()` 会自动等待元素出现
### Q: 测试很慢怎么办?
A: 减少不必要的 `wait_for_timeout()`,使用事件驱动的等待方法