常见的交互方法
大家好,接下来我们来看看常见的控件交互方法有哪些。在自动化测试中,尤其是移动端测试,我们经常需要与 APP 的控件进行交互,比如点击按钮、输入文本、获取元素属性等。这些操作是自动化测试的基础,掌握它们可以帮助我们更好地模拟用户行为,验证 APP 的功能和性能。
简介
与 Web 元素操作一样(参考 Selenium Web 元素操作),定位到 APP 控件元素后,可以对控件进行一系列的操作,实现与 APP 交互,比如点击、文本输入、元素属性获取等。
与 Web 元素操作类似,定位到 APP 控件后,我们可以对它进行一系列操作,比如点击、输入文本、获取属性等。Appium 的交互方式和 Web 测试非常相似,基本步骤就是先定位元素,然后执行操作。举个例子,我们可以通过 Appium 模拟用户点击登录按钮、输入用户名和密码、获取某个元素的显示状态等。简单来说,定位到元素后,我们就能对它进行多种操作,从而自动化完成用户行为。
控件交互常用方法
接下来,我们来看一些常用的控件交互方法。这些方法可以帮助我们实现点击、输入、状态判断等操作。掌握这些方法后,我们就能轻松地编写自动化测试脚本了。
常见操作
- 点击元素:
element.click()
。 - 点击坐标:
driver.tap([(x, y)], 1000)
- 元素中输入内容:
element.send_keys('appium')
。 - 清除元素中内容:
element.clear()
。
首先,我们来看一些常见的操作。比如,点击元素可以使用 element.click(),而点击屏幕上的某个坐标则可以使用 driver.tap([(x, y)], 1000)。如果你想在输入框中输入内容,可以使用 element.send_keys('appium'),而清除输入框内容则可以使用 element.clear()。这些操作都非常简单,但它们是自动化测试中最常用的基础操作。
状态判断
- 是否可见
element.is_displayed()
返回 True/False。 - 是否可用
element.is_enabled()
返回 True/False。 - 是否被选中
element.is_selected()
返回 True/False。
除了操作元素,我们还需要判断元素的状态。比如,我们可以通过 element.is_displayed() 来判断元素是否可见,返回 True 或 False。同样地,element.is_enabled() 可以判断元素是否可用,而 element.is_selected() 则用于判断元素是否被选中。这些方法在测试中非常有用,尤其是在验证页面元素的交互逻辑时。
获取元素属性
- 获取元素属性:
element.get_attribute()
- resource-id
- text
- class
- content-desc
- checkable、checked、clickable、enabled、focusable、focused 等
- 获取元素文本:
element.text
- 获取元素坐标:
- 格式:
element.location
- 结果:
{'y': 19,'x: 498}
- 获取元素尺寸(高和宽):
- 格式:
element.size
- 结果:
{'width':500,'height':22}
有时候,我们需要获取元素的属性信息。比如,通过 element.get_attribute() 可以获取元素的 resource-id、text、class 等属性。我们还可以通过 element.text 获取元素的文本内容,或者通过 element.location 获取元素的坐标位置。此外,element.size 可以获取元素的尺寸,返回宽度和高度。这些信息在测试中非常有用,尤其是在验证 UI 布局和元素位置时。
控件操作交互示例
- 使用 appium 官方 Demo apk 进行练习,apk 网盘地址。
- 打开 ApiDemos.apk。
- 点击 Animation 进入下个页面。
- 点击 Seeking 进入下个页面。
- 查看【RUN】按钮是否显示/是否可点击。
- 查看【滑动条】是否显示/是否可点击。
- 获取【滑动条】长度。
- 点击【滑动条】中心位置。
接下来,我们通过一个实际的例子来练习这些操作。我们可以使用 Appium 官方提供的 Demo APK 进行练习。首先,我们打开 ApiDemos.apk,然后点击 Animation 进入下一个页面,接着点击 Seeking 进入下一个页面。在这个页面上,我们可以查看【RUN】按钮是否显示、是否可点击,还可以查看【滑动条】的显示状态和可点击状态。最后,我们可以获取【滑动条】的长度,并点击它的中心位置。这个例子涵盖了前面提到的所有操作,非常实用。
Python 代码示例
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
class TestEleOper:
def setup_class(self):
'''
完成 capability 设置
初始化 driver
:return:
'''
# 设置 cpability
caps = {
# 设置 app 安装的平台(Android,iOS)
"platformName": "Android",
# 设置 appium 驱动
"appium:automationName": "uiautomator2",
# 设置设备名称
"appium:deviceName": "emulator-5554",
# 设置被测 app 的包名
"appium:appPackage": "io.appium.android.apis",
# 设置被测 app 启动页面的 Activity
"appium:appActivity": ".ApiDemos"
}
# 初始化 driver
self.driver = webdriver.Remote(
"http://127.0.0.1:4723",
options=UiAutomator2Options().load_capabilities(caps)
)
# 设置全局隐式等待
self.driver.implicitly_wait(5)
def teardown_class(self):
'''
关闭 driver
:return:
'''
self.driver.quit()
def test_ele_oper(self):
'''
点击滑动条中心位置
:return:
'''
# 点击 Animation
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, "Animation"
).click()
# 点击 Seeking
self.driver.find_element(
AppiumBy.ACCESSIBILITY_ID, "Seeking"
).click()
# 查看【RUN】按钮是否显示/是否可点击
run_btn_ele = self.driver.find_element(
AppiumBy.ID, "io.appium.android.apis:id/startButton"
)
print(f"RUN 按钮是否显示 {run_btn_ele.is_displayed()}")
print(f"RUN 按钮是否可用 {run_btn_ele.is_enabled()}")
print(f"RUN 按钮是否可点击 {run_btn_ele.get_attribute('clickable')}")
# 查看【滑动条】是否显示/是否可点击
seek_bar_ele = self.driver.find_element(
AppiumBy.ID, "io.appium.android.apis:id/seekBar"
)
print(f"滑动条是否显示 {seek_bar_ele.is_displayed()}")
print(f"滑动条是否可点击 {seek_bar_ele.get_attribute('clickable')}")
# 查看【滑动条】的属性
print(f"滑动条的 resource-id 属性为 {seek_bar_ele.get_attribute('resource-id')}")
print(f"滑动条的 text 属性为 {seek_bar_ele.get_attribute('text')}")
print(f"滑动条的 class 属性为 {seek_bar_ele.get_attribute('class')}")
print(f"滑动条的 content-desc 属性为 {seek_bar_ele.get_attribute('content-desc')}")
# 获取【滑动条】长度
seek_bar_ele_width = seek_bar_ele.size.get('width')
print(f"滑动条长度为 {seek_bar_ele_width}")
# 获取【滑动条】起始位置坐标
seek_bar_ele_start = seek_bar_ele.location
print(f"滑动条起始位置坐标为 {seek_bar_ele_start}")
# 获取【滑动条】中间位置坐标
seek_bar_center_x = seek_bar_ele_start.get("x") + seek_bar_ele_width / 2
seek_bar_center_y = seek_bar_ele_start.get("y")
seek_bar_center = (seek_bar_center_x, seek_bar_center_y)
print(f"滑动条中间位置坐标为 {seek_bar_center}")
# 点击【滑动条】中间位置
self.driver.tap([seek_bar_center], 1000)
现在,我们来看一个 Python 的代码示例。这段代码展示了如何使用 Appium 进行控件交互。首先,我们初始化了 Appium 的 driver,然后通过 find_element 方法定位到元素。接着,我们使用 click() 方法点击元素,使用 send_keys() 方法输入文本,使用 is_displayed() 和 is_enabled() 方法判断元素状态。最后,我们还获取了元素的属性信息,比如 resource-id 和 text,并通过 tap() 方法点击了滑动条的中心位置。这段代码非常直观,展示了如何通过代码实现自动化操作。
Java 代码示例
package org.example;
import io.appium.java_client.AppiumBy;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.Collections;
public class TestEleOper {
private static AndroidDriver driver;
@BeforeAll
public static void setUp() throws MalformedURLException {
// 初始化capability
DesiredCapabilities caps = new DesiredCapabilities();
// 设置 app 安装的平台(Android、iOS)
caps.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
// 设置 appium 驱动
caps.setCapability(MobileCapabilityType.AUTOMATION_NAME, "UiAutomator2");
// 设置设备名称
caps.setCapability(MobileCapabilityType.DEVICE_NAME, "emulator-5554");
// 设置 app 的包名
caps.setCapability("appPackage", "io.appium.android.apis");
// 设置 app 的启动页
caps.setCapability("appActivity", ".ApiDemos");
// 设置 app 不清空缓存
caps.setCapability("appium:noReset", true);
// 设置 app 不重启
caps.setCapability("appium:shouldTerminateApp", true);
// 设置启动url
URL remoteUrl = new URL("http://127.0.0.1:4723");
// 初始化driver
driver = new AndroidDriver(remoteUrl, caps);
}
@AfterAll
public static void teardownClass() {
if (driver != null) {
driver.quit();
}
}
@Test
public void testEleOper() {
// 点击 Animation
driver.findElement(AppiumBy.accessibilityId("Animation")).click();
// 点击 Seeking
driver.findElement(AppiumBy.accessibilityId("Seeking")).click();
// 查看【RUN】按钮是否显示/是否可点击
WebElement runBtnEle = driver.findElement(AppiumBy.id("io.appium.android.apis:id/startButton"));
System.out.println("RUN 按钮是否显示: " + runBtnEle.isDisplayed());
System.out.println("RUN 按钮是否可用: " + runBtnEle.isEnabled());
System.out.println("RUN 按钮是否可点击: " + runBtnEle.getAttribute("clickable"));
// 查看【滑动条】是否显示/是否可点击
WebElement seekBarEle = driver.findElement(AppiumBy.id("io.appium.android.apis:id/seekBar"));
System.out.println("滑动条是否显示: " + seekBarEle.isDisplayed());
System.out.println("滑动条是否可点击: " + seekBarEle.getAttribute("clickable"));
// 查看【滑动条】的属性
System.out.println("滑动条的 resource-id 属性为: " + seekBarEle.getAttribute("resource-id"));
System.out.println("滑动条的 text 属性为: " + seekBarEle.getAttribute("text"));
System.out.println("滑动条的 class 属性为: " + seekBarEle.getAttribute("class"));
System.out.println("滑动条的 content-desc 属性为: " + seekBarEle.getAttribute("content-desc"));
// 获取【滑动条】长度
int seekBarEleWidth = seekBarEle.getSize().getWidth();
System.out.println("滑动条长度为: " + seekBarEleWidth);
// 获取【滑动条】起始位置坐标
Point seekBarEleStart = seekBarEle.getLocation();
System.out.println("滑动条起始位置坐标为: " + seekBarEleStart);
// 获取【滑动条】中间位置坐标
int seekBarCenterX = seekBarEleStart.getX() + seekBarEleWidth / 2;
int seekBarCenterY = seekBarEleStart.getY();
System.out.println("滑动条中间位置坐标为: (" + seekBarCenterX + ", " + seekBarCenterY + ")");
// 点击【滑动条】中间位置
PointerInput finger = new PointerInput(PointerInput.Kind.TOUCH, "finger");
Sequence sequence = new Sequence(finger, 1)
.addAction(finger.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), seekBarCenterX, seekBarCenterY))
.addAction(finger.createPointerDown(PointerInput.MouseButton.LEFT.asArg()))
.addAction(finger.createPointerUp(PointerInput.MouseButton.LEFT.asArg()));
driver.perform(Collections.singletonList(sequence));
}
}
接下来是 Java 的代码示例。这段代码的功能和 Python 示例类似,但使用的是 Java 语言。我们首先初始化了 AndroidDriver,然后通过 findElement 方法定位到元素。接着,我们使用 click() 方法点击元素,使用 isDisplayed() 和 isEnabled() 方法判断元素状态。最后,我们获取了元素的属性信息,并通过 PointerInput 和 Sequence 实现了点击滑动条中心位置的操作。这段代码展示了如何在 Java 中使用 Appium 进行控件交互。
总结
- 常见操作
- 状态判断
- 获取元素属性
最后,我们来总结一下今天的内容。我们学习了常见的控件交互方法,包括点击、输入、状态判断和获取元素属性。这些方法是自动化测试的基础,掌握它们可以帮助我们更好地编写测试脚本。希望大家通过今天的课程,能够熟练使用这些方法,并在实际项目中应用它们。