常用测试方式与代码
具体的操作方式类似于“远古”时期,程序员操作 DOM
元素一样
识别与操作控件元素
Appium Inspector的用法
需要用到 Appium Inspector
相关博客:https://zhuanlan.zhihu.com/p/517599445
最有效率的获取元素的方法如图所示
使用代码获取元素
如下示例承接前文:通过逍遥模拟器
- 进入软件
设置
- 获取元素
网络和互联网
并点击进入 - 获取该级目录下所有选项的主要文字并输出出来
import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
public class AppTest {
// 创建驱动对象,这里是空的
protected static AndroidDriver driver = null;
// private static AppiumDriverLocalService service;
@Test
public void run() throws InterruptedException {
// 通过XPath来获取元素,并点击
driver.findElement(AppiumBy.xpath("//*[@text='网络和互联网']")).click();
// 等待3秒,为了让效果看起来更明显
Thread.sleep(3000);
// 子层级,这里的id指的是resource-id,并且不是唯一的,这里和web页面不同
List<WebElement> subElements = driver.findElements(AppiumBy.id("android:id/title"));
// 遍历每一个元素
for (WebElement e: subElements){
// 获取文字
System.out.println(e.getText());
}
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
// DesiredCapabilities 可以理解为是 必需设备信息 类
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.settings");
device.setCapability("appActivity", ".Settings");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
}
@AfterClass
public void afterClass(){
if (driver != null) driver.quit();
}
}
模拟按键操作
相关博客:https://blog.csdn.net/mahoon411/article/details/125411407
这里我想在进入 网络和互联网
之后,等待两秒之后返回上一级
代码如下
import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
public class KeyCodeTest {
protected static AndroidDriver driver = null;
@Test
public void run() throws InterruptedException {
driver.findElement(AppiumBy.xpath("//*[@text='网络和互联网']")).click();
Thread.sleep(2000);
// 第二步,点击按钮返回
driver.pressKey(new KeyEvent(AndroidKey.BACK));
Thread.sleep(2000);
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
// 第一步,从这里进入设置
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.settings");
device.setCapability("appActivity", ".Settings");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
}
@AfterClass
public void afterClass(){
if (driver != null) driver.quit();
}
}
勾选单选框和操作开关
这里用到的是 逍遥模拟器
自带的 Chrome浏览器
本质上也是调用 click()
方法
import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class TestChrome {
protected static AndroidDriver driver = null;
@Test
public void run() throws InterruptedException {
// 进入设置
driver.findElement(AppiumBy.accessibilityId("更多选项")).click();
driver.findElement(AppiumBy.accessibilityId("设置")).click();
// 进入密码
driver.findElement(By.xpath("//*[@text='密码']")).click();
// 关闭保存密码
WebElement toggleSwitch = driver.findElement(By.id("com.android.chrome:id/switch_widget"));
// 如果已启用,就关闭
if (toggleSwitch.isEnabled()) toggleSwitch.click();
// 关闭自动登录
WebElement checkBox = driver.findElement(By.id("android:id/checkbox"));
// 如果已启用,就关闭
if (checkBox.isEnabled()) checkBox.click();
// 等待3秒,为了让效果看起来更明显
Thread.sleep(3000);
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.chrome");
device.setCapability("appActivity", "com.google.android.apps.chrome.Main");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
// 隐式等待十秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
// 初始化软件的初步设置
driver.findElement(By.id("com.android.chrome:id/terms_accept")).click();
driver.findElement(By.id("com.android.chrome:id/button_primary")).click();
}
@AfterClass
public void afterClass(){
if (driver != null) driver.quit();
}
}
操作通知栏
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class TestNotifications {
protected static AndroidDriver driver = null;
@Test
public void run() throws InterruptedException {
// 打开通知栏
driver.openNotifications();
Thread.sleep(3000);
// 返回键触发关闭通知栏
driver.navigate().back();
Thread.sleep(3000);
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.chrome");
device.setCapability("appActivity", "com.google.android.apps.chrome.Main");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
// 隐式等待十秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
@AfterClass
public void afterClass(){
if (driver != null) driver.quit();
}
}
手势滑动
期望效果:下拉通知栏,然后收回通知栏
统一设置,设置 逍遥模拟器
的显示分辨率为 1200*1920
如图所示
这里用到的还是 Chrome浏览器
,不过需要做一些准备工作
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class TestAction {
protected static AndroidDriver driver = null;
@Test
public void run() throws InterruptedException {
// 准备工作
WebElement ipt = driver.findElement(By.id("com.android.chrome:id/url_bar"));
// 需要先点击再回车
ipt.click();
ipt.sendKeys("HelloWorld");
driver.pressKey(new KeyEvent(AndroidKey.ENTER));
// 上滑操作
Actions actions = new Actions(driver);
WebElement firstElement = driver.findElements(By.className("android.view.View")).get(0);
actions.dragAndDropBy(firstElement, 0, -500).perform();
Thread.sleep(3000);
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.chrome");
device.setCapability("appActivity", "com.google.android.apps.chrome.Main");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
// 隐式等待十秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
// 初始化软件的初步设置
driver.findElement(By.id("com.android.chrome:id/terms_accept")).click();
driver.findElement(By.id("com.android.chrome:id/button_primary")).click();
}
@AfterClass
public void afterClass() {
if (driver != null) driver.quit();
}
}
九宫格手势解锁
没有找到用来测试的app,这里用坐标定位法做一下上面的 手势滑动 示例
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class TestAction {
protected static AndroidDriver driver = null;
@Test
public void run() throws InterruptedException {
// 准备工作
WebElement ipt = driver.findElement(By.id("com.android.chrome:id/url_bar"));
// 需要先点击再回车
ipt.click();
ipt.sendKeys("HelloWorld");
driver.pressKey(new KeyEvent(AndroidKey.ENTER));
// 上滑操作
Actions actions = new Actions(driver);
// WebElement firstElement = driver.findElements(By.className("android.view.View")).get(0);
// actions.dragAndDropBy(firstElement, 0, -500).perform();
actions
// 移动鼠标到指定坐标
.moveToLocation(600,960)
// 需要暂停等待鼠标移动过去
.pause(Duration.ofSeconds(1))
// 按住鼠标不松开
.clickAndHold()
// 按照偏移量移动
.moveByOffset(0, -500)
// 松开鼠标
.release()
// 展示
.perform();
Thread.sleep(3000);
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.chrome");
device.setCapability("appActivity", "com.google.android.apps.chrome.Main");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
// 隐式等待十秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
// 初始化软件的初步设置
driver.findElement(By.id("com.android.chrome:id/terms_accept")).click();
driver.findElement(By.id("com.android.chrome:id/button_primary")).click();
}
@AfterClass
public void afterClass() {
if (driver != null) driver.quit();
}
}
多点操作与复杂操作
多点操作一般是在 IOS系统上用到的比较多
相关文章:https://appiumpro.com/editions/30-ios-specific-touch-action-methods
复杂操作看文章:https://appiumpro.com/editions/29-automating-complex-gestures-with-the-w3c-actions-api
这两个地址来自于源代码;io.appium.java_client.MultiTouchAction
常用API
内部跳转与外部跳转
App的一个页面跳到另一个页面,一个App跳转到另一个App
在 Chrome浏览器
中跳转到 设置
,代码如下
import io.appium.java_client.android.Activity;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class TestActivity {
protected static AndroidDriver driver = null;
@Test
public void run() throws InterruptedException {
// 第一个参数是appPackage,第二个参数是appActivity
Activity activity = new Activity("com.android.settings", ".Settings");
driver.startActivity(activity);
// 等待3秒,为了让效果看起来更明显
Thread.sleep(3000);
}
@BeforeClass
public void beforeClass() throws MalformedURLException {
DesiredCapabilities device = new DesiredCapabilities();
device.setCapability("deviceName", "mahe666_test");
device.setCapability("automationName", "UiAutomator2");
device.setCapability("platformName", "Android");
device.setCapability("platformVersion", "9");
device.setCapability("appPackage", "com.android.chrome");
device.setCapability("appActivity", "com.google.android.apps.chrome.Main");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/"), device);
// 隐式等待十秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
// 初始化软件的初步设置
driver.findElement(By.id("com.android.chrome:id/terms_accept")).click();
driver.findElement(By.id("com.android.chrome:id/button_primary")).click();
}
@AfterClass
public void afterClass(){
if (driver != null) driver.quit();
}
}
获取页面dom元素
// 返回的是整个页面的dom结构,以字符串的形式展示
String str = driver.getPageSource();
获取当前页面类名
// 获取
String str = driver.currentActivity();
对页面进行截图
需要Hutool依赖
File screenshot = driver.getScreenshotAs(OutputType.FILE);
FileUtil.copyFile(screenshot, new File("/test.png"));
获取当前系统时间
String deviceTime = driver.getDeviceTime();
获取设备的DPI
Long displayDensity = driver.getDisplayDensity();
获取设备的横竖屏状态
PORTRAIT
是竖屏,LANDSCAPE
是横屏
ScreenOrientation orientation = driver.getOrientation();