一.用命令行做了一部分准备工作

二.环境准备好后,直接下载的 app dmg

1.首先去 Appium 官网上下载 appium.dmg。官网地址:http://appium.io/downloads.html
2.安装完成后运行监测

3.发现 android home 没配 强迫症要把环境配好

4.下载 android studio 它自己就把安卓 sdk 下载好了

5.找到 sdk 位置 在/etc/profile 中配置 android home

export ANDROID_HOME=/Users/gloria/Library/Android/sdk
export M2_HOME=/Users/gloria/jobs/apache-maven-3.3.9
export PATH=$PATH:$M2_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools

6.后再运行检测
提示 xcode 已经安装 但是自己没找到 又下了一个 xcode 4g...( 注意 8x 以上的 xcode, appium1.5.3 不支持 下 7x,踩了个坑)

再运行检测看起来没什么问题了。

三.下载官方 demo 编译

下载 appium 的测试例子:
git clone https://github.com/appium/sample-code

  1. 使用 terminal 命令行形式运行例子

a. 启动 appium;

b. 输入下面的命令编译生成示例程序:

cd sample-code/sample-code/apps/TestApp
xcodebuild -sdk iphonesimulator

c.目录下通过如下命令编译生成示例程序:xcodebuild -sdk iphonesimulator 当看到BUILD SUCCEEDED则说明编译成功。这行命令在 TestApp 项目底下创建了一个 build/Release-iphonesimulator 目录,并且声称一个可以透过 Appium 服务器交流的.app 封装包,该包为 appium gui 中 App Path 的路径。

d.直接执行启动

四.设置配置

配置如下

🚩 注意地址 型号和版本 错了会起不来报错

设置里修改部分配置

出图

上面按钮可定位 recode 可录制(但是录制的脚本基本跑不成 问题还挺多)

-------------此处 appium 的安装启动就完毕了--------------

--------下面是工程时间----------

1.步骤: New Project -- Maven -- 输入 Project name -- Project location -- Next -- Next
2.加入 pom 依赖

<dependencies>
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.seleniumhq.selenium</groupId>
          <artifactId>selenium-java</artifactId>
          <version>LATEST</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>io.appium</groupId>
          <artifactId>java-client</artifactId>
          <version>1.0.2</version>
      </dependency>
      <dependency>
          <groupId>com.googlecode.json-simple</groupId>
          <artifactId>json-simple</artifactId>
          <version>1.1</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>commons-lang</groupId>
          <artifactId>commons-lang</artifactId>
          <version>2.6</version>
          <scope>test</scope>
      </dependency>
      <!-- Includes the Sauce JUnit helper libraries -->
      <dependency>
          <groupId>com.saucelabs</groupId>
          <artifactId>sauce_junit</artifactId>
          <version>1.0.18</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>com.google.code.gson</groupId>
          <artifactId>gson</artifactId>
          <version>2.2.4</version>
      </dependency>
  </dependencies>

  <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-surefire-plugin</artifactId>
          </plugin>
          <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>1.5</source>
                  <target>1.5</target>
              </configuration>
          </plugin>
      </plugins>
  </build>

  <repositories>
      <repository>
          <id>saucelabs-repository</id>
          <url>https://repository-saucelabs.forge.cloudbees.com/release</url>
          <releases>
              <enabled>true</enabled>
          </releases>
          <snapshots>
              <enabled>true</enabled>
          </snapshots>
      </repository>
  </repositories>

配置好 ,建立新的文件 贴进代码

/**
 * Created by gloria on 17/1/22.
 */


import io.appium.java_client.AppiumDriver;


import io.appium.java_client.MobileElement;
import org.openqa.selenium.By;
import org.openqa.selenium.DeviceRotation;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;


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

public class apptest1 {
        public static void main(String[] args) throws MalformedURLException {
            WebDriver wd;
            DesiredCapabilities capabilities = new DesiredCapabilities();
            capabilities.setCapability("appium-version", "1.0");
            capabilities.setCapability("platformName", "iOS");
            capabilities.setCapability("platformVersion", "9.3");
            capabilities.setCapability("deviceName", "iPhone 6s Plus");
            capabilities.setCapability("app", "/Users/gloria/jobs/appiumtest/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app");
            wd = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities) {
                public void rotate(DeviceRotation deviceRotation) {

                }

                public DeviceRotation rotation() {
                    return null;
                }

                public MobileElement scrollTo(String s) {
                    return null;
                }

                public MobileElement scrollToExact(String s) {
                    return null;
                }
            };
            wd.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
            wd.findElement(By.name("TextField1")).sendKeys("4");
            wd.findElement(By.name("(null)")).sendKeys("5");
            wd.switchTo().alert().accept();
            wd.findElement(By.name("show alert")).click();
            wd.findElement(By.name("(null)")).click();
            wd.findElement(By.name("ComputeSumButton")).click();
            wd.findElement(By.name("locationStatus")).click();
           // wd.shake();
//            wd.findElement(By.name("DisabledButton")).click();
//            (JavascriptExecutor)wd.executeScript("mobile: swipe", new HashMap<String, Double>() {{
//                put("touchCount", (double) 1); put("startX", (double) 125);
//                put("startY", (double) 389); put("endX", (double) 283);
//                put("endY", 390); put("duration", 1.3539453125); }});
            wd.findElement(By.name("show alert")).click();
            wd.findElement(By.name("contact alert")).click();
            wd.close();
        }


}

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>2.42.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>2.2.0</version>
</dependency>

能正常启动模拟器了 但是启动后 还是没有正常跑 testcase

搜搜搜 更新 appium-client 3.2.0 解决

<dependency>
    <groupId>io.appium</groupId>
    <artifactId>java-client</artifactId>
    <version>3.2.0</version>
</dependency>

搜了半天 发现是 Appium1.5.0 的问题,于是,到 github 去搜了一下,果然,已经有人提交了 issue

npm install appium on windows not support driver.findElement(By.name("Add Contact"))

by.name 的方法在 1.5.0 中被移除了。。。移除了。。。移除。。了。。除。。了

搜搜搜 搜搜搜 增加两行 貌似解决了
capabilities.setCapability("appPackage", "com.company.AppName");
capabilities.setCapability("appActivity", "com.company.AppName.AppMainActivity");

此问题报错位置在 wd.close();代码释放的最后一行 (至少到了最后一行)

搜搜搜 搜搜搜 搜不着。。。- -!

至此 终于一个完整的小 case 可以跑过了。
最终的代码被注释掉大部分。没有打开 但是至少。。。跑通了

代码如下:


/**
 * Created by gloria on 17/1/22.
 */


import io.appium.java_client.AppiumDriver;


import io.appium.java_client.MobileElement;
import org.openqa.selenium.By;
import org.openqa.selenium.DeviceRotation;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;


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

public class apptest1 {
        public static void main(String[] args) throws MalformedURLException {
            WebDriver wd;
            DesiredCapabilities capabilities = new DesiredCapabilities();
            capabilities.setCapability("appium-version", "1.0");
            capabilities.setCapability("platformName", "iOS");
            capabilities.setCapability("platformVersion", "9.3");
            capabilities.setCapability("deviceName", "iPhone 6s Plus");
            capabilities.setCapability("appPackage", "com.company.AppName");
            capabilities.setCapability("appActivity", "com.company.AppName.AppMainActivity");
//            capabilities.setCapability("locationServicesAuthorized", true);
//            capabilities.setCapability("waitForAppScript", "$.delay(5000); $.acceptAlert(); true;");
            capabilities.setCapability("app", "/Users/gloria/jobs/appiumtest/sample-code/sample-code/apps/TestApp/build/release-iphonesimulator/TestApp.app");
            wd = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities) {
                public void rotate(DeviceRotation deviceRotation) {

                }

                public DeviceRotation rotation() {
                    return null;
                }

                public MobileElement scrollTo(String s) {
                    return null;
                }

                public MobileElement scrollToExact(String s) {
                    return null;
                }
            };
            wd.findElement(By.xpath("//UIAApplication[1]/UIAWindow[2]/UIAButton[2]\n")).click();

            wd.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

            wd.quit();
            //wd.findElement(By.xpath("//UIAApplication[1]/UIAWindow[2]/UIAButton[3]\n")).click();

//            wd.findElement(By.name("TextField1")).sendKeys("4");
//            wd.findElement(By.name("(null)")).sendKeys("5");
//            wd.switchTo().alert().accept();
//            wd.findElement(By.name("show alert")).click();
//            wd.findElement(By.name("(null)")).click();
//            wd.findElement(By.name("ComputeSumButton")).click();
//            wd.findElement(By.name("locationStatus")).click();
            //wd.shake();
//            wd.findElement(By.name("DisabledButton")).click();
//            (JavascriptExecutor)wd.executeScript("mobile: swipe", new HashMap<String, Double>() {{
//                put("touchCount", (double) 1); put("startX", (double) 125);
//                put("startY", (double) 389); put("endX", (double) 283);
//                put("endY", 390); put("duration", 1.3539453125); }});
//            wd.findElement(By.name("show alert")).click();
//            wd.findElement(By.name("contact alert")).click();


        }


}

班门弄斧了 写一个 mac+java+idea+iOS 的 能跑通的实践记录。。。。。

后面还请大家多多指导:)

----------------------------------------------实践补充-------------------------------------------------------

