基于Pytest+Appium的Android自动化测试框架项目组织方案咨询
Appium+Pytest Android 测试框架拆分方案
推荐项目目录结构
采用分层按业务模块拆分的结构,既解耦各模块逻辑,又能复用Appium连接:
app_test_framework/ ├── common/ # 公共基础层 │ ├── __init__.py │ ├── driver_util.py # Appium驱动初始化、销毁逻辑封装 │ └── settings.py # 全局配置(设备UDID、应用包名、Appium服务地址等) ├── testcases/ # 测试用例层,按业务模块拆分 │ ├── __init__.py │ ├── test_register.py # 注册模块测试用例 │ ├── test_home.py # 首页模块测试用例 │ └── test_subscribe.py# 付费订阅模块测试用例 ├── reports/ # 测试报告输出目录 ├── conftest.py # pytest全局钩子、公共fixture配置 └── pytest.ini # pytest运行配置
核心代码实现
1. 全局配置(common/settings.py)
把硬编码的配置统一抽离,方便后续修改:
# Appium服务配置 APPIUM_HOST = "http://localhost:4723/wd/hub" # 设备配置 DEVICE_UDID = "RF8MA2GW1ZF" PLATFORM_NAME = "android" # 应用配置 APP_PACKAGE = "com.tg17.ud.internal" APP_ACTIVITY = "com.tg17.ud.ui.splash.SplashActivity" NO_RESET = True # 报告配置 REPORT_DIR = "reports" REPORT_FORMAT = "xml"
2. 驱动工具封装(common/driver_util.py)
封装驱动初始化、销毁逻辑:
from appium import webdriver from common.settings import * def init_driver(): dc = { "reportDirectory": REPORT_DIR, "reportFormat": REPORT_FORMAT, "udid": DEVICE_UDID, "appPackage": APP_PACKAGE, "appActivity": APP_ACTIVITY, "platformName": PLATFORM_NAME, "noReset": NO_RESET } driver = webdriver.Remote(APPIUM_HOST, dc) driver.implicitly_wait(10) # 全局隐式等待,可按需调整 return driver def quit_driver(driver): if driver: driver.quit()
3. 全局fixture配置(conftest.py)
通过pytest的session级fixture实现全局唯一驱动实例,整个测试周期只会初始化一次Appium连接,满足保持设备连接的需求:
import pytest from common.driver_util import init_driver, quit_driver from common.settings import REPORT_DIR import os import shutil @pytest.fixture(scope="session", autouse=True) def app_driver(): # 测试前初始化:创建报告目录、初始化Appium驱动 if not os.path.exists(REPORT_DIR): os.mkdir(REPORT_DIR) else: # 可选:清空历史报告 shutil.rmtree(REPORT_DIR) os.mkdir(REPORT_DIR) driver = init_driver() yield driver # 此处会把driver实例传递给所有测试用例 # 测试后清理:断开设备连接 quit_driver(driver)
4. 分模块测试用例示例
各模块的测试用例独立存放,直接复用全局的driver实例即可,无需重复编写初始化逻辑:
testcases/test_register.py
class TestRegister: def test_register_by_phone(self, app_driver): # 注册逻辑代码 app_driver.find_element("id", "xxx").send_keys("13xxxxxxxxx") # 其余断言逻辑 def test_register_by_wechat(self, app_driver): # 微信注册逻辑 pass
testcases/test_home.py
class TestHome: def test_home_banner_display(self, app_driver): # 首页Banner展示校验逻辑 pass def test_home_menu_click(self, app_driver): # 首页菜单点击校验逻辑 pass
需求匹配说明
- Appium服务对接与设备初始化:通过session级fixture自动完成驱动初始化,整个测试过程只会建立一次Appium连接,不会重复启动应用,符合你设置的
noReset参数要求。 - 按顺序运行多模块测试套件:运行测试时直接按模块顺序指定执行路径即可:
如果需要更灵活的用例顺序控制,可安装pytest testcases/test_register.py testcases/test_home.py testcases/test_subscribe.py -v --junitxml=reports/result.xmlpytest-order插件,通过@pytest.mark.order()标记用例优先级。 - 测试后清理操作:fixture中yield后的逻辑会在所有测试用例执行完成后自动运行,自动断开设备连接,同时运行命令中指定的
--junitxml参数会自动导出xml格式测试报告到指定目录,也可根据需求接入Allure等更可视化的报告工具。
内容的提问来源于stack exchange,提问作者Shen
相关产品推荐
相关产品推荐

