上一节我们简单介绍了使用Appium来测试native程序,而对于hybrid程序,因为里面的按钮、输入框等都位于webviewer控件中,所以我们的测试脚本会有些不一样。
根据官方文档显示,Appium使用以下的第三方框架:
Android 4.4+: Google’s UiAutomator
Android 2.3+: Google’s Instrumentation. (Instrumentation由单独的项目Selendroid提供支持 )
在4.4以上(包含4.4)可以使用UiAutomator,此时注意开启webview的一个选项:
webView.setWebContentsDebuggingEnabled(true);
这里我统一使用selendroid,使用selendroid有以下几个注意事项:
1.DesiredCapabilities需要设置“automationName”为“Selendroid”
capabilities.setCapability("automationName","Selendroid");
Selendroid在控件查找方面可以使用cssSelector,UiAutomator就不行,如果使用UiAutomator就只能通过控件类型以及上面的文本来进行查找了,另外在最开始查找控件之前,先Sleep一段时间,否则因为画面没有渲染完,导致找不到控件如:
Thread.sleep(2000);
driver.findElementsByClassName("android.widget.Button").get(0).click();
driver.findElementByXPath("//android.view.View[contains(@content-desc,'确定')]").click();
2.DesiredCapabilities需要设置“app”,否则会提示权限不足 。
File classpathRoot = new File(System.getProperty("user.dir"));
File appDir = new File(classpathRoot, "apps");
File app = new File(appDir, "Appium_TestApp.apk");
capabilities.setCapability("app", app.getAbsolutePath());
3.输入字符不支持unicode,对于中文字符使用下面的方法进行输入:
JavascriptExecutor jse = (JavascriptExecutor) driver;
jse.executeScript("document.getElementById('title').value='软件工程'");
完整测试脚本如下:
package com.digiwin.mobile.appium;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.URL;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;
public class hybrid_seledroid {
private AndroidDriver<?> driver;
@SuppressWarnings("rawtypes")
@Before
public void setUp() throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("automationName","Selendroid");
capabilities.setCapability("platformName", "Android");
File classpathRoot = new File(System.getProperty("user.dir"));
File appDir = new File(classpathRoot, "apps");
File app = new File(appDir, "Appium_TestApp.apk");
capabilities.setCapability("app", app.getAbsolutePath());
capabilities.setCapability("appPackage", "com.example.appium_testapp");
capabilities.setCapability("appActivity", ".MainActivity");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
}
@Test
public void webview() throws InterruptedException {
Set<String> contexts = driver.getContextHandles();
for (String contextName : contexts) {
System.out.println(contextName);
if (contextName.contains("WEBVIEW")){
driver.context(contextName);
}
}
Thread.sleep(2000);
//新增测试
int bookNum = driver.findElementsByCssSelector("ion-item").size();//当前书籍数
driver.findElement(By.cssSelector(".ion-ios-plus-outline")).click();//新增
Thread.sleep(1000);
driver.findElement(By.cssSelector("#title")).sendKeys("AAA");
driver.findElement(By.cssSelector("#author")).sendKeys("Clark");
driver.findElement(By.cssSelector("#press")).sendKeys("BBBB");
driver.findElement(By.cssSelector("#edition")).sendKeys("CCC");
driver.findElements(By.cssSelector("input")).get(4).sendKeys("ISBN 7-302-1212-6/PQ·3633");
driver.findElement(By.cssSelector(".button-positive")).click();//保存
Thread.sleep(1000);
driver.findElement(By.cssSelector("button.ng-binding")).click();//点击确定按钮
Thread.sleep(10000);
System.out.println("当钱书籍个数:"+driver.findElementsByCssSelector("ion-item").size());
assertEquals(++bookNum,driver.findElementsByCssSelector("ion-item").size());
//修改测试
driver.findElementsByCssSelector("ion-item").get(0).click();
Thread.sleep(1000);
driver.findElement(By.cssSelector("#author")).clear();
driver.findElement(By.cssSelector("#author")).sendKeys("Test");
driver.findElement(By.cssSelector(".button-positive")).click();//保存
Thread.sleep(1000);
driver.findElement(By.cssSelector("button.ng-binding")).click();//点击确定按钮
Thread.sleep(1000);
driver.findElementsByCssSelector("ion-item").get(0).click();
assertEquals(driver.findElement(By.cssSelector("#author")).getAttribute("value"),"Test");
driver.findElementByCssSelector(".ion-chevron-left").click();
Thread.sleep(1000);
// 删除测试
driver.findElement(By.cssSelector(".ion-ios-minus-outline")).click();//点击删除按钮
Thread.sleep(1000);
int lastIndex = driver.findElements(By.cssSelector("ion-delete-button")).size()-1;
driver.findElements(By.cssSelector("ion-delete-button")).get(lastIndex).click();
Thread.sleep(1000);
driver.findElement(By.cssSelector(".ion-ios-minus-outline")).click();//再次点击删除按钮,返回正常状态
assertEquals(--bookNum,driver.findElementsByCssSelector("ion-item").size());
Thread.sleep(10000);
}
@After
public void tearDown() throws Exception {
driver.quit();
}
}