1. 为什么选择CURSOR搭建APP自动化测试框架第一次接触APP自动化测试时我被各种工具和框架搞得晕头转向。直到遇到CURSOR才发现原来搭建测试框架可以这么简单。CURSOR最大的优势在于它把复杂的配置过程封装成了可视化操作就像用积木搭房子一样直观。我去年接手一个电商APP项目时从零开始搭建测试环境只用了不到2小时这在以前简直不敢想象。对于中小型团队来说CURSOR特别适合这些场景需要快速验证核心业务流程、频繁回归测试、多设备兼容性测试。它内置的Python支持让写测试用例像写普通脚本一样简单而且能和主流的Appium、Selenium完美配合。记得有次紧急版本上线前我们用CURSOR连夜跑了300多个测试用例成功拦截了5个严重bug这种效率传统方式根本做不到。2. 环境配置避坑指南2.1 必备软件清单我建议先准备这些食材再下厨Python 3.9别用太新的版本3.9.7最稳JDK 8注意配置JAVA_HOME环境变量Android SDK建议通过Android Studio安装Appium Server2.0版本开始支持WebDriver协议模拟器推荐Pixel_3a_API_35镜像最近帮学弟配环境时发现个坑Android SDK的build-tools版本必须和模拟器匹配。比如用API 35的模拟器就要装35.0.0的build-tools。验证环境是否OK有个妙招在cmd连续输入adb devices、appium -v、java -version三个命令都正常输出就成功大半了。2.2 Python依赖管理requirements.txt我习惯这样写appium-python-client3.0.0 selenium4.0.0 urllib32.0.0 pytest7.0.0 PyQt55.15.9 # 固定版本避免兼容问题 requests2.31.0 allure-pytest2.13.2 # 生成漂亮报告安装时加个清华源加速pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple遇到过最头疼的问题是PyQt5和其他库冲突后来发现先装PyQt5再装其他依赖就能避免。建议新建虚拟环境我用conda创建隔离环境从没翻车过conda create -n app_test python3.9 conda activate app_test3. 项目结构设计实战3.1 目录架构详解我的项目模板长这样app_auto_framework/ ├── common/ # 公共方法 │ ├── __init__.py │ ├── device_util.py # 设备旋转、截图 │ └── network_util.py # 模拟弱网 ├── config/ │ ├── __init__.py │ ├── config.yaml # 测试配置 │ └── elements/ # 元素定位 │ ├── home_page.yaml │ └── login_page.yaml ├── logs/ # 按日期自动生成 ├── pages/ # POM模式 │ ├── base_page.py │ ├── home_page.py │ └── login_page.py ├── reports/ # Allure报告 ├── screenshots/ # 失败自动截图 ├── test_cases/ # 测试用例 │ ├── __init__.py │ ├── test_login.py │ └── test_order.py ├── utils/ │ ├── logger.py # 日志配置 │ └── report_util.py └── conftest.py # pytest夹具config.yaml典型配置devices: - name: Pixel_3a platformVersion: 11 udid: emulator-5554 appPackage: com.example.app appActivity: .MainActivity test: timeout: 30 retry: 23.2 核心模块设计**页面对象模式(POM)**的妙处在于把元素定位和业务逻辑分离。比如登录页面这样写class LoginPage(BasePage): def __init__(self, driver): self.elements load_yaml(config/elements/login_page.yaml) super().__init__(driver) def input_username(self, text): self.find_element(self.elements[username]).send_keys(text) def input_password(self, text): self.find_element(self.elements[password]).send_keys(text)日志模块我推荐用loguru比原生logging简单十倍from loguru import logger logger.add(logs/test_{time}.log, rotation10 MB) logger.info(Start testing login function)4. 编写第一个测试用例4.1 测试用例规范pytest测试文件示例class TestLogin: pytest.fixture(autouseTrue) def setup(self, app_driver): self.driver app_driver self.login_page LoginPage(self.driver) def test_success_login(self): self.login_page.input_username(testuser) self.login_page.input_password(123456) self.login_page.click_login() assert HomePage(self.driver).check_login_success()conftest.py里定义全局夹具pytest.fixture(scopesession) def app_driver(): capabilities load_config(config/config.yaml)[devices][0] driver webdriver.Remote(http://localhost:4723/wd/hub, capabilities) yield driver driver.quit()4.2 运行与调试技巧启动测试时用这些参数更高效pytest test_cases/ -v --alluredir./reports遇到元素找不到时我的排查三板斧用uiautomatorviewer检查元素是否真实存在加隐式等待driver.implicitly_wait(10)检查是否在正确的WebView上下文最近发现个神器——Appium Desktop的Inspector可以实时查看元素树。有次遇到动态ID问题就是用这个工具发现ID每周会变最后改用XPath的contains语法解决。