首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的跨平台测试自动化框架不能并行运行?

为什么我的跨平台测试自动化框架不能并行运行?
EN

Stack Overflow用户
提问于 2018-01-23 05:10:44
回答 1查看 959关注 0票数 0

我目前正在为我公司的移动测试重写自动化测试框架。我们尝试使用一个由多个Page对象模型实现的接口,该接口依赖于运行应用程序的移动设备的操作系统。我可以让这个框架按顺序运行,甚至创建多个线程,但无论我做什么,它都不会并行运行。值得注意的是,我们使用的是Appium和DeviceCart/DeviceConnect,它允许我在物理上远程访问多个设备,因此这并不是在网格上运行。说到这里,我将链接我的相关代码(这是我的第二个版本,我用ThreadLocal写了一个,另一个没有用ThreadLocal)

这应该为每个测试实例化一个具有新线程的新驱动程序

代码语言:javascript
复制
public class TLDriverFactory {

    private ThreadLocal < AppiumDriver < MobileElement >> tlDriver = new ThreadLocal <>();

    public synchronized void setTLDriver(OS platform, String server, String udid, String bundleID) {

        switch (platform) {
        case IOS:
            tlDriver = ThreadLocal.withInitial(() -> {
                try {
                    return new IOSDriver < MobileElement > (new URL(server), DesiredCapsManager.getDesiredCapabilities(OS.IOS, udid, bundleID));
                } catch(MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null;
            });
            break;
        case ANDROID:
            tlDriver = ThreadLocal.withInitial(() -> {
                try {
                    return new AndroidDriver < MobileElement > (new URL(server), DesiredCapsManager.getDesiredCapabilities(OS.ANDROID, udid, bundleID));
                } catch(MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null;
            });
            break;
        default:
            break;
        }
    }

    public synchronized ThreadLocal < AppiumDriver < MobileElement >> getTLDriver() {
        return tlDriver;
    }
}

它处理浏览器的功能

代码语言:javascript
复制
public class DesiredCapsManager {

    public static DesiredCapabilities getDesiredCapabilities(OS platform, String udid, String bundleID) {
        //Set DesiredCapabilities
        DesiredCapabilities capabilities = new DesiredCapabilities();

        capabilities.setCapability("deviceConnectUserName", "User@Name.com");
        capabilities.setCapability("deviceConnectApiKey", "API-Token-Here");
        capabilities.setCapability("udid", udid);
        capabilities.setCapability("platformName", platform);
        capabilities.setCapability("bundleID", bundleID);
        //IOS only Settings
        if (platform.equals(OS.IOS)) {
            capabilities.setCapability("automationName", "XCUITest");
        }
        else {
            //Android only Settings
            capabilities.setCapability("automationName", "appium");
        }

        return capabilities;
    }
}

这是每个测试都继承的Base Test类

代码语言:javascript
复制
public class BaseTest {

    protected AppiumDriver < MobileElement > driver;
    protected AppiumSupport.TLDriverFactory TLDriverFactory = new AppiumSupport.TLDriverFactory();

    public enum OS {
        ANDROID,
        IOS
    }

    @AfterMethod
    public synchronized void tearDown() throws Exception {
        driver.quit();
        TLDriverFactory.getTLDriver().remove();
    }
}

下面是测试用例本身

代码语言:javascript
复制
public class Test_SignIn extends BaseTest {

    protected SignInPage signInPage;

    @Parameters(value = {
        "udid",
        "bundleID",
        "platform",
        "server"
    })
    @BeforeMethod
    public void setup(String udid, String bundleID, OS platform, String server) throws MalformedURLException,
    InterruptedException {
        //Set & Get ThreadLocal Driver
        TLDriverFactory.setTLDriver(platform, server, udid, bundleID);
        driver = TLDriverFactory.getTLDriver().get();
        Thread.sleep(5000);
        switch (platform) {
        case IOS:
            signInPage = new SignInPageIOS(driver);
            break;

        case ANDROID:
            signInPage = new SignInPageAndroid(driver);
            break;

        default:
            break;
        }

        System.out.println("Current Thread ID BeforeTest: " + Thread.currentThread().getName());
    }

    @Test
    public synchronized void Authenticate() throws Exception {
        System.out.println("Current Thread ID Test 1: " + Thread.currentThread().getName());
        signInPage.Login("Username", "Password");

    }
}

这是testng.xml文件

代码语言:javascript
复制
   < !DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Test" parallel="tests" thread-count="4">
   <test name="SignIn" parallel ="instances" thread-count="2">
          <parameter name="udid" value="DeviceIdGoesHere" />
          <parameter name="bundleID" value="Environment.address.here" />
          <parameter name="platform" value="ANDROID" />
          <parameter name="server" value="http://deviceconnect/appium" />
          <classes>
              <class name="Test.Test_SignIn">
              </class>
          </classes>
   </test>
   <test name="SignIn2" parallel="instances" thread-count="2">
          <parameter name="udid" value="DeviceIdGoesHere" />
          <parameter name="bundleID" value="Environment.address.here" />
          <parameter name="platform" value="IOS" />
          <parameter name="server" value="http://deviceconnect/appium" />
          <classes>
              <class name="Test.Test_SignIn">
              </class>
          </classes>
   </test>
</suite>

我正在寻找的是,是否有人可以确定我犯了什么错误,或者是什么瓶颈阻碍了测试的并行运行

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-26 16:09:08

根据您到目前为止所分享的内容,以下是应该支持您的并发性需求的经过清理和修复的代码。

负责为每个线程创建和清理Appium驱动程序实例的驱动程序工厂类如下所示:

代码语言:javascript
复制
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.ios.IOSDriver;

import java.net.MalformedURLException;
import java.net.URL;

public class TLDriverFactory {

    private static final ThreadLocal<AppiumDriver<MobileElement>> tlDriver = new ThreadLocal<>();

    public static void setTLDriver(BaseTest.OS platform, String server, String udid, String bundleID) throws MalformedURLException {

        System.out.println("Current Thread ID Driver Instantiation: " + Thread.currentThread().getName());

        AppiumDriver<MobileElement> driver;
        switch (platform) {
            case IOS:
                driver = new IOSDriver<>(new URL(server), DesiredCapsManager.getDesiredCapabilities(BaseTest.OS.IOS, udid, bundleID));
                break;

            default:
                driver = new AndroidDriver<>(new URL(server), DesiredCapsManager.getDesiredCapabilities(BaseTest.OS.ANDROID, udid, bundleID));
                break;
        }

        tlDriver.set(driver);
    }

    public static AppiumDriver<MobileElement> getTLDriver() {
        return tlDriver.get();
    }

    public static void cleanupTLDriver() {
        tlDriver.get().quit();
        tlDriver.remove();
    }
}

下面是BaseTest的样子,我猜它应该是所有测试的基类

代码语言:javascript
复制
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;

public class BaseTest {

    private static final ThreadLocal<SignInPage> signInPage = new ThreadLocal<>();

    public enum OS {
        ANDROID,
        IOS
    }

    @Parameters(value = {"udid", "bundleID", "platform", "server"})
    @BeforeMethod
    public void setup(String udid, String bundleID, OS platform, String server) throws Exception {
        //Set & Get ThreadLocal Driver
        TLDriverFactory.setTLDriver(platform, server, udid, bundleID);

        Thread.sleep(5000);
        SignInPage instance;
        switch (platform) {
            case IOS:
                instance = new SignInPageIOS(TLDriverFactory.getTLDriver());
                break;

            default:
                instance = new SignInPageAndroid(TLDriverFactory.getTLDriver());
                break;
        }

        System.out.println("Current Thread ID BeforeTest: " + Thread.currentThread().getName());
        signInPage.set(instance);
    }

    @AfterMethod
    public void tearDown() {
        System.out.println("Current Thread ID AfterTest: " + Thread.currentThread().getName());
        TLDriverFactory.cleanupTLDriver();
    }

    protected static SignInPage getPageForTest() {
        return signInPage.get();
    }

}

下面是页面类的构造函数应该是什么样子

代码语言:javascript
复制
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;

public class SignInPageIOS extends SignInPage {
    public SignInPageIOS(AppiumDriver<MobileElement> tlDriver) {
        super(tlDriver);
    }
}

下面是一个典型的测试用例的样子

代码语言:javascript
复制
import org.testng.annotations.Test;

public class Test_SignIn extends BaseTest {
    @Test
    public void authenticate() {
        //Get the instance of "SignInPage" for the current thread and then work with it.
        getPageForTest().Login("Username", "Password");
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48390324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档