Appium android 上 appium 多个设备同时执行

fengcanfly · 2015年11月05日 · 最后由 离黎 回复于 2018年05月31日 · 3521 次阅读

多个设备同时执行多个不同的用例,研究了大半天终于搞定了,也不难,给大家分享一下
测试类 1:

package com.fenfa;
。。。。。
import com.jayway.jsonpath.JsonPath;

public class XiaoMi {
    private AndroidDriver driver;
    File classpathRoot = new File(System.getProperty("user.dir"));
    File res = new File(classpathRoot, "resource");
    String time = new SimpleDateFormat("yyyyMMdd").format(new Date());
    String timeJson = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    String timeS = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
    Tools tool=new Tools();
    String port;
    String udid;

    // 生成json

    public static int lastPage = 0;
    public static int pageIndex = 1;
    public static String number = "";
    // 屏幕宽高
    public static int width = 0;
    public static int height = 0;


    @BeforeMethod
    @Parameters({"port","udid"})
    public void setUp(String port,String udid) throws Exception {
        System.out.println(port+" "+udid);
        // set up appium
        File app = new File(res, "com.xiaomi.market_R.1.4.5.apk");
        System.out.println(app.getAbsolutePath());
        DesiredCapabilities capabilities = new DesiredCapabilities();
        //capabilities.setCapability("deviceName", "Android Emulator");
        capabilities.setCapability("deviceName", udid);
        capabilities.setCapability("udid", udid);
        capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
        capabilities.setCapability("platformVersion", "4.4.4");
        capabilities.setCapability("platformName", "Android");
        capabilities.setCapability("app", app.getAbsolutePath());
        capabilities.setCapability("app-package", "com.xiaomi.market");
        capabilities.setCapability("app-activity", ".ui.MainTabActivity");
        driver = new AndroidDriver(new URL("http://127.0.0.1:"+port+"/wd/hub"),
                capabilities);
    }

    @Test(groups = { "SDK" })
    public void testXiaomi() throws InterruptedException{
        tool.screenShot("小米", "分类", 1, driver);
        System.out.println("小米-------");
              。。。。。
    }

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

测试类 2

package com.fenfa;
。。。。。
import com.jayway.jsonpath.JsonPath;

public class WanDouJia {
    private AndroidDriver driver;
    File classpathRoot = new File(System.getProperty("user.dir"));
    File res = new File(classpathRoot, "resource");
    String time = new SimpleDateFormat("yyyyMMdd").format(new Date());
    String timeJson = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
            .format(new Date());
    String timeS = new SimpleDateFormat("yyyyMMddHHmm").format(new Date());
    Tools tool=new Tools();
    String port;
    String udid;

    // 生成json

    public static int lastPage = 0;
    public static int pageIndex = 1;
    public static String number = "";
    // 屏幕宽高
    public static int width = 0;
    public static int height = 0;

    @BeforeMethod
    @Parameters({"port","udid"})
    public void setUp(String port,String udid) throws Exception {
        System.err.println(port+" "+udid);
        // set up appium
        File app = new File(res, "com.xiaomi.market_R.1.4.5.apk");
        System.out.println(app.getAbsolutePath());
        DesiredCapabilities capabilities = new DesiredCapabilities();
        // capabilities.setCapability("deviceName", "Android Emulator");
        capabilities.setCapability("deviceName", udid);
        capabilities.setCapability("udid", udid);
        capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
        capabilities.setCapability("platformVersion", "4.4.4");
        capabilities.setCapability("platformName", "Android");
        // capabilities.setCapability("unicodeKeyboard", "True");
        // capabilities.setCapability("resetKeyboard", "True");
        capabilities.setCapability("app", app.getAbsolutePath());
        // capabilities.setCapability("app-package", "com.xiaomi.market");
        // capabilities.setCapability("app-activity", ".ui.MainTabActivity");
        driver = new AndroidDriver(new URL("http://127.0.0.1:"+port+"/wd/hub"),
                capabilities);
    }
    @Test(groups = { "SDK" })
    public void testWanDou() throws InterruptedException{
        tool.screenShot("豌豆荚", "分类", 1, driver);
        System.out.println("豌豆荚----------");
               。。。。。
    }

    @AfterMethod
    public void tearDown() throws Exception {
        driver.quit();
    }
}
配置中一定要用udid,andorid也就是deviceName当作udid使用

testng.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<suite name='Suite1' parallel="tests" thread-count="5">

