对应代码:配套代码/test/ 完整目录结构
说明:本节讲解如何组织一个中大型 Appium 测试项目,从目录结构到文件职责,从脚本到工程的演进。
这节讲什么
测试项目从小到大会经历三个阶段:
阶段 1:脚本阶段
test_login.py # 一个文件搞定
test_register.py # 又一个文件
问题:代码重复多,维护困难。
阶段 2:框架阶段
base/ # 基类
base_driver.py
base_page.py
pages/ # 页面对象
login_page.py
tests/ # 测试用例
test_login.py
问题:文件多了,但结构不清晰。
阶段 3:工程阶段(本节要讲的)
test/
base/ # 驱动管理
pages/ # 页面对象
tests/ # 测试用例
api/ # API 测试封装
core/ # 核心模块(路由、执行器、验证器)
utils/ # 工具类(日志、截图、报告)
testcases/ # 测试数据(YAML、设计稿)
scripts/ # 辅助脚本(环境检查、并行执行)
conftest.py # pytest 配置
config.yaml # 全局配置
问题:结构复杂,需要理解每个目录的职责。
目录结构详解
base/ --- 驱动管理
| 文件 | 职责 |
|---|---|
base_driver.py |
Appium 驱动初始化(Android/iOS) |
base_page.py |
页面对象基类(元素定位、等待、操作) |
设计原则:
- 基类只封装通用逻辑,不包含业务代码
- 具体页面继承基类,实现页面特有逻辑
pages/ --- 页面对象
| 文件 | 职责 |
|---|---|
login_page.py |
登录页面元素和操作 |
shell_home_page.py |
首页元素和操作 |
register_page.py |
注册页面元素和操作 |
设计原则:
- 每个页面对应一个文件
- 页面类继承
BasePage - 只封装元素定位和操作,不包含断言(断言在测试用例中)
tests/ --- 测试用例
| 文件 | 职责 |
|---|---|
test_login_api.py |
登录接口测试 |
test_appium_demo.py |
Appium UI 测试示例 |
test_login_data_driven_example.py |
数据驱动登录测试 |
设计原则:
- 测试文件以
test_开头(pytest 约定) - 测试类以
Test开头 - 测试方法以
test_开头 - 一个文件测试一个功能模块
api/ --- API 测试封装
| 文件 | 职责 |
|---|---|
base_api.py |
API 请求封装(GET/POST/PUT/DELETE) |
设计原则:
- 统一处理请求头、超时、重试
- 支持 Bearer Token 认证
- 返回结构化结果(状态码、响应体、耗时)
core/ --- 核心模块
| 文件 | 职责 |
|---|---|
test_router.py |
测试路由(API vs UI 自动选择) |
hybrid_test_executor.py |
混合测试执行器 |
validator.py |
测试结果验证器 |
data_driver.py |
数据驱动引擎 |
test_recorder.py |
测试录制器 |
设计原则:
- 核心模块是框架的"大脑"
- 不依赖具体业务,只封装测试逻辑
- 可独立测试、独立升级
utils/ --- 工具类
| 文件 | 职责 |
|---|---|
logger.py |
日志工具 |
screenshot.py |
截图工具 |
visual_comparison.py |
视觉对比 |
xmind_parser.py |
XMind 解析 |
bug_reporter.py |
Bug 报告生成 |
allure_helper.py |
Allure 报告辅助 |
设计原则:
- 工具类是"工具箱",按需取用
- 每个工具独立,不互相依赖
- 工具类应该可复用到其他项目
testcases/ --- 测试数据
| 目录 | 内容 |
|---|---|
yaml/ |
YAML 格式的测试用例 |
data/ |
测试数据(用户、配置等) |
ui_designs/ |
UI 设计稿(用于视觉对比) |
设计原则:
- 测试数据与测试代码分离
- 数据文件用 YAML/JSON 格式(易读易维护)
- 设计稿用 PNG 格式(用于视觉回归)
scripts/ --- 辅助脚本
| 文件 | 职责 |
|---|---|
check_android_env.py |
检查 Android 环境 |
run_parallel_test.py |
并行执行测试 |
xmind_to_yaml.py |
XMind 转 YAML |
open_allure_report.sh |
打开 Allure 报告 |
设计原则:
- 辅助脚本是"一次性工具",不纳入 pytest 执行
- 脚本应该独立运行,不依赖测试框架
- 脚本应该有清晰的命令行参数
文件职责边界
什么该放 base/,什么该放 pages/?
base/:通用逻辑(所有页面都用的)
- 元素定位、等待、点击、滑动
- 截图、日志、异常处理
pages/:页面特有逻辑(只在这个页面用的)
- 登录页面的用户名输入框定位
- 首页的导航栏元素
什么该放 core/,什么该放 utils/?
core/:测试框架的核心逻辑
- 路由、执行器、验证器
- 这些模块决定"测试怎么跑"
utils/:辅助工具
- 日志、截图、报告
- 这些模块决定"测试怎么记录"
什么该放 tests/,什么该放 testcases/?
tests/:Python 测试代码
- pytest 测试文件
- 包含断言、fixture、hook
testcases/:测试数据
- YAML 格式的测试用例
- 设计稿、配置文件
- 不包含代码,只包含数据
注意事项
1. 不要把所有代码放一个文件
随着项目增长,测试代码会越来越多。如果不分文件,一个文件可能有几千行,难以维护。
建议:
- 每个文件不超过 500 行
- 超过 500 行考虑拆分
- 拆分原则:按职责拆分,不是按行数拆分
2. 不要循环导入
A 导入 B,B 导入 C,C 又导入 A → 循环导入,启动报错。
建议:
- 基类不导入子类
- 工具类不导入业务类
- 测试用例导入所有模块,但不被其他模块导入
3. 配置文件统一管理
配置分散在各个文件中(如 Appium 地址、超时时间),修改时容易遗漏。
建议:
- 所有配置集中在
config.yaml - 代码通过
config_reader.py读取配置 - 环境变量优先级高于配置文件
4. 测试数据与代码分离
测试数据(用户名、密码、URL)硬编码在测试代码中,修改时需要改代码。
建议:
- 测试数据放在
testcases/data/目录 - 使用 YAML 格式(易读、支持注释)
- 测试代码通过
data_driver.py加载数据
总结
测试项目结构的核心原则:
- 职责清晰:每个目录、每个文件都有明确职责
- 低耦合:模块之间依赖少,修改一个不影响其他
- 高内聚:相关代码放在一起,容易找到
- 可扩展:新增功能时,知道该往哪加代码
配套代码中的实现 :配套代码/test/ 完整目录结构(数十个 Python 文件,涵盖驱动管理、页面对象、API 封装、核心模块、工具类、测试数据等完整分层),可直接作为模板使用。
后续:第 1-16 节内容完成。配套代码已覆盖 Appium 测试的完整生命周期:环境搭建→驱动初始化→页面对象→API 测试→数据驱动→智能路由→混合执行→视觉测试→用例转换→重试容错→报告管理→项目结构。