capabilities.setCapability("autoAcceptAlerts",true);
apabilities.setCapability("waitForAppScript", "$.delay(6000); $.acceptAlert(); true;");
System.out.print(wd.getPageSource());打印全部页面元素

使用 1.5 版本相比 1.4 swipe 的方式从 ‘xy 起始坐标’ 变成了 ‘xy 起坐标,xy 偏移量’。。。。。(又踩到了坑)
所以滑动的方法需要修改:

传入 driver,during 是滑动时间,num 是次数

左滑代码:(由于是左滑,偏移量为负)


public static void swipeToLeft(AppiumDriver<WebElement> driver, int during, int num) {
    int width = driver.manage().window().getSize().width;
    int height = driver.manage().window().getSize().height;
    System.out.println(width);
    System.out.println(height);
    for (int i = 0; i < num; i++) {
        driver.swipe(width*6/7, height / 2, -(width*4/7), 0, during);
    }


}

滑动代码亲测可用(适用版本 1.5.3)

import io.appium.java_client.AppiumDriver;
import org.openqa.selenium.WebElement;

/**
 * Created by gloria on 17/2/7.
 */
public class SwipUtils {

    /**
     * 向左滑动
     *
     * @param driver
     * @param during
     * @param num
     */
    public static void swipeToLeft(AppiumDriver<WebElement> driver, int during, int num) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        System.out.println(width);
        System.out.println(height);
        for (int i = 0; i < num; i++) {
            driver.swipe(width*6/7, height / 2, -(width*4/7), 0, during);
        }

    }


    /**
     * 上滑
     *
     * @param driver
     * @param during
     * @param num
     */
    public static void swipeToUp(AppiumDriver<WebElement> driver,int during, int num) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        for (int i = 0; i < num; i++) {
            driver.swipe(width / 2, height * 3 / 4, 0, -(height*2/ 4), during);

        }
    }

    /**
     * 下拉
     *
     * @param driver
     * @param during
     * @param num
     */
    public static void swipeToDown(AppiumDriver<WebElement> driver,int during, int num) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        System.out.println(width);
        System.out.println(height);
        for (int i = 0; i < num; i++) {
            driver.swipe(width / 2, height / 4, 0, height * 3 / 4, during);

        }
    }


    /**
     * 向右滑动
     *
     * @param driver
     * @param during
     * @param num
     */
    public static void swipeToRight(AppiumDriver<WebElement> driver,int during, int num) {
        int width = driver.manage().window().getSize().width;
        int height = driver.manage().window().getSize().height;
        for (int i = 0; i < num; i++) {
            driver.swipe(width / 4, height / 2, width * 3 / 4, 0 , during);

        }
    }
}

###
###
###
###

----------------------------------------------真机调试---------------------------------------------------

developer 选项里的 Enable UI Automation 开启,不然会报错:

selenium.common.exceptions.WebDriverException: Message: u'A new session could not be created. (Original error: Instruments crashed on startup)'

(这个错误 可能还和 app 签名有关 ,如果换手机:只要把用这个手机的签名重新编译一个 APP,就可以了。)

ideviceinstaller -l

显示如下:

‘空的’

很可能 你的 ideviceinstaller 版本太低 或者 没有 ,会报错找不到 这个 ideviceinstaller
删除老的并下载最新的 :

brew uninstall ideviceinstaller

brew install ideviceinstaller

就 OK 了

appium 会报的错误为: 安装 app 失败 大概就是: install xxx app faile

这时候 运行:sudo chmod 777 /var/db/lockdown/

再次执行 ideviceinstaller -l

出现你机器上的 app 包显示,就 ok 了

如果手机上有预装 不需要填写 app path 地址

启动后点击 Inspector 如果 Inspector 不能启动 脚本也会报错。

----------------------------------------------Android 真机调试---------------------------------------------------
步骤 见 https://testerhome.com/topics/153

下载了一个 demo 配置设置如下

这里 device name 直接使用 add devices 出来的结果就可以

----------------------------------------------android 的滑屏---------------------------------------------------

实验证明 android 的滑屏和 ios 不一样,android 仍然使用起止点的方式定义 swipe 方法,使用安卓时需要换 swipe 方式。
坑真多啊 摊手



/**
 * 向左滑动 安卓
 *
 * @param driver
 * @param during
 * @param num
 */
public static void swipeToLeftAndroid(AppiumDriver<WebElement> driver, int during, int num) {
    int width = driver.manage().window().getSize().width;
    int height = driver.manage().window().getSize().height;
    System.out.println(width);
    System.out.println(height);
    for (int i = 0; i < num; i++) {
        driver.swipe(width*6/7, height/2, width*1/7, height/2, during);
    }

}


((AppiumDriver<WebElement>) wd).hideKeyboard();


↙↙↙阅读原文可查看相关链接,并与作者交流