尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Appium自动化测试:从核心原理到跨平台实战全解析

Appium自动化测试:从核心原理到跨平台实战全解析
📅 发布时间:2026/6/29 22:40:59

1. 项目概述:Appium自动化测试的边界与能力

最近在跟几个刚入行测试的朋友聊天,发现他们对Appium的理解还停留在“一个能测App的工具”这个层面。这让我想起自己刚接触移动端自动化时,也以为Appium就是个“高级版点击器”。但实际上,Appium的能力边界远比我们想象的要宽广和深刻。它不仅仅是一个工具,更是一个连接不同操作系统、不同应用形态的桥梁,其设计哲学决定了它能做什么、不能做什么,以及我们如何最大化地利用它。今天,我就结合自己这些年踩过的坑和积累的经验,来系统性地拆解一下:Appium到底能测什么?它的能力边界在哪里?我们又该如何根据不同的测试需求来驾驭它?

简单来说,Appium是一个开源的、跨平台的移动端应用自动化测试框架。它的核心价值在于,允许你使用同一套API(比如WebDriver协议)来编写测试脚本,然后这些脚本可以不经修改或仅做少量适配,就能在iOS和Android两大平台的原生、混合乃至Web应用上运行。这听起来很美好,但“能运行”和“测得好”是两码事。理解Appium的能力范围,是设计出高效、稳定自动化测试用例的前提。无论是想验证一个购物App的下单流程,还是测试一个内嵌H5页面的金融应用,亦或是评估一个车载中控屏上的App,Appium都可能成为你的得力助手,但前提是你得知道它的“开关”在哪里。

2. Appium的核心能力与测试范围解析

要搞清楚Appium能测什么,我们得先回到它的技术原理上。Appium遵循着“客户端-服务器”架构,并且其核心是WebDriver协议。这意味着,它并不直接与你的手机或模拟器“对话”,而是通过一个中间服务器(Appium Server)来转发指令。服务器再调用各平台原生提供的自动化测试框架(如Android的UiAutomator2/iOS的XCUITest)来执行具体操作。这种设计带来了巨大的灵活性,也划定了它的能力圈。

2.1 跨平台应用类型的全覆盖测试

这是Appium最广为人知的优势。它并非只针对某一种应用。

原生应用测试:这是Appium的“主场”。无论是用Java/Kotlin开发的Android App,还是用Swift/Objective-C开发的iOS App,Appium都能通过对应平台的驱动(AndroidDriver, XCUITestDriver)进行完整的UI交互测试。你可以模拟用户的点击、滑动、输入文本、长按等所有手势操作,也能获取页面元素的状态(如文本内容、是否可点击、坐标位置)。我做过一个电商App的项目,其核心的“浏览-加购-下单-支付”流程就是用Appium覆盖的,脚本在Android和iOS设备上都能稳定执行,大大提升了回归测试的效率。

混合应用测试:很多应用为了平衡开发效率和体验,会采用原生外壳内嵌WebView(即H5页面)的方式。Appium对此有专门的支持。测试混合应用时,你需要进行“上下文切换”。当操作进入WebView部分时,你必须将驱动器的上下文(Context)从“NATIVE_APP”切换到对应的WebView上,然后就可以像使用Selenium测试网页一样,使用CSS选择器或XPath来定位和操作H5页面里的元素了。操作完毕后,再切换回原生上下文。这个切换过程是混合应用测试的关键,也是新手最容易出错的地方。

注意:在Android上,需要确保WebView已启用调试模式(通常是在App代码中设置WebView.setWebContentsDebuggingEnabled(true),这需要开发配合)。在iOS上,对于UIWebView(已废弃)和WKWebView的支持略有不同,且真机测试需要额外的配置。

移动端Web应用测试:你想测试手机浏览器(如Chrome, Safari)里打开的网页的响应式和交互吗?Appium同样可以。通过将browserName能力(Capability)设置为对应的浏览器(如Chrome,Safari),Appium就会直接启动浏览器并打开指定URL,后续的所有操作都将在这个浏览器会话中进行。这在测试移动端网页的兼容性时非常有用。

2.2 超越“点击与输入”的深度交互能力

很多人以为自动化测试就是“找元素,然后点击”。Appium的能力远不止于此。

复杂手势与多点触控:除了基础的tap(点击),Appium的TouchAction(旧版)和W3C Actions API(推荐)支持丰富的触摸手势。你可以轻松实现:

  • 滑动/拖拽:用于列表滚动、轮播图切换、解锁屏幕。
  • 长按:触发上下文菜单、拖动排序。
  • 捏合与缩放:地图、图片查看器等场景。
  • 多点触控:模拟双指旋转图片等复杂操作。

这些手势的API调用可能稍显复杂,但一旦封装成通用函数,就能极大地增强测试脚本的表现力。我习惯将常用的手势操作(如从屏幕底部上滑返回桌面)封装成独立的方法,方便在不同脚本中调用。

非UI接口与系统交互:Appium可以通过driver对象执行一些特殊的指令,来与设备系统进行交互,这常常被忽略但极其有用。

  • 获取和设置网络状态:模拟2G/3G/4G/Wi-Fi/飞行模式等网络环境,测试App在不同网络下的表现和容错能力。
  • 控制设备旋转:横竖屏切换测试。
  • 模拟来电、短信:测试应用被打断时的行为。
  • 操作通知栏:拉下通知栏,点击或清除通知。
  • 文件推送与拉取:向设备推送测试用的图片、配置文件,或从设备拉取日志、截图。这在数据准备和结果收集时非常方便。
  • 执行Shell命令:通过execute_script执行mobile: shell命令,可以运行一些adb命令(Android)或类似操作,功能强大但需谨慎使用。

访问应用权限与设置:虽然不能直接修改系统全局设置,但Appium可以启动系统的“设置”Activity(Android)或Preferences(iOS),并自动化操作其中的开关。更常见的做法是,在测试开始前,通过ADB(Android)或类似工具预先设置好App所需的权限,保证测试环境的一致性。

2.3 特殊场景与新兴领域的测试探索

随着技术发展,Appium也在不断拓展其边界。

小程序/快应用测试:这类应用运行在超级App(如微信、支付宝)的容器内。测试它们本质上是对宿主App内一个特殊WebView的测试。你需要先启动宿主App(如微信),然后通过Activity跳转或深度链接进入小程序页面,再进行上下文切换到小程序的WebView进行元素操作。流程繁琐,且受宿主App版本限制较大,但技术上是可行的。

TV、车载等大屏设备测试:原理与手机测试相同,但由于交互方式不同(常用DPAD遥控器而非触摸),定位和操作方式需要调整。Appium支持模拟DPAD的上下左右、确认、返回等按键事件。元素定位时,要特别注意TV界面通常为横向,且焦点移动逻辑与触摸不同。

桌面端应用测试(有限支持):Appium最初是为移动端设计的,但社区也有尝试将其用于测试某些基于Electron等框架开发的桌面应用,前提是该应用能提供可访问性树(类似移动端的UI层级)。但这并非Appium的主战场,稳定性不如专门的桌面端测试工具。

3. Appium不能做什么?明确能力边界

知道能做什么很重要,但明确不能做什么,更能避免我们走弯路和产生不切实际的期望。

无法测试纯后端逻辑与性能:Appium是UI自动化测试框架。它关心的是用户界面的响应和行为。对于接口返回数据的正确性、服务器并发处理能力、数据库查询性能等,需要借助Postman、JMeter、LoadRunner等接口或性能测试工具。自动化测试体系应该是分层的,UI自动化只是金字塔顶端的一部分。

对游戏、高频动画应用支持有限:对于重度依赖OpenGL/DirectX渲染的游戏,或者动画元素非常多、界面变化极快的应用,Appium基于UI层级树的元素定位方式会非常吃力,甚至无法稳定定位。这类测试更适合图像识别方案(如Airtest)或游戏引擎提供的专用测试框架。

无法绕过安全限制:Appium必须在被测应用可被自动化工具访问的前提下工作。如果应用做了反自动化加固(比如检测是否被注入、是否运行在模拟器),Appium可能无法正常工作。同样,它不能破解登录验证(如指纹、人脸),测试时需要关闭这些安全功能或使用测试账户。

非“零成本”与“全智能”:编写和维护一套稳定、可读、可复用的Appium测试脚本需要投入相当的开发资源和时间。它不能替代测试人员的思考,比如如何设计用例、如何断言、如何处理异常场景。它只是一个忠实的执行者。近年来“AI自动化测试”概念很热,其本质是借助AI(如图像识别、自然语言处理)来辅助生成或维护脚本,降低编写成本,但核心的执行引擎和测试逻辑,依然需要人来设计和把控。

4. 实战:构建一个跨平台App核心流程测试案例

光说不练假把式。我们以一个经典的“用户登录”场景为例,看看如何用Appium进行实际的跨平台测试。假设我们有一个App,在Android和iOS上都有登录页面。

4.1 测试环境搭建与初始化

首先,你需要准备好环境。这通常是新手的第一道坎。

  1. 安装Node.js与Appium Server:Appium Server是基于Node.js的。去官网下载安装Node.js后,通过npm安装Appium:npm install -g appium。也可以使用图形化的Appium Desktop,它内置了Inspector工具,对于调试非常方便。
  2. 安装平台驱动与依赖:
    • Android:安装Android SDK,配置好ANDROID_HOME环境变量。确保安装了对应API级别的平台工具和构建工具。Appium会使用其中的adb工具。
    • iOS:必须在macOS系统上。安装Xcode和Xcode Command Line Tools。对于真机测试,还需要配置开发者证书和描述文件。
  3. 安装客户端库:根据你的编程语言选择Appium客户端库。Python用户常用Appium-Python-Client,Java用户常用java-client。通过pip或Maven安装即可。

初始化驱动(Driver)是脚本的起点,这里包含了所有告诉Appium“你要测什么、怎么测”的信息,即Desired Capabilities。

# Python 示例 - Android from appium import webdriver from appium.options.android import UiAutomator2Options desired_caps = { 'platformName': 'Android', 'platformVersion': '13', # 根据你的设备或模拟器调整 'deviceName': 'Android Emulator', # 或你的真机名称 'automationName': 'UiAutomator2', # Android推荐驱动 'app': '/path/to/your/app.apk', # 应用安装包路径,或使用`appPackage`和`appActivity`启动已安装应用 'noReset': True, # 是否在会话开始前重置应用状态(如清除数据) 'newCommandTimeout': 300, # 命令超时时间 } driver = webdriver.Remote('http://localhost:4723/wd/hub', options=UiAutomator2Options().load_capabilities(desired_caps))
# Python 示例 - iOS from appium import webdriver from appium.options.ios import XCUITestOptions desired_caps = { 'platformName': 'iOS', 'platformVersion': '16.4', 'deviceName': 'iPhone 14 Pro', # 模拟器名称 'automationName': 'XCUITest', 'app': '/path/to/your/app.app', # 或使用bundleId 'noReset': True, } driver = webdriver.Remote('http://localhost:4723/wd/hub', options=XCUITestOptions().load_capabilities(desired_caps))

实操心得:Desired Capabilities的配置是成功的第一步。建议将不同设备、不同应用的配置用JSON或YAML文件管理起来,脚本读取配置文件来初始化驱动,这样切换测试环境会非常灵活。noReset这个参数很重要,设置为True可以保留App的数据状态,适合连续执行多个测试用例;设置为False则每次都会清空数据,保证用例独立性。

4.2 元素定位策略与页面对象模型实践

元素定位是UI自动化的基石。Appium支持多种定位器,但如何选用大有讲究。

常用定位器:

  • ID/Resource-Id (Android) / accessibility id (iOS):首选。通常由开发设置,唯一且稳定。driver.find_element(AppiumBy.ID, “com.example:id/login_button”)
  • XPath:功能强大,但性能相对较差,且容易因UI微调而失效。应尽量避免使用绝对路径(/html/body/...)和包含索引的路径(//android.widget.Button[3])。尽量使用相对路径和属性组合,如//android.widget.EditText[@text=“请输入用户名”]。
  • Class Name:通常只能定位到一类元素,需要结合其他条件或使用find_elements后过滤。
  • Android UIAutomator / iOS Predicate String:平台原生的定位方式,表达式灵活强大,适合复杂定位。例如Android:driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, ‘new UiSelector().text(“登录”)’)

强烈推荐:页面对象模型:这是让测试脚本变得可维护、可复用的关键设计模式。其核心思想是将每个页面封装成一个类,页面上的元素作为这个类的属性,页面上的操作(如输入、点击)作为这个类的方法。

# login_page.py from appium.webdriver.common.appiumby import AppiumBy class LoginPage: def __init__(self, driver): self.driver = driver # 定义页面元素定位器 self.username_input = (AppiumBy.ID, ‘com.example:id/username’) self.password_input = (AppiumBy.ID, ‘com.example:id/password’) self.login_button = (AppiumBy.ID, ‘com.example:id/login_btn’) self.error_toast = (AppiumBy.XPATH, ‘//android.widget.Toast’) def enter_username(self, username): self.driver.find_element(*self.username_input).send_keys(username) def enter_password(self, password): self.driver.find_element(*self.password_input).send_keys(password) def click_login(self): self.driver.find_element(*self.login_button).click() def get_error_message(self): # Toast提示可能需要特殊方式获取,这里仅为示例 try: return self.driver.find_element(*self.error_toast).text except: return None # 在测试脚本中使用 def test_login_failure(driver): login_page = LoginPage(driver) login_page.enter_username(‘wrong_user’) login_page.enter_password(‘wrong_pass’) login_page.click_login() error_msg = login_page.get_error_message() assert ‘登录失败’ in error_msg

这样做的好处是,当登录页面的按钮ID从login_btn改成sign_in_btn时,你只需要在一个地方(LoginPage类)修改定位器,所有用到这个按钮的测试脚本都自动生效,维护成本极低。

4.3 登录流程的跨平台脚本实现与断言

结合POM,我们的测试脚本会非常清晰。同时,我们需要处理平台差异。

# test_login.py - 使用pytest框架 import pytest from appium import webdriver from login_page import LoginPage from home_page import HomePage # 假设登录成功后跳转到首页 # 使用fixture来管理driver的生命周期 @pytest.fixture(scope=“function”) # 每个测试函数一个独立的session def driver(appium_server_url, platform_caps): # 假设这些参数通过conftest.py或其他方式传入 _driver = webdriver.Remote(appium_server_url, options=platform_caps) yield _driver # 测试函数执行时使用这个driver _driver.quit() # 测试函数执行完毕后退出 def test_successful_login(driver): """测试成功登录""" login_page = LoginPage(driver) home_page = HomePage(driver) # 执行登录操作 login_page.enter_username(‘valid_user’) login_page.enter_password(‘valid_password’) login_page.click_login() # 验证登录成功:通常通过跳转后的页面元素来判断 # 方法1:等待首页某个特有元素出现 welcome_element = home_page.wait_for_welcome_message(timeout=10) assert welcome_element is not None assert ‘欢迎’ in welcome_element.text # 方法2:检查登录按钮是否消失(页面已跳转) # assert not login_page.is_login_button_present() def test_login_with_empty_password(driver): """测试密码为空时的登录行为""" login_page = LoginPage(driver) login_page.enter_username(‘valid_user’) # 不输入密码,直接点击登录 login_page.click_login() # 验证出现了正确的错误提示(可能是Toast或页面内的文本) error_msg = login_page.get_error_message() # 这里断言需要根据实际App的提示文案来调整 assert error_msg is not None assert ‘密码’ in error_msg and ‘空’ in error_msg # 示例断言

处理平台差异:如果Android和iOS的UI差异很大,定位器不同,我们可以在页面对象内部做判断。

# 在LoginPage类的__init__中 def __init__(self, driver): self.driver = driver platform = driver.capabilities[‘platformName’] if platform.lower() == ‘android’: self.login_button = (AppiumBy.ID, ‘com.example.android:id/login’) self.error_text = (AppiumBy.ID, ‘com.example.android:id/error_tv’) elif platform.lower() == ‘ios’: self.login_button = (AppiumBy.ACCESSIBILITY_ID, ‘LoginButton’) # iOS常用accessibility id self.error_text = (AppiumBy.IOS_PREDICATE, ‘label == “Error Message”’)

5. 高级技巧与最佳实践:让测试更稳定、更高效

写一个能跑的脚本不难,写一个能在不同设备、不同网络、不同时间下都稳定运行的脚本,才是挑战。

5.1 等待机制:解决“元素找不到”的头号利器

超过一半的自动化测试失败是由于“元素未找到”或“元素不可交互”。罪魁祸首往往是页面加载或渲染的延迟。粗暴地使用time.sleep()是下策,它会拖慢测试速度且不可靠。Appium推荐使用显式等待。

from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from appium.webdriver.common.appiumby import AppiumBy # 等待一个元素出现并可点击,最多等10秒,每0.5秒检查一次 wait = WebDriverWait(driver, 10, poll_frequency=0.5) login_btn = wait.until(EC.element_to_be_clickable((AppiumBy.ID, ‘com.example:id/login_btn’))) login_btn.click() # 也可以封装成页面对象的方法 class BasePage: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def find_clickable_element(self, locator): “”“查找一个可点击的元素”“” return self.wait.until(EC.element_to_be_clickable(locator)) class LoginPage(BasePage): # 继承BasePage def click_login(self): btn = self.find_clickable_element(self.login_button) btn.click()

隐式等待(driver.implicitly_wait(10)) 可以全局设置一个查找元素的超时时间,但它不够灵活,无法针对特定条件(如可点击、可见)。建议以显式等待为主,隐式等待为辅或不用。

5.2 测试数据管理与参数化

测试数据(如用户名、密码、搜索关键词)不应该硬编码在脚本里。使用参数化可以轻松实现数据驱动测试。

import pytest import json # 从JSON文件加载测试数据 with open(‘test_data/login_data.json’, ‘r’) as f: test_cases = json.load(f) @pytest.mark.parametrize(“username, password, expected_result”, [ (“”, “123456”, “用户名为空”), (“test@example.com”, “”, “密码为空”), (“wrong”, “wrong”, “用户名或密码错误”), (“valid@example.com”, “correct_pwd”, “登录成功”), ]) def test_login_parametrize(driver, username, password, expected_result): login_page = LoginPage(driver) login_page.enter_username(username) login_page.enter_password(password) login_page.click_login() if expected_result == “登录成功”: # 验证成功逻辑 assert HomePage(driver).is_displayed() else: # 验证失败逻辑 assert expected_result in login_page.get_error_message()

将测试数据和测试逻辑分离,使得添加新的测试用例只需要修改数据文件,脚本结构保持不变,维护性极高。

5.3 测试报告与日志记录

没有报告和日志的自动化测试是没有灵魂的。我们需要知道测试通过了多少,失败了多少,失败在哪里。

  • Allure报告:与pytest集成度极高,可以生成非常美观、详细的HTML报告,包含测试步骤、截图、日志等。

    # 运行测试并生成Allure结果数据 pytest test_login.py –alluredir=./allure-results # 生成HTML报告 allure serve ./allure-results

    在测试脚本中,可以使用@allure.step装饰器来标记测试步骤,使报告更清晰。

  • 日志记录:使用Python内置的logging模块,将运行过程中的关键信息(如开始执行某某用例、定位到了什么元素、发生了错误等)记录到文件,方便排查问题。

    import logging logging.basicConfig(level=logging.INFO, format=‘%(asctime)s - %(name)s - %(levelname)s - %(message)s’) logger = logging.getLogger(__name__) def click_login(self): logger.info(“尝试点击登录按钮”) try: btn = self.find_clickable_element(self.login_button) btn.click() logger.info(“登录按钮点击成功”) except Exception as e: logger.error(f“点击登录按钮失败: {e}”) self.driver.save_screenshot(“click_login_failed.png”) # 失败时截图 raise

