如何在Appium Android自动化测试中拆分脚本并保持应用运行状态?
Appium拆分脚本保持应用持续运行的可行性及实现方案
当然可行!这种场景在Appium自动化测试里太常见了——尤其是当你想把测试逻辑拆分成不同阶段(比如把登录作为前置步骤,后续执行业务流程测试),同时避免重复启动应用带来的时间损耗。下面给你详细讲讲具体的实现思路和方法:
核心思路:复用同一个Appium Driver实例
Appium的Driver实例是和设备/应用会话绑定的,只要你不调用driver.quit(),这个会话就会一直保持,应用也不会被关闭。所以实现需求的关键,就是让第二部分脚本能拿到第一部分创建好的Driver实例,继续操作。
方式一:借助测试框架的全局会话机制(推荐)
如果你用JUnit、TestNG(Java)或者Pytest(Python)这类测试框架,完全可以利用它们的全局前置/后置钩子来初始化一次Driver,然后让多个测试方法复用这个实例。这种方式最规范,也最容易维护。
示例1:TestNG(Java)
import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.MobileElement; import org.openqa.selenium.By; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.*; import java.net.URL; public class AppSplitTest { // 全局Driver实例,所有测试方法共享 private static AndroidDriver<MobileElement> driver; @BeforeSuite public void setupGlobalDriver() throws Exception { // 配置Desired Capabilities DesiredCapabilities caps = new DesiredCapabilities(); caps.setCapability("platformName", "Android"); caps.setCapability("deviceName", "emulator-5554"); caps.setCapability("appPackage", "com.your.app"); caps.setCapability("appActivity", ".MainActivity"); // noReset设为false(首次启动需要登录),如果后续要保留状态可以设为true caps.setCapability("noReset", false); // 初始化Driver,建立会话 driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), caps); } @Test(priority = 1) public void testLoginFlow() { // 执行登录操作 driver.findElement(By.id("com.your.app:id/et_username")).sendKeys("test_user"); driver.findElement(By.id("com.your.app:id/et_password")).sendKeys("test_pass"); driver.findElement(By.id("com.your.app:id/btn_login")).click(); // 等待登录完成,进入主页面 WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.presenceOfElementLocated(By.id("com.your.app:id/main_container"))); } @Test(priority = 2) public void testBusinessOperations() { // 直接复用全局Driver,此时应用处于登录后的状态 driver.findElement(By.id("com.your.app:id/btn_my_profile")).click(); // 继续执行业务流程测试,比如查看个人信息、提交表单等 } @AfterSuite public void teardownGlobalDriver() { // 所有测试完成后,再关闭Driver和应用 if (driver != null) { driver.quit(); } } }
示例2:Pytest(Python)
import pytest from appium import webdriver # 定义全局会话级别的fixture,所有测试用例共享 @pytest.fixture(scope="session") def appium_driver(): desired_caps = { "platformName": "Android", "deviceName": "emulator-5554", "appPackage": "com.your.app", "appActivity": ".MainActivity", "noReset": False } # 初始化Driver driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps) yield driver # 会话结束后关闭Driver driver.quit() def test_login(appium_driver): # 登录操作逻辑 appium_driver.find_element_by_id("com.your.app:id/et_username").send_keys("test_user") appium_driver.find_element_by_id("com.your.app:id/et_password").send_keys("test_pass") appium_driver.find_element_by_id("com.your.app:id/btn_login").click() # 验证登录成功 appium_driver.implicitly_wait(10) assert appium_driver.find_element_by_id("com.your.app:id/main_container").is_displayed() def test_business_flow(appium_driver): # 复用Driver执行后续业务操作 appium_driver.find_element_by_id("com.your.app:id/btn_my_profile").click() # 其他业务测试步骤...
方式二:手动保存会话ID,跨脚本复用
如果你的两个脚本是完全独立的文件(比如两个分开的Python脚本),可以在第一部分脚本结束时保存会话信息,第二部分脚本通过这些信息重新连接到已有的会话,而不是新建会话。
步骤1:第一部分(登录脚本)
from appium import webdriver desired_caps = { "platformName": "Android", "deviceName": "emulator-5554", "appPackage": "com.your.app", "appActivity": ".MainActivity", "noReset": False } # 初始化Driver并执行登录 driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps) driver.find_element_by_id("com.your.app:id/et_username").send_keys("test_user") driver.find_element_by_id("com.your.app:id/et_password").send_keys("test_pass") driver.find_element_by_id("com.your.app:id/btn_login").click() driver.implicitly_wait(10) assert driver.find_element_by_id("com.your.app:id/main_container").is_displayed() # 保存会话信息到临时文件 session_info = { "server_url": driver.command_executor._url, "session_id": driver.session_id } with open("session_data.txt", "w") as f: f.write(f"{session_info['server_url']}\n{session_info['session_id']}") # 注意:这里绝对不要调用driver.quit()!
步骤2:第二部分(业务脚本)
from appium.webdriver.webdriver import WebDriver # 读取之前保存的会话信息 with open("session_data.txt", "r") as f: server_url = f.readline().strip() session_id = f.readline().strip() # 重新连接到已有的会话 driver = WebDriver(command_executor=server_url, desired_capabilities={}) driver.session_id = session_id # 现在可以直接操作应用,此时应用处于登录后的状态 driver.find_element_by_id("com.your.app:id/btn_my_profile").click() # 后续业务测试逻辑... # 所有操作完成后,再决定是否关闭Driver # driver.quit()
关键注意事项
- 绝对不要在第一部分脚本中调用
driver.quit(),否则会话会被销毁,应用也会被关闭。 - 关于
noReset和fullReset:noReset=true会让Appium不重置应用数据,适合长期保持登录状态;如果是首次运行需要登录,可设为noReset=false,后续复用会话时保持noReset=true。fullReset必须设为false,否则Appium会重新安装应用,之前的状态会丢失。
- 确保Appium服务器在整个测试过程中持续运行,不要重启服务器,否则所有会话都会失效。
内容的提问来源于stack exchange,提问作者Dtg
相关产品推荐
相关产品推荐

