简体   繁体   English

如何限制用作工厂的TestNG dataprovider方法的线程

[英]How do I limit threads on a TestNG dataprovider method used as a factory

I'm using selenium to test a single page app. 我正在使用硒来测试单页应用程序。 I'm loading the page in a @beforeClass method. 我正在使用@beforeClass方法加载页面。 Then running all the tests in the class. 然后运行该类中的所有测试。 Then tearing down the driver in the @afterClass method. 然后在@afterClass方法中@afterClass驱动程序。

I've annotated my constructor as a @factory method using a dataprovider from a base class. 我已经使用基类中的dataprovider构造函数注释为@factory方法。 The dataprovider is used to setup a collection of different browsers. dataprovider用于设置不同浏览器的集合。

I'm using crossbrowsertesting.com to run the tests, and I'm struggling to control the parallelization. 我正在使用crossbrowsertesting.com来运行测试,并且正在努力控制并行化。 I need to be able to control the maximum number of concurrent threads running at any one time (our current plan only allows for 2 simultaneous tests). 我需要能够控制任何一次运行的并发线程的最大数量(我们当前的计划仅允许2个同时测试)。 And I want to ensure that parallelisation occurs at the dataprovider level. 而且我想确保并行化发生在数据提供者级别。 (ie I want a thread for each browser up to a maximum of 2 threads). (即,我希望每个浏览器最多有2个线程)。

I'm using a testng.xml file. 我正在使用一个testng.xml文件。

<suite name="functional_tests" parallel="classes" thread-count="2">
    <test name="com.mapov.functional_tests suite">
        <classes>
           <class name="com.mapov.functional_tests.KiteTests" />
        </classes>

    </test>
</suite>

With a base class - 有基类-

public class BaseTest {

    public BaseTest (String browser, String platform, String resolution, String browserDescription) {  
        userName = "myUsername";
        accessKey = "myKey"; 
        pageUrl = "http://test.mapov.com/hotels/benidorm";
        this.browserDescription = browserDescription;

        caps = new DesiredCapabilities();
        caps.setCapability("browser_api_name", browser);
        caps.setCapability("os_api_name", platform);
        caps.setCapability("screen_resolution", resolution);
        caps.setCapability("name", this.browserDescription);
        caps.setCapability("record_video", "false");
        caps.setCapability("record_network", "false");
        caps.setCapability("record_snapshot", "false");      
    }

    @DataProvider(parallel=true)
    public static Object[][] getBrowsers() {
        return new Object[][]{
            new Object[]{"MblSafari8.0", "iPadAir-iOS8Sim", "1024x768", "Ipad air, with safari 8"}, 
            new Object[]{"IE11", "Win10", "1280x1024", "IE11 on windows 10"},
            new Object[]{"Safari9", "Mac10.11", "1280x1024", "Safari 9 on Mac osx10.11"}, 
        };
    }


    @BeforeClass
    public void SetupDriver() {
        long id = Thread.currentThread().getId();
        try {
            URL remoteDriverURL = new URL("http://" + userName + ":" + accessKey + "@hub.crossbrowsertesting.com:80/wd/hub");
            driver = new RemoteWebDriver(remoteDriverURL, caps);
            driver.get(pageUrl);
            WebElement pager = (new WebDriverWait(driver, 30)).until(ExpectedConditions.visibilityOfElementLocated(By.id("pager")));
        } catch (MalformedURLException ex) {
            System.out.println(ex.getMessage());
        }
    }

    @AfterClass
    public void disposeOfDriver() {
        // quit the driver
    }
}

And then an inheriting class with tests. 然后是带有测试的继承类。

public class KiteTests extends BaseTest {

    @Factory(dataProvider = "getBrowsers")
    public KiteTests(String browser, String platform, String resolution, String description) {
        super(browser, platform, resolution, "Kite tests on " + description);
    }   

    @Test 
    public void testKitesAppear() {
        // test.
    }

    @Test
    public void testHotelNamePresent() {
       // test
    }

}

If I remove the parallel="classes" thread-count="2" attributes from the suite node of the xml, then everything runs fine (just not in parallel). 如果我从xml的套件节点中删除parallel="classes" thread-count="2"属性,则一切运行正常(只是不并行)。

If I keep the parameters then I get the following error - 如果保留参数,则会出现以下错误-

    FAILED CONFIGURATION: @BeforeClass SetupDriver
