使用Appium测试Android

使用Appium测试Android

本文介绍了使用Appium测试Android Webview的各种问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个混合应用程序,主要只是一个webview.这是基本测试的代码:

  @BeforeClass
  public static void setupAppium() throws MalformedURLException {
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("appium-version", "1.5.3");
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("platformVersion", "6.0");
    capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "AppiumTesterDevice");
    capabilities.setCapability("app", "/work/builds/unify/app/build/outputs/apk/app-debug.apk");
    capabilities.setCapability("appPackage", "com.company.unify");
    capabilities.setCapability("appActivity", "AdministerActivity");
    driver = new AndroidDriver<>(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);
  }

  @Test
  public void CompanyUrlTest() {
    driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.EditText[1]")).clear();
    driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.EditText[1]")).sendKeys(companyserverUrl);
    driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[3]/android.widget.Button[2]")).click();
  }

  @Test
  public void SimpleTest() {
    driver.context("WEBVIEW_com.company.unify");
    WebDriverWait wait = new WebDriverWait(driver,20);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".localPickerList")));
    driver.findElementByCssSelector(".localePickerList").click();
    driver.findElementByCssSelector(".SPANISH_PR").click();
  }

第一个测试工作正常,因为它只能在普通的android应用上运行,没有webview.因此,只需更改文本字段中的URL并按一个按钮即可将我们转到Web视图中的URL.

第二个测试是哪里有问题,并且问题会根据android版本和chromedriver版本而变化.我已经完成了大量的谷歌搜索工作,只能得出结论说appium/selendroid/chromedriver存在一系列无休止的错误.

我从 https://sites.google.com下载了最新的Chromedriver. /a/chromium.org/chromedriver/downloads .在我的appium设置中,我设置了chromedriver路径来指向此位置.在我的Android 6.0中,此版本的ChromeDriver出现此错误:

org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Can't stop process; it's not currently running (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 224 milliseconds
Build info: version: 'unknown', revision: '1969d75', time: '2016-10-18 09:43:45 -0700'
System info: host: 'company-me-m', ip: '192.168.1.154', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.4', java.version: '1.8.0_45'
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities [{app=/work/builds/unify/app/build/outputs/apk/app-debug.apk, appPackage=com.company.unify, networkConnectionEnabled=true, warnings={}, databaseEnabled=false, deviceName=emulator-5554, platform=LINUX, deviceUDID=emulator-5554, appActivity=AdministerActivity, desired={app=/work/builds/unify/app/build/outputs/apk/app-debug.apk, appPackage=com.comany.unify, appActivity=AdministerActivity, appium-version=1.5.3, platformVersion=6.0, automationName=Appium, platformName=Android, deviceName=AppiumTesterDevice}, appium-version=1.5.3, platformVersion=6.0, webStorageEnabled=false, locationContextEnabled=false, automationName=Appium, takesScreenshot=true, javascriptEnabled=true, platformName=Android}]
Session ID: bc7100bd-2498-47d2-b0f2-3b29602c8e0d

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:635)
    at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:40)
    at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
    at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
    at io.appium.java_client.AppiumDriver.context(AppiumDriver.java:557)
    at com.comapny.UnifyAppiumJunit.BasicTest.SimpleTest(BasicTest.java:57)

在appium选项中未设置此版本的Chromedriver时,出现另一个错误(但是,当我不指定它时,我不知道它使用的是chromedriver可执行文件).这是该错误:

Jan 27, 2017 3:02:39 PM org.openqa.selenium.support.ui.ExpectedConditions findElement
WARNING: WebDriverException thrown by findElement(By.cssSelector: .localPickerList)
org.openqa.selenium.NoSuchSessionException: no such session

在这两种情况下,似乎都没有加载我的Web视图.当应用加载Web视图时,代码仍然会运行,这似乎很糟糕.为什么等待"似乎没有做任何事情?这有关系吗?

最后,如果我使用Android 5.1.1模拟器,则会出现此错误:

WebDriverException thrown by findElement org.openqa.selenium.WebDriverException: unknown error: Maximum call stack size exceeded

有什么想法吗?为此,我整天都在反对Google.

解决方案

有了新的UIautomator,您无需将驱动程序切换到Webview.它具有识别webView内部元素的内置功能.

请一次更新您的Android SDK.

WebView内的元素将在UIAutomator(适用于Android 6.0及更高版本)中可见.但是,一旦为Android 6.0+设备自动执行脚本,就可以为6.0以下的Android版本使用相同的脚本.

您还可以使用UIAutomator在Android 6.0+设备上查看webView内的元素.

