前记

通过 Appium+Maven+TestNG 操作多终端运行

代码

InitDriver.java

private static AppiumDriver driver;

public static AppiumDriver getDriver() {
    return driver;
}

/**
 * 初始化启动
 *
 * @param udid 设备唯一标志
 * @param port Appium server通信的端口
 */
@BeforeClass
@Parameters({"udid", "port", "platformName", "appPackage", "appActivity", "isAppBrand", "androidProcess"})
public static void setUp(@Optional("06157df6f1f6813c") String udid, @Optional("4723") String port,
                         String platformName, String appPackage, String appActivity, boolean isAppBrand,
                         String androidProcess) throws Throwable {
    System.out.println("udid:" + udid + ",port:" + port);

    DesiredCapabilities caps = new DesiredCapabilities();

    caps.setCapability("platformName", platformName);
    caps.setCapability("deviceName", udid);
    caps.setCapability("udid", udid);
    caps.setCapability("automationName", "uiautomator2");
    caps.setCapability("appPackage", appPackage);
    caps.setCapability("appActivity", appActivity);
    caps.setCapability("noReset", true);
    caps.setCapability("showChromedriverLog", true);

    if (isAppBrand) {
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setExperimentalOption("androidProcess", androidProcess);
        caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
    }

    caps.setCapability("browserName", "");

    driver = new AppiumDriver(new URL("http://127.0.0.1:" + port + "/wd/hub"), caps);
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}

@AfterClass
public static void afterClass() {
    // 每一个用例完毕结束这次测试
    driver.quit();
}

XueQiu.java

public class XueQiu extends InitDriver {

    private static AppiumDriver driver;

    @BeforeClass
    public void initDriver() {
        driver = InitDriver.getDriver();
    }

    @Test
    public void demo() throws InterruptedException {
        Thread.sleep(5000);
        System.out.println(driver.getPageSource());
    }
}

Example.java

public class Example extends InitDriver {

    private static AppiumDriver driver;

    @BeforeClass
    public void initDriver() {
        driver = InitDriver.getDriver();
    }

    /**
     * 测试步骤
     * 1. 在微信界面点击"我",进入个人画面
     * 2. 点击"卡包",再次点击"查看全部",表示所有会员卡
     * <p>
     * 通过使用`@Test(priority = 1)`控制每个用例的执行顺序
     * 没有注明`(priority = 1)`默认值为0,最优先执行
     */
    @Test
    public void testOne() throws Throwable {

        driver.findElementByXPath("//*[@resource-id='com.tencent.mm:id/cdj' and @text='我']").click();
        driver.findElementByXPath("//*[@text='卡包']").click();
        driver.findElementByXPath("//*[contains(@text,'查看全部')]").click();

        Thread.sleep(5000);

        System.out.println("获取元素\n" + driver.getPageSource());
    }
}

testNG.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="测试" parallel="tests" thread-count="2" preserve-order="true">
    <test name="卡包储值">
        <!--verbose="2" 控制记录日志的详细级别-->
        <!--preserve-order="true" 控制按顺序执行-->
        <parameter name="port" value="4723"/>
        <parameter name="udid" value="06157df6f1f6813c"/>
        <parameter name="platformName" value="Android"/>
        <parameter name="appPackage" value="com.tencent.mm"/>
        <parameter name="appActivity" value=".ui.LauncherUI"/>
        <parameter name="isAppBrand" value="true"/>
        <parameter name="androidProcess" value="com.tencent.mm:appbrand0"/>
        <classes>
            <class name="iwinnerExample.Example"/>
        </classes>
    </test>
    <test name="雪球demo">
        <!--verbose="2" 控制记录日志的详细级别-->
        <!--preserve-order="true" 控制按顺序执行-->
        <parameter name="port" value="4755"/>
        <parameter name="udid" value="192.168.56.102:5555"/>
        <parameter name="platformName" value="Android"/>
        <parameter name="appPackage" value="com.xueqiu.android"/>
        <parameter name="appActivity" value=".view.WelcomeActivityAlias"/>
        <parameter name="isAppBrand" value="false"/>
        <parameter name="androidProcess" value=""/>
        <classes>
            <class name="iwinnerExample.XueQiu"/>
        </classes>
    </test>
    <listeners>
        <listener class-name="org.uncommons.reportng.HTMLReporter"/>
        <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
    </listeners>
</suite>

执行截图

问题点

  1. testNG.xmlsuitethread-count设置为 1,单个单个运行
  2. thread-count设置为 2,两个终端同时运行,就不成功,错误日志
org.openqa.selenium.WebDriverException: It is impossible to create a new session because 'createSession' which takes HttpClient, InputStream and long was not found or it is not accessible
Build info: version: '3.12.0', revision: '7c6e0b3', time: '2018-05-08T14:04:26.12Z'
System info: host: 'TD-01.local', ip: 'fe80:0:0:0:1c49:d6bd:ef23:d60e%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.6', java.version: '1.8.0_171'
Driver info: driver.version: InitDriver

    at io.appium.java_client.remote.AppiumCommandExecutor$1.createSession(AppiumCommandExecutor.java:195)
    at io.appium.java_client.remote.AppiumCommandExecutor.createSession(AppiumCommandExecutor.java:209)
    at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:231)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:543)
    at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
    at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:207)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:130)
    at io.appium.java_client.DefaultGenericMobileDriver.<init>(DefaultGenericMobileDriver.java:38)
    at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:84)
    at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:94)
    at InitDriver.InitDriver.setUp(InitDriver.java:54)
    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:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:168)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:105)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.access$000(SuiteRunner.java:40)
    at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:489)
    at org.testng.internal.thread.ThreadUtil$1.call(ThreadUtil.java:52)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
    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:498)
    at io.appium.java_client.remote.AppiumCommandExecutor$1.createSession(AppiumCommandExecutor.java:185)
    ... 32 more
Caused by: org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8201
Build info: version: '3.12.0', revision: '7c6e0b3', time: '2018-05-08T14:04:26.12Z'
System info: host: 'TD-01.local', ip: 'fe80:0:0:0:1c49:d6bd:ef23:d60e%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.6', java.version: '1.8.0_171'
Driver info: driver.version: InitDriver
remote stacktrace: UnknownError: An unknown server-side error occurred while processing the command. Original error: Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8201
    at JWProxy.command$ (/usr/local/lib/node_modules/appium/node_modules/_appium-base-driver@3.2.0@appium-base-driver/lib/jsonwp-proxy/proxy.js:248:13)
    at tryCatch (/usr/local/lib/node_modules/appium/node_modules/_babel-runtime@5.8.24@babel-runtime/regenerator/runtime.js:67:40)
    at GeneratorFunctionPrototype.invoke [as _invoke] (/usr/local/lib/node_modules/appium/node_modules/_babel-runtime@5.8.24@babel-runtime/regenerator/runtime.js:315:22)
    at GeneratorFunctionPrototype.prototype.(anonymous function) [as throw] (/usr/local/lib/node_modules/appium/node_modules/_babel-runtime@5.8.24@babel-runtime/regenerator/runtime.js:100:21)
    at GeneratorFunctionPrototype.invoke (/usr/local/lib/node_modules/appium/node_modules/_babel-runtime@5.8.24@babel-runtime/regenerator/runtime.js:136:37)
    at <anonymous>
    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:423)
    at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$new$0(W3CHandshakeResponse.java:57)
    at org.openqa.selenium.remote.W3CHandshakeResponse.lambda$getResponseFunction$2(W3CHandshakeResponse.java:104)
    at org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0(ProtocolHandshake.java:123)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464)
    at org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:126)
    ... 37 more


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