org.openqa.selenium.WebDriverException: This account has reached it maxiumum number of concurrent selenium tests - please wait for a test to finish before starting a new test.
Command duration or timeout: 668 milliseconds
Build info: version: '2.48.2', revision: '41bccdd', time: '2015-10-09 19:55:52'
System info: host: 'Ewen-Macbook.lan', ip: '192.168.1.65', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.11', java.version: '1.8.0_45'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
    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:206)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:647)
    at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:247)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:129)
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:156)
    at com.mapov.functional_tests.BaseTest.SetupDriver(BaseTest.java:75)
    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.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
    at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

I think using the parameters concept of TestNG is a better method to get the desired results. 我认为使用TestNG的参数概念是获得所需结果的更好方法。

TestNG.xml TestNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="functional_tests Suite" parallel="tests"
thread-count="2">
<test name="functional_tests suite - Ipad air, with safari 8">
    <parameter name="browser" value="MblSafari8.0" />
    <parameter name="os" value="iPadAir-iOS8Sim" />
    <parameter name="screen" value="1024x768" />
    <parameter name="desc" value="Ipad air, with safari 8" />
    <classes>
        <class name="com.mapov.functional_tests.KiteTests" />
    </classes>
</test>

<test name="functional_tests suite - IE11 on windows 10">
    <parameter name="browser" value="IE11" />
    <parameter name="os" value="Win10" />
    <parameter name="screen" value="1024x768" />
    <parameter name="desc" value="IE11 on windows 10" />
    <classes>
        <class name="com.mapov.functional_tests.KiteTests" />
    </classes>
</test>

<test name="functional_tests suite - Safari 9 on Mac osx10.11">
    <parameter name="browser" value="Safari9" />
    <parameter name="os" value="Mac10.11" />
    <parameter name="screen" value="1024x768" />
    <parameter name="desc" value="Safari 9 on Mac osx10.11" />
    <classes>
        <class name="com.mapov.functional_tests.KiteTests" />
    </classes>
</test>

BaseClass 基类

import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;

public class BaseTest {

    @Parameters({ "browser", "os", "screen", "desc" })
    @BeforeClass
    public void SetupDriver(String browser, String os, String screen, String desc) {
        // connect to the remote server and load the page.
        System.out.println(browser + os + screen + desc);
    }

    @AfterClass
    public void disposeOfDriver() {
        // quit the driver
    }
}

Test Class 测试班

import org.testng.annotations.Test;

public class KiteTests {

    @Test
    public void testKitesAppear() {
        // test.
    }

    @Test
    public void testHotelNamePresent() {
        // test
    }
}

This structure gives control to configure the test flow from the XML file without changing the JAVA code. 这种结构使您可以控制从XML文件配置测试流程,而无需更改JAVA代码。

Hope this helps you!! 希望这对您有帮助!!

尝试使用: data-provider-thread-count="2"而不是thread-count="2"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 与DataProvider一起使用的TestNG Factory和@BeforeClass或@BeforeSuite - TestNG Factory and @BeforeClass or @BeforeSuite used with DataProvider 与数据提供者绑定时,Testng @Factory方法失败 - Testng @Factory method fails when tied with a DataProvider TestNG使用@Factory和@DataProvider - TestNG Using @Factory and @DataProvider 如何从testng数据提供程序检索特定的数据行? - How do I retrieve a specific row of data from a testng dataprovider? 如何将动态参数传递给testNG中的dataProvider方法 - How to pass dynamic parameter to dataProvider method in testNG 如果使用DataProvider,如何在TestNG可通过电子邮件发送的报告中提供自定义方法名称 - How to give Custom Method name in TestNG emailable report, in case when DataProvider is Used TestNG:如何从DataProvider获取将要由Factory创建的类 - TestNG: How to get class that is about to create by Factory from DataProvider 当使用工厂和数据提供者注释方法时,如何限制特定方法仅执行一次? - How to restrict the particular method to be executed once only, When factory and dataprovider annotation method is used? TestNG如何在每个测试用例中使用DataProvider之前重新初始化它? - TestNG How to reinitialize DataProvider before it is used in each test case? 使用Factory和Dataprovider的TestNG类永远无法工作 - TestNG class with Factory and Dataprovider never works
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM