Appium [Share] 使用 appium1.0 与 Java 进行自动化的例子

思寒_seveniruby · 2014年05月17日 · 最后由 pepper 回复于 2016年12月04日 · 5046 次阅读
本帖已被设为精华帖!

这个视频是面向小白的一个小教程.
用一个小例子带还不懂的小白同学入门, 高手请忽略.

appium 1.x 改进

http://testerhome.com/topics/809
最大的变化是使用了自己的封装库. 这个封装库继承自 WebDriver, 并进行了扩展和重载.
所以除了要下载 Selenium Java 库外, 还需要下载 Appium 的 Java Client 库

Java Binding

下载 Selenium Java 客户端库
下载 Appium 的 Java Client 库.
把库添加到项目的依赖中

Android 与 Uiautomator

Appium 在 Android4.2 及以上用的是 Uiautomator.
4.2 以下用的是 Selendroid 体系. 基于插桩, 类似 Robotium 的一个框架.

我目前使用的是一个 android4.2 版本的手机, ZTE 中兴.

代码

代码很简单, 只是演示, 所以没有加验证语句. 更多例子以后也会放出视频给大家.

package com.testerhome.appium.example;

import io.appium.java_client.AppiumDriver;

import java.net.URL;
import java.util.concurrent.TimeUnit;

import org.junit.*;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.*;

public class AppiumExample {
    private AppiumDriver driver;

    @Before
    public void setUp() throws Exception {
        //配置webdriver
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
        capabilities.setCapability("platformName", "Android");
        capabilities.setCapability("deviceName","ZTE");
        capabilities.setCapability("platformVersion", "4.2");
        capabilities.setCapability("appPackage", "com.taobao.taobao");
        capabilities.setCapability("appActivity", "com.taobao.tao.homepage.MainActivity3");
        //appium的独特地方,使用自己的AppiumDriver, 它本身是继承自WebDriver
        driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
        //设置超时
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }

    @After
    public void tearDown() throws Exception {
        driver.quit();
    }

    @Test
    public void taobao_search() throws InterruptedException{
        //找输入框并点击
        WebElement text = driver.findElementByClassName("android.widget.EditText");
        text.click();
        //输入要搜索的内容
        text.sendKeys("xiaomi3");
        //找搜索按钮并点击
        WebElement search = driver.findElementByAndroidUIAutomator("new UiSelector().className(\"android.widget.Button\").text(\"搜索\")");        
        search.click();
    }
}

运行视频

本视频稍后上传到网上
跪了, 没录制上声音.
视频地址

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 35 条回复 时间 点赞

很赞啊,上传好后我给加到专辑里

#1 楼 @oscarxie 我今天打算重新录制一边, 没声音毕竟不太好理解.

下载 Selenium Java 客户端库
下载 Appium 的 Java Client 库.
这 2 个在哪里下载

#3 楼 @young 小白很多、同样疑问?

#3 楼 @young @xianjin http://testerhome.com/topics/809 在官方的迁移文档里面已经给了地址. 找不到就尝试 google 下. 应该可以找到.

#5 楼 @seveniruby @young @xianjin
http://yun.baidu.com/s/1i3vDi5J 这是我之前提出来的包,可以用的。

#6 楼 @benlooking 赞. 利国利民.

@seveniruby @benlooking 用 maven 可以解决 jar 包依赖

org.seleniumhq.selenium
selenium-java
LATEST
test


io.appium
java-client
1.1.0

#8 楼 @tspring 我推荐用 Maven 或者 gradle 管理依赖和编译. 只是目前很多新手估计对这个还不了解.

#8 楼 @tspring
是的,使用 maven 管理第三方 jar 包/库很省事。
我也提供一个我自己能跑的 java 代码,使用的是 testng,appium 1.0,很简单的。
重构一下,更好。

package com.xx;

import org.openqa.selenium.Alert;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.TouchAction;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.Test;


public class Demo {

    private AppiumDriver driver;