有关更多信息,请参见此链接

I have a hybrid app that is primarily just a webview. Here is the code for the basic test:

  @BeforeClass
  public static void setupAppium() throws MalformedURLException {
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("appium-version", "1.5.3");
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("platformVersion", "6.0");
    capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "AppiumTesterDevice");
    capabilities.setCapability("app", "/work/builds/unify/app/build/outputs/apk/app-debug.apk");
    capabilities.setCapability("appPackage", "com.company.unify");
    capabilities.setCapability("appActivity", "AdministerActivity");
    driver = new AndroidDriver<>(new URL("http://0.0.0.0:4723/wd/hub"), capabilities);
  }

  @Test
  public void CompanyUrlTest() {
    driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.EditText[1]")).clear();
    driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.EditText[1]")).sendKeys(companyserverUrl);
    driver.findElement(By.xpath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[3]/android.widget.Button[2]")).click();
  }

  @Test
  public void SimpleTest() {
    driver.context("WEBVIEW_com.company.unify");
    WebDriverWait wait = new WebDriverWait(driver,20);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".localPickerList")));
    driver.findElementByCssSelector(".localePickerList").click();
    driver.findElementByCssSelector(".SPANISH_PR").click();
  }

The first test works fine because it's just operating on normal android app, no webview. So its just changing the URL in a text field and pressing a button to take us to that URL in the webview.

The second test is where there are problems, and the problems change depending on android version and chromedriver version. I've done tons of googling and can only conclude there is an endless series of bugs with appium/selendroid/chromedriver.

I downloaded the latest Chromedriver from https://sites.google.com/a/chromium.org/chromedriver/downloads. And in my appium settings, I have set the chromedriver path to point at this. In my Android 6.0 I get this error with this version of ChromeDriver:

org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Can't stop process; it's not currently running (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 224 milliseconds
Build info: version: 'unknown', revision: '1969d75', time: '2016-10-18 09:43:45 -0700'
System info: host: 'company-me-m', ip: '192.168.1.154', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11.4', java.version: '1.8.0_45'
Driver info: io.appium.java_client.android.AndroidDriver
Capabilities [{app=/work/builds/unify/app/build/outputs/apk/app-debug.apk, appPackage=com.company.unify, networkConnectionEnabled=true, warnings={}, databaseEnabled=false, deviceName=emulator-5554, platform=LINUX, deviceUDID=emulator-5554, appActivity=AdministerActivity, desired={app=/work/builds/unify/app/build/outputs/apk/app-debug.apk, appPackage=com.comany.unify, appActivity=AdministerActivity, appium-version=1.5.3, platformVersion=6.0, automationName=Appium, platformName=Android, deviceName=AppiumTesterDevice}, appium-version=1.5.3, platformVersion=6.0, webStorageEnabled=false, locationContextEnabled=false, automationName=Appium, takesScreenshot=true, javascriptEnabled=true, platformName=Android}]
Session ID: bc7100bd-2498-47d2-b0f2-3b29602c8e0d

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:635)
    at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:40)
    at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
    at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
    at io.appium.java_client.AppiumDriver.context(AppiumDriver.java:557)
    at com.comapny.UnifyAppiumJunit.BasicTest.SimpleTest(BasicTest.java:57)

Without this version of Chromedriver set in appium options, I get a different error (I don't however, know what chromedriver executable its using when I'm not specifying it). Here is that error:

Jan 27, 2017 3:02:39 PM org.openqa.selenium.support.ui.ExpectedConditions findElement
WARNING: WebDriverException thrown by findElement(By.cssSelector: .localPickerList)
org.openqa.selenium.NoSuchSessionException: no such session

It seems like it's not even letting my webview load in both cases. While the app is loading the webview, the code runs anyway, which seems bad. Why isn't the Wait seemingly doing anything? Does this even matter?

Finally, if I use my Android 5.1.1 emulator, I get this error:

WebDriverException thrown by findElement org.openqa.selenium.WebDriverException: unknown error: Maximum call stack size exceeded

Any ideas? I've been banging my head against google all day over this.

解决方案

With new UIautomator you don't need to switch your driver to webview. It has built in capabilities to identify the elements inside webView.

Please update your Android SDK once.

Elements inside WebView will be visible in UIAutomator for Android Version 6.0+ versions. However, once you automate the script for Android 6.0+ device, you can use the same script for Android version below 6.0.

And also you can see the elements inside webView on Android 6.0+ devices using UIAutomator.

For more information refer this link

这篇关于使用Appium测试Android Webview的各种问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 16:17