 <test name="demo1">
   <parameter name = "port" value = "4723"/>
   <parameter name = "udid" value = "331f188d"/>
   <classes>
     <class name="com.fenfa.XiaoMi"/> 
    </classes>
  </test>

   <test name="demo2">
       <parameter name = "port" value = "4725"/>
       <parameter name = "udid" value = "CB5A21SXVP"/>
       <classes>
     <class name="com.fenfa.WanDouJia"/>
     </classes>
  </test>
</suite>
testng.xml中配置参数,多线程个数thread-count="5"

pom.xml 的一部分

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
      <configuration>
            <suiteXmlFiles>
                 <suiteXmlFile>testng.xml</suiteXmlFile>
            </suiteXmlFiles>                
    </configuration>
</plugin>

启动多个 appium server
第一个 server


第二个 server

最后执行
mvn test

共收到 21 条回复 时间 点赞
2楼 已删除

#2 楼 @lihuazhang 请管理员审批

匿名 #4 · 2015年12月25日

#3 楼 @fengcanfly
楼主可以把整个 pom.xml 发出来看下吗?不知道为何一直在报错,想学习下

#3 楼 @fengcanfly 启动多个 appium server 可以做成自动化,我没有用 testng 自带的多线程机制,是自己写多线程实现的,感觉更灵活

请教一下,不使用 maven 和 testng,只用 junit 能实现测试用例的并行执行吗?

启动 appium server 可以从命令行执行的。像下面
appium -p 4723 -bp 4724 -U 22238e79 --command-timeout 600
所以可以专门写一个类, 去自动启动 appium server, 当测试执行完成后,再自动关闭。

问下,你用的是 testng+maven 是吗?maven 和 testng 配置怎么做的 请指教

都是大神啊

python 写的多线程并发,结果还是先运行完一个 appium 然后在运行另一个

大神有没有 python 的写法?

请问楼主,开启多个 appium server,为什么需要设置 Bootstrap Port,这个 port 有什么作用吗,谢谢

#7 楼 @xutester 大神 麻烦问下,你说的这个 appium -p 4723 -bp 4724 -U 22238e79 --command-timeout 600。是启动了 Node Server 还是就只是打开了 appium 应用,我用了这个它只启动了 appium 客户端需要手动点击启动,可以直接就启动吗?

#13 楼 @alex429 启动 appium 服务可以通过该命令行启动:node C:\Develop\Appium\node_modules\appium\lib\server\main.js --address 127.0.0.1 --port 4723--platform-name Android --platform-version 17 --automation-name Appium --log-no-color,在 appium 点击三角启动的时候就会出现,你可以百度一下各个参数的含义,我目前也在查找解决多设备的问题。

我多台执行的时候提示这个:
org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: Command failed: C:\Windows\system32\cmd.exe /s /c "D:\wyf\tools\Android\ADT-64\ADT\sdk\platform-tools\adb.exe shell "getprop persist.sys.language""
error: more than one device/emulator
) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 7.41 seconds
Build info: version: '2.44.0', revision: '76d78cf', time: '2014-10-23 20:02:37'
System info: host: 'Administrator_0', ip: '192.168.2.170', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_73'
Driver info: io.appium.java_client.android.AndroidDriver
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:204)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:180)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:240)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:126)
at org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:153)
at io.appium.java_client.AppiumDriver.(AppiumDriver.java:109)
at io.appium.java_client.android.AndroidDriver.(AndroidDriver.java:39)
at basicTest.basicTest.setUp(basicTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

#12 楼 @xmtzlj port 是 client 和 appium server 通信的端口,bootstrap port 是 mobile device 和 appium server 通信的端口,转自网络。
一开始忘记修改了 bootstrap port 结果执行的时候一台模拟器执行完后才去执行另一台模拟器的动作。甚至就此卡住。

匿名 #17 · 2017年04月18日

楼主问个问题 能够一个 appiumservice 启动多个 session 呢

实际效果还是一个设备一个设备运行啊。能同时运行?

用 python 的话怎么跑这个过程?

赞一个 ,正在琢磨着(python)如何进行一个设备发出请求,另一台设备接受请求,这两台设备之间存在依赖关系。。。。。


在运行多个设备时,总是报以上错误,abd 的端口号 5037,这个怎么解决的?

多设备应用是同时启动了,但是运行 case 时,就是一个先运行,等运行完毕后,另一个才会再运行,各位有解决这个的吗??是我的多线程写的有问题吗??

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