  @Test
  public void f() throws InterruptedException {
      WebElement ctn = driver.findElementByName("Continue");
      TouchAction action = new TouchAction(driver);

      action.press(ctn).perform();
      Thread.sleep(3);            // sleep for debugging

      int X = driver.manage().window().getSize().getWidth();
      int Y = driver.manage().window().getSize().getHeight();

      int sX = (int) (X * 0.9);
      int sY = (int) (Y * 0.5);
      int eX = (int) (X * 0.05);
      int eY = sY;
      int duration = 2000;
      driver.swipe(sX, sY, eX, eY, duration);      //swipe function is broken in iOS 7.x simulator by Apple
       Thread.sleep(3000);      // sleep for debugging
  }

  @BeforeMethod
  public void setUp() throws Exception {
      // set up appium    
      File appDir = new File("/app/Testing_App");
      File app = new File(appDir, "xxx.app");
      DesiredCapabilities capabilities = new DesiredCapabilities();
      capabilities.setCapability(CapabilityType.BROWSER_NAME, "iOS");
      capabilities.setCapability("device", "iOS");
      capabilities.setCapability(CapabilityType.VERSION, "7.1");
      capabilities.setCapability(CapabilityType.PLATFORM, "Mac");
      capabilities.setCapability("app", app.getAbsolutePath());
      driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);

  }

  @AfterMethod
  public void teardown() {
      driver.quit();
  }



}

已经附上视频连接. 没有声音, 大家将就下吧, 以后有时间再补声音, 或者重做

有没有 python 的呀?

@532589730 WebElement ctn = driver.findElementByName("Continue");,你直接用这个查找元素,如果这个元素需要等待,你怎么处理?

#14 楼 @tspring 设置 timeout 或者循环短等待

你好,我在 mac 上,想跑下 appium 的 sample code
但是一直报 Error: Device android not configured yet
info: Error: Device android not configured yet,
我不知道哪里出的问题.能不能帮我看下
我安装的是 appium1.0
appium log:debug: Appium request initiated at /wd/hub/session
debug: Request received with params: {"desiredCapabilities":{"platformVersion":"4.2","app":"/Users/build/appium/sample-code/examples/java/junit/../../../apps/ContactManager/ContactManager.apk","platformName":"Android","deviceName":"GT-P5113","browserName":"","app-package":"com.example.android.contactmanager","app-activity":".ContactManager"}}
error: Trying to run a session for device 'android' but that device hasn't been configured. Run config
info: Got configuration error, not starting session
info: Cleaning up appium session
error: Failed to start an Appium session, err was: Error: Device android not configured yet
info: Error: Device android not configured yet
at Appium.configure (/usr/local/lib/node_modules/appium/lib/appium.js:264:15)
at Appium.start (/usr/local/lib/node_modules/appium/lib/appium.js:102:10)
at exports.createSession (/usr/local/lib/node_modules/appium/lib/server/controller.js:155:16)
at callbacks (/usr/local/lib/node_modules/appium/node_modules/express/lib/router/index.js:164:37)
at param (/usr/local/lib/node_modules/appium/node_modules/express/lib/router/index.js:138:11)
at pass (/usr/local/lib/node_modules/appium/node_modules/express/lib/router/index.js:145:5)
at nextRoute (/usr/local/lib/node_modules/appium/node_modules/express/lib/router/index.js💯7)
at callbacks (/usr/local/lib/node_modules/appium/node_modules/express/lib/router/index.js:167:11)
at /usr/local/lib/node_modules/appium/lib/server/controller.js:41:7
at callbacks (/usr/local/lib/node_modules/appium/node_modules/express/lib/router/index.js:164:37)
info: Responding to client with error: {"status":33,"value":{"message":"A new session could not be created. (Original error: Device android not configured yet)","origValue":"Device android not configured yet"},"sessionId":null}
POST /wd/hub/session 500 1ms - 216b

这是跑 mvn 的 log:
admins-MacBook-Pro:junit build$ mvn -Dtest=com.saucelabs.appium.AndroidContactsTest test
[INFO] Scanning for projects...
[WARNING]
[WARNING] Some problems were encountered while building the effective model for com.saucelabs:sauce_appium_junit:jar:0.0.1-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 60, column 12
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-surefire-plugin is missing. @ line 56, column 12
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]