失败自动截图:如上例所示,在关键操作或断言失败时自动截图,是定位UI问题最直观的手段。可以将其封装成一个装饰器或放在pytest的钩子函数中,实现失败用例自动截图并附加到测试报告里。

6. 常见问题排查与性能优化实录

在实际项目中,你会遇到各种各样稀奇古怪的问题。这里记录几个我印象最深的“坑”和解决办法。

6.1 元素定位失败问题排查表

问题现象可能原因排查步骤与解决方案
NoSuchElementException1. 页面未加载完成。
2. 定位器写错了(ID变更、XPath失效)。
3. 元素在WebView或Flutter等非原生容器内,需要切换上下文。
4. 元素在弹窗、新Activity或Fragment中。
1.增加显式等待,等待元素出现或可交互。
2.使用Appium Inspector或UIAutomatorViewer重新检查元素属性,更新定位器。优先使用唯一的resource-id或accessibility id。
3.打印当前页面源码:driver.page_source,查看元素是否存在。对于混合应用,检查并切换Context:driver.contexts和driver.switch_to.context(‘WEBVIEW_xxx’)。
4. 对于弹窗,可能需要先定位并关闭弹窗,或者确保操作在正确的窗口句柄下。
ElementNotInteractableException1. 元素被遮挡(如弹窗、蒙层)。
2. 元素不可见(visible=“false”)。
3. 元素虽是可见的,但处于不可交互状态(如enabled=“false”)。
1.检查是否有弹窗,先处理掉遮挡物。
2. 尝试使用JavaScript(在WebView中)或mobile: scroll等滚动操作,将元素滚动到可视区域。
3. 检查元素属性,确认其enabled和visible均为true。有时需要等待一小段时间让元素变为可交互状态。
脚本在iOS和Android上行为不一致1. 平台UI差异导致定位器不同。
2. 手势或API在不同平台上有差异。
3. 应用本身在不同平台上的逻辑或响应速度不同。
1.实现平台无关的页面对象,在内部根据平台返回不同的定位器或执行不同的操作链。
2.封装平台特定的操作,如iOS的mobile: swipe和Android的swipe手势参数可能不同。
3.调整等待策略,iOS可能比Android渲染慢或快,需要针对性地调整显式等待的超时时间。

6.2 会话管理与性能瓶颈

会话启动慢:每次webdriver.Remote()都会启动一个新的Appium会话,这个过程包括安装/启动App,耗时可能长达几十秒。对于一套需要执行大量用例的测试集,这是不可接受的。

  • 解决方案:尽量复用会话。使用noReset: true或fullReset: false能力,避免每次重置App。将多个相关的测试用例组织在一个pytest的class里,并使用scope=“class”的fixture来初始化driver,让这个class内的所有测试方法共享同一个会话。但要注意测试用例之间的独立性,避免状态污染。

测试执行慢:

  • 定位器优化:避免使用复杂的、遍历整个树的XPath。优先使用ID。对于列表中的元素,可以先定位父容器,再在容器内查找。
  • 操作合并:减少不必要的find_element调用。找到元素后,如果需要多次操作,可以存储引用。
  • 并行测试:利用Appium Grid或Selenium Grid架构,同时在多台设备/模拟器上运行测试。这需要将测试脚本设计成无状态的,并且妥善管理测试数据和报告聚合。

