appium初识

1、环境安装

jdk11+nodejs+android studio+appium desktop

image

2、环境检查

image

3、启动参数相关信息查询

启动代码demo:

image

4、appium版本

1)1.19版本以下,点击AppiumDesktop的放大镜按钮,右上角第一个放大镜按钮,进入client配置页面,即 Appium Inspctor;
2)1.20版本以上,直接打开Appium Inspctor;

5、等待

代码示例:
1)强制等待(常用于调试代码用):

2)隐式等待(作用整个用例,通常只在BeforeAll中添加一次即可):
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

3)显示等待(隐式等待只确认元素是否出现,但不确认js是否可操作,显示等待弥补了这一缺陷):
WebElement el2 = new WebDriverWait(driver,Duration.ofSeconds(10))
.until(ExpectedConditions.elementToBeClickable(
AppiumBy.id(“com.xueqiu.android:id/home_search”)
));
4)流等待(在设定时间内,每x秒点击一次,直到得到预期结果,可忽略已识别的错误)
FluentWait wait = new FluentWait(driver)
//设置等待评估条件为真的时间 —超时值
.withTimeout(Duration.ofSeconds(10))
//设置评估条件的频率 —轮询频率
.pollingEvery(Duration.ofSeconds(3))
.ignoring(NoSuchElementException.class);
//流等待应用
WebElement element = (WebElement) wait.until(new Function<AndroidDriver,WebElement>() {
@Override
public WebElement apply(AndroidDriver androidDriver) {
WebElement element1 = driver.findElement(AppiumBy.id(“com.xueqiu.android:id/home_search”));
return element1;
}
});

6、IDEA中maven项目创建

1)添加pom依赖

image

2)使用录制脚本,并进行优化,优化点如下:
a.优化 capability 信息,去掉Capability设置中的Appium信息;
b.返回app首页用物理返回键,回键直接用 driver.manage.back;
c.添加隐式等待,driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
d.添加noReset属性保留历史数据,在Capabilities中添加设置信息,desiredCapabilities.setCapability(“noReset”, true);
e.driver退出之前断言,

3)app启动的两种方式
方式一:driver = new AndroidDriver(new URL(“url”), caps);
方式二:driver.execute(LAUNCH_APP)

4)实践代码如下:
package com.appium;

import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import static io.appium.java_client.MobileCommand.LAUNCH_APP;
import static java.lang.Thread.sleep;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class SampleTest {
private static AndroidDriver driver;

@BeforeAll
public static void setUp() throws MalformedURLException {
    DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
    //a.优化 capability 信息,去掉Capability设置中的Appium信息
    desiredCapabilities.setCapability("platformName", "Android");
    desiredCapabilities.setCapability("platformVersion", "6.0");
    desiredCapabilities.setCapability("deviceName", "127.0.0.1:7555");
    desiredCapabilities.setCapability("automationName", "UiAutomator2");
    desiredCapabilities.setCapability("appActivity", ".MainActivity");
    desiredCapabilities.setCapability("appPackage", "io.cloudgrey.the_app");
    desiredCapabilities.setCapability("ensureWebviewsHavePages", true);
    desiredCapabilities.setCapability("nativeWebScreenshot", true);
    desiredCapabilities.setCapability("newCommandTimeout", 3600);
    desiredCapabilities.setCapability("connectHardwareKeyboard", true);
    //d.添加noReset属性保留历史数据,在Capabilities中添加设置信息,desiredCapabilities.setCapability("noReset", true);
    desiredCapabilities.setCapability("noReset",true);

    URL remoteUrl = new URL("http://127.0.0.1:4723/wd/hub");

    driver = new AndroidDriver(remoteUrl, desiredCapabilities);
    //c.添加隐式等待,driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}

@Test
public void sampleTest() throws InterruptedException {
    WebElement el1 = (WebElement) driver.findElement(By.xpath("//android.view.ViewGroup[@content-desc='Echo Box']/android.widget.TextView[1]"));
    el1.click();
    WebElement el2 = (WebElement) driver.findElement(By.xpath("//android.widget.EditText[@content-desc='messageInput']"));
    el2.sendKeys("Hello World !");
    WebElement el3 = (WebElement) driver.findElement(By.xpath("//android.view.ViewGroup[@content-desc='messageSaveBtn']/android.widget.TextView"));
    el3.click();
    //b.返回app首页用物理返回键,回键直接用 driver.manage.back;
    driver.navigate().back();
    System.out.println("退出这个app");
    //强制等待10s
    sleep(1000);
    //热启动,打开app退出时的页面
    driver.execute(LAUNCH_APP);
    WebElement element = driver.findElement(AppiumBy.xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup"));
    String text = element.getText();
    //添加断言
    assertEquals("The App",text,"对应页面没有返回");
    System.out.println("text:"+text);
}

@AfterAll
public static void tearDown() {
    driver.quit();
}

}

7、常见控制交互方法:

8、获取中心点坐标示例:

    //获取中心点坐标
    //原理: 中心点X = 起始点+ 1/2宽;中心点Y = 起始点+ 1/2高
    int startX = location.getX();
    int startY = location.getY();
    int midX = size.width;
    int midY = size.height;
    System.out.println("中心点x:"+(startX+midX/2));
    System.out.println("中心点y:"+(startY+midY/2));