Selenium 网格 - 测试不是并行运行,而是在每个模拟器上运行两次

Posted

技术标签:

【中文标题】Selenium 网格 - 测试不是并行运行,而是在每个模拟器上运行两次【英文标题】:Selenium grid - test is not running in parallel instead it runs twice on each emulator 【发布时间】:2021-10-19 23:21:23 【问题描述】:

我正在尝试使用 selenium 网格在 appium 上运行并行测试。奇怪的是,它在每台设备上运行两次。

示例我有 2 个设备和 2 个测试用例,它在每个设备上运行 2 个测试用例。总共运行了 4 个测试用例。

我一直在努力思考可能出了什么问题,但我不确定是什么原因造成的。

DriverManager 类:

package com.universalapp.utility;

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 org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.IInvokedMethodListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;

import java.io.IOException;
import java.net.URL;

public class DriverManager 

    private static final ThreadLocal<AppiumDriver<MobileElement>> appiumDriver = new ThreadLocal<>();
    private final CapabilityFactory capabilityFactory = new CapabilityFactory();

    public static synchronized AppiumDriver<MobileElement> getAppiumDriver() 
        return appiumDriver.get();
    

    public static synchronized void setAppiumDriver(AppiumDriver<MobileElement> driver) 
        appiumDriver.set(driver);
    


    @BeforeMethod
    @Parameters("platformVersion", "udid")
    public void setup(String platform, String udid) throws IOException 
        String[] platformInfo = platform.split(" ");
        DesiredCapabilities caps = this.capabilityFactory.getCapabilities(platform, udid);
        if (platformInfo[0].equalsIgnoreCase("ANDROID")) 
            setAppiumDriver(new AndroidDriver<>(new URL(UniversalAppConstants.COMMON_APP_DETAILS.HUB_URL), caps));
         else 
            setAppiumDriver(new IOSDriver<>(new URL(UniversalAppConstants.COMMON_APP_DETAILS.HUB_URL), caps));
        
        System.out.println("Thread id = " + Thread.currentThread().getName());
        System.out.println("Hashcode of web driver instance = " + getAppiumDriver().hashCode());
    

    @AfterMethod
    public void teardown() 
        getAppiumDriver().quit();
    


跑步者类:

package com.universalapp.runner;

import com.universalapp.utility.DriverManager;
import io.cucumber.testng.CucumberOptions;
import io.cucumber.testng.FeatureWrapper;
import io.cucumber.testng.PickleWrapper;
import io.cucumber.testng.TestNGCucumberRunner;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

@CucumberOptions(
        plugin = "pretty", "json:target/json/output.json", "html:target/html/", "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:",
        features = "src/main/feature/",
        glue = "com.universalapp.stepDefinition",
        tags = "@Test",
        monochrome = true
)

public class RunnerTest extends DriverManager 

    private TestNGCucumberRunner testNGCucumberRunner;

    @BeforeClass(alwaysRun = true)
    public void setup() 
        this.testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
    

    @Test(dataProvider = "feature")
    public void features(PickleWrapper eventWrapper, FeatureWrapper cucumberFeature) 
        this.testNGCucumberRunner.runScenario(eventWrapper.getPickle());
    

    @DataProvider
    public Object[][] feature() 
        return this.testNGCucumberRunner.provideScenarios();
    

    @AfterClass(alwaysRun = true)
    public void tearDownClass() 
        this.testNGCucumberRunner.finish();
    


TestNg xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite name="Suite" parallel="tests" thread-count="2">
    <test name="emulator-5554">
        <parameter name="platformVersion" value="Android 8.0"/>
        <parameter name="udid" value="emulator-5554"/>
        <classes>
            <class name="com.universalapp.runner.RunnerTest"/>
        </classes>
    </test>
    <test name="emulator-5556">
        <parameter name="platformVersion" value="Android 10.0"/>
        <parameter name="udid" value="emulator-5556"/>
        <classes>
            <class name="com.universalapp.runner.RunnerTest"/>
        </classes>
    </test>
</suite>

【问题讨论】:

你曾经并行运行过 Cucumber 测试吗?我怀疑您所展示的内容可能实际上不起作用。请参阅此cucumber documentation。另一件事是您在问题标题中提到了 Selenium 网格。但是我在您的代码中看不到任何对网格的引用.. @AlexeyR。是的,类似的设置适用于网络。但不幸的是,不适用于移动设备。使用它作为黄瓜并行移动自动化的参考swtestacademy.com/appium-cucumber-parallel-test-execution 【参考方案1】:

检查您的第二个模拟器是否处于活动状态并显示在adb devices 下。默认情况下,每个第一个模拟器都有id : emulator-5554

【讨论】:

它处于活动状态。它在两个设备上运行。只是两次 尝试用 Cucumber 的 @Before 替换 TestNG 的 @BeforeMethod 并检查它是否仍然相同。尝试将 @BeforeMethod 中的 @Parameter("platformVersion", "udid") 的值存储在一些变量中并在您的 setup() 中调用

以上是关于Selenium 网格 - 测试不是并行运行,而是在每个模拟器上运行两次的主要内容,如果未能解决你的问题,请参考以下文章

使用 Robot 框架实现 Selenium 网格

使用 ThreadCount TestNG 限制并行测试的数量

历元 - 并行执行(网格)

在 Azure 批处理上运行 Selenium 并行测试

使用 selenium TestNG 和 selenium 进行并行测试

Selenium GRID:并行运行多个 Robot Framework 测试套件