稳定性问题:除了等待机制,网络波动、设备资源不足(内存、CPU)、App本身的内存泄漏都可能导致测试失败。

  • 增加重试机制:对于非逻辑性的失败(如网络超时、偶现的元素找不到),可以使用pytest的@pytest.mark.flaky装饰器或自己实现重试逻辑。
  • 监控设备状态:在测试开始前和结束后,检查设备日志(adb logcat)、内存占用等,有助于发现系统性问题的根源。

6.3 与持续集成流水线集成

自动化测试只有集成到CI/CD(如Jenkins, GitLab CI, GitHub Actions)中,才能发挥最大价值,实现“持续测试”。

  1. 环境准备:CI机器上需要安装好Appium Server、对应平台的SDK和依赖。可以使用Docker镜像来标准化环境,例如appium/appium的官方Docker镜像。
  2. 启动服务:在CI脚本中,需要先启动Appium Server,可以以后台进程方式运行:appium --log-level error &。
  3. 连接设备:如果是真机,需要提前连接并配置好;如果是模拟器/仿真器,需要在CI脚本中启动它。云测平台(如Sauce Labs, BrowserStack, 国内的各云测平台)则省去了这个麻烦,但需要付费。
  4. 执行测试:运行测试命令,如pytest --alluredir=./results。
  5. 收集结果:测试完成后,收集Allure报告、日志和截图,归档或发布到CI系统的展示页面。
  6. 清理环境:无论测试成功与否,都要确保退出driver、关闭模拟器、停止Appium Server,释放资源。

一个简单的GitHub Actions工作流示例:

name: Appium UI Tests on: [push] jobs: test: runs-on: macos-latest # iOS测试必须在macOS上 steps: - uses: actions/checkout@v3 - name: Set up Node.js uses: actions/setup-node@v3 - name: Install Appium run: npm install -g appium - name: Start Appium Server run: | appium --log-level error & sleep 10 # 等待服务器启动 - name: Run Tests run: pytest --alluredir=./allure-results - name: Generate Allure Report if: always() uses: simple-elf/allure-report-action@master with: allure_results: allure-results allure_report: allure-report - name: Upload Allure Report if: always() uses: actions/upload-artifact@v3 with: name: allure-report path: allure-report

这条路走下来,你会发现Appium自动化测试不是一个简单的“录制回放”工具,而是一个需要测试人员具备一定开发思维、架构意识和调试能力的工程实践。从理解其能力边界,到设计稳定的测试用例,再到集成到开发流程中,每一步都需要耐心和积累。但当你看到每次代码提交后,自动化测试套件都能自动运行并快速反馈结果时,那种对产品质量的掌控感和效率提升带来的成就感,会让你觉得所有的投入都是值得的。

相关新闻

  • 国内口碑好的手机平板回收品牌有哪些
  • GM-Alt₂富勒烯室温超导体系学术评价
  • HTML5+CSS3+JS小实例:图片懒加载

最新新闻

  • 5分钟掌握音乐解锁工具:让加密音乐文件重获自由
  • 【AI生产力投资回报率白皮书】:基于1,243名知识工作者的付费行为分析,这3类人建议立刻开通,其余人慎付!
  • 【Ambari Plus】02.Ranger 安装
  • 5分钟快速上手:ucore操作系统实验环境搭建终极指南
  • 深入解析MSPM0 DEBUGSS与SWD接口:从调试原理到实战应用
  • Java毕业设计-基于 SpringBoot+Vue 的公司考勤管理系统的设计与实现 前后端分离的企业员工考勤管理系统设计与开发(源码+LW+部署文档+全bao+远程调试+代码讲解等)

日新闻

  • 【计算机毕业设计案例】基于 Spring Boot+Vue 的电影售票系统设计与实现 前后端分离架构下影院在线购票管理平台(程序+文档+讲解+定制)
  • 到底 TMD 用哪个: npm, pnpm, Yarn, Bun, Deno? 傻瓜, 当然用 npm 啦
  • Google限制Meta使用Gemini模型 凸显AI授权竞争白热化

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号