[INFO] ------------------------------------------------------------------------
[INFO] Building sauce_appium_junit 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ sauce_appium_junit ---
[debug] execute contextualize
[WARNING] Using platform encoding (EUC_CN actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/build/appium/sample-code/examples/java/junit/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ sauce_appium_junit ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ sauce_appium_junit ---
[debug] execute contextualize
[WARNING] Using platform encoding (EUC_CN actually) to copy filtered resources, i.e. build is platform dependent!

这是 test case code:

package com.saucelabs.appium;

import io.appium.java_client.AppiumDriver;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.io.File;
import java.net.URL;
import java.util.List;

public class AndroidContactsTest {
private AppiumDriver driver;

@Before
public void setUp() throws Exception {
// set up appium
File classpathRoot = new File(System.getProperty("user.dir"));
File appDir = new File(classpathRoot, "../../../apps/ContactManager");
File app = new File(appDir, "ContactManager.apk");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName","GT-P5113");
capabilities.setCapability("platformVersion", "4.2");
capabilities.setCapability("app", app.getAbsolutePath());
capabilities.setCapability("app-package", "com.example.android.contactmanager");
capabilities.setCapability("app-activity", ".ContactManager");
driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}

@After
public void tearDown() throws Exception {
driver.quit();
}

@Test
public void addContact(){
WebElement el = driver.findElement(By.name("Add Contact"));
el.click();
//List textFieldsList = driver.findElementsByClassName("android.widget.EditText");
//textFieldsList.get(0).sendKeys("Some Name");
//textFieldsList.get(2).sendKeys("Some@example.com");
//driver.swipe(100, 500, 100, 100, 2);
//driver.findElementByName("Save").click();
}

}

大神,能帮我分析一下错误的原因吗,小白的我真是毫无办法。求助。

ERROR: debug: Appium request initiated at /wd/hub/session
info: Didn't get app but did get Android package, will attempt to launch it on the device
ERROR: debug: Request received with params: {"desiredCapabilities":{"platformVersion":"4.4","platformName":"Android","deviceName":"android","browserName":"","appActivity":"com.taobao.tao.homepage.MainActivity3","appPackage":"com.taobao.taobao"}}
info: Creating new appium session 5eedf0ca-ec99-4281-99ac-7c5b266376e1
ERROR: debug: Using fast reset? true
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" devices
info: Starting android appium
info: Preparing device for session
info: Not checking whether app is present since we are assuming it's already on the device
info: Checking whether adb is present
info: [ADB] Using adb from D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe
info: Trying to find a connected android device
info: [ADB] Getting connected devices...
info: [ADB] 1 device(s) connected
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 wait-for-device
info: Setting device id to emulator-5554
info: [ADB] Waiting for device to be ready and to respond to shell commands (timeout = 5)
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "echo 'ready'"
info: Starting logcat capture
info: Getting device API level
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "getprop ro.build.version.sdk"
info: Device is at API Level 19
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "rm -rf /data/local/tmp/strings.json"
ERROR: debug: Not uninstalling app since server not started with --full-reset
info: Skipping install since we launched with a package instead of an app path
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 forward tcp:4724 tcp:4724
ERROR: debug: Pushing appium bootstrap to device...
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 push "D:\Appium1.0.0.3\node_modules\appium\build\android_bootstrap\AppiumBootstrap.jar" /data/local/tmp/
ERROR: debug: Pushing unlock helper app to device...
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 install "D:\Appium1.0.0.3\node_modules\appium\build\unlock_apk\unlock_apk-debug.apk"
info: Attempting to kill all 'uiautomator' processes
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "ps 'uiautomator'"
info: Getting all processes with 'uiautomator'
info: No matching processes found
ERROR: debug: spawning: D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe -s emulator-5554 shell uiautomator runtest AppiumBootstrap.jar -c io.appium.android.bootstrap.Bootstrap
info: Running bootstrap
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: numtests=1
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: stream=
info: [UIAUTOMATOR STDOUT] io.appium.android.bootstrap.Bootstrap:
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: id=UiAutomatorTestRunner
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: test=testRunServer
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: class=io.appium.android.bootstrap.Bootstrap
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS: current=1
info: [UIAUTOMATOR STDOUT] INSTRUMENTATION_STATUS_CODE: 1
info: [BOOTSTRAP] [info] Socket opened on port 4724
info: [BOOTSTRAP] [info] Appium Socket Server Ready
ERROR: debug: Waking up device if it's not alive
info: [BOOTSTRAP] [info] Loading json...
info: Pushing command to appium work queue: ["wake",{}]
info: [BOOTSTRAP] [info] Registered crash watchers.
info: [BOOTSTRAP] [info] Client connected
info: [BOOTSTRAP] [info] Got data from client: {"cmd":"action","action":"wake","params":{}}
info: [BOOTSTRAP] [info] Got command of type ACTION
info: [BOOTSTRAP] [debug] Got command action: wake
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "dumpsys window"
info: [BOOTSTRAP] [info] Returning result: {"value":true,"status":0}
info: Writing dumpsys output to D:\Appium1.0.0.3\node_modules\appium.dumpsys.log
ERROR: debug: Screen already unlocked, continuing.
info: Pushing command to appium work queue: ["getDataDir",{}]
info: [BOOTSTRAP] [info] Got data from client: {"cmd":"action","action":"getDataDir","params":{}}
info: [BOOTSTRAP] [info] Got command of type ACTION
info: [BOOTSTRAP] [debug] Got command action: getDataDir
ERROR: debug: dataDir set to: /data
info: [BOOTSTRAP] [info] Returning result: {"value":"\/data","status":0}
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n com.taobao.taobao/com.taobao.tao.homepage.MainActivity3"
ERROR: debug: executing: "D:\tools\adt-bundle-windows-x86_64-20131030\sdk\platform-tools\adb.exe" -s emulator-5554 shell "am start -S -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000 -n com.taobao.taobao/.com.taobao.tao.homepage.MainActivity3"

#17 楼 @zwdlp520 里面已经说了, 是 app 的配置有问题, 你得检查下

#18 楼 @seveniruby 现在运行的时候还是会有很多错误,但脚本能正常执行...无解。

感谢分享,英语不好的有福了。

#14 楼 @tspring
我会使用 while 循环去判断了,附加一个间隔时间,设一个等待时间。

一般我会加一个 app 是否成功开启的一个方法,先来一个确定。
如果连 app 都没有成功打开,谈何测试。

@seveniruby 请问一下 Selenium 是不是只能用 java 和 maven 才能做?

楼主你好,
capabilities.setCapability("appPackage", "com.taobao.taobao");
capabilities.setCapability("appActivity", "com.taobao.tao.homepage.MainActivity3");
像这个 com.taobao.taobao,com.taobao.tao.homepage.MainActivity3,我要是测试其它的 app 怎么写啊?

这个 appium 可以进行安卓的 web 测试吗?

#23 楼 @happyjiejie 换其他 App 的 appPackage 和 appActivity

#24 楼 @happyjiejie 可以,Appium 支持原生,混合和 Web 三种类型的 App

#22 楼 @mingyuwang 请搜索 Selenium,Selenium 支持 Python,Ruby,Java,C#

#27 楼 @xiaomayi0323 你好,我以前是做 PC 端的 web 测试的用的是 selenium,前段时间的时候 selenium 还可以启动起来安装的默认浏览器,但 API 更新以后就那以前的那个启动安卓默认浏览器的方法给删除了,你有什么方法吗?给写个 dome,谢谢啦。

有没有 Appium JAVA ios 的例子提供给小白?

楼主,如果 Appium 的 Java Client 库升级到 2.0 的话,AppiumDriver 这个类变成了抽象函数,要改用 AndroidDriver

#31 楼 @sunrise 说得很对,我之前也是用的 AppiumDriver 类结果没有 “findElementByAndroidUIAutomator” 这个方法。

#32 楼 @hiahia 估计是为了架构, 让两个 driver 继承自公共特性的 appiumdriver

楼主,我按照你贴出来的步骤跟脚本执行了下,但是一直报下面这个错
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jdt/internal/junit/runner/RemoteTestRunner
Caused by: java.lang.ClassNotFoundException: org.eclipse.jdt.internal.junit.runner.RemoteTestRunner
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
只要在项目里加上 java-client-1.2.1.jar、selenium-java-2.44.0.zip、selenium-server-standalone-2.44.0.jar 这三个包,就会报错,单独运行简单的 junit 脚本是没问题,请问您知道问题的原因么~

之前也是用的 AppiumDriver 类结果没有 “findElementByAndroidUIAutomator” 这个方法

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册