问题描述
我想使用@dataprovider在TestNg中并行运行硒测试.理想情况下,测试是按方法并行的(一种测试=一种方法),而不是浏览器的简单套件并行性.我读过某个地方的内容,一次可以控制大约5个ChromeDriver实例,因此我认为应该可以实现.稍后,我计划移至grid2.为了进行开发,我通过右键单击+在XML配置文件上运行,使用IntelliJ Idea测试运行程序运行该程序.
I want to run selenium tests in TestNg in parallel that use the @dataprovider. Ideally tests are parallel by method (one test = one method) and not simple suite parallelism by browser. I have read somewhere that about 5 instances of ChromeDriver can be controlled at a time so I thought this should be possible. Later I plan to move to grid2. For developement I'm running things with IntelliJ Idea test runner by right-click + run on the XML config file.
我无法同时(在grid2和本地)运行测试,因此我创建了一个或多或少想要执行的示例.
I had problems running my tests in parallel (on grid2 and locally) so I created a sample of more or less what I want to do.
这是我的考试班
package tests;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.*;
import java.util.concurrent.TimeUnit;
import static org.testng.Assert.assertNotNull;
public class ParallelTest {
public static final String SEARCH_TERMS = "search-terms";
private WebDriver driver;
@BeforeMethod
@Parameters({"browser"})
public void beforeMethod(@Optional("chrome") String browser){
driver = getBrowser(browser);
driver.manage().deleteAllCookies();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
private WebDriver getBrowser(String browser) {
if(browser.equals("chrome")){
System.setProperty("webdriver.chrome.driver", "webdrivers\\chromedriver.exe");
return new ChromeDriver();
}
return new FirefoxDriver();
}
@AfterMethod
public void afterMethod(){
driver.quit();
}
@Test(description = "Check parallel selenium works.",
dataProvider = SEARCH_TERMS)
public void parallelSeleniumTest(String searchTerm){
driver.get("http://google.com");
WebElement search = driver.findElement(By.id("gbqfq"));
new Actions(driver)
.sendKeys(search, searchTerm)
.sendKeys(search, Keys.ENTER)
.perform();
String firstResult = driver.findElements(By.className("r")).get(0).getText();
assertNotNull(firstResult);
System.out.println(firstResult);
}
@DataProvider(name = SEARCH_TERMS, parallel = true)
public Object[][] getSearchTerms(){
return new Object[][]{
{"google"},
{"microsoft"},
{"facebook"},
{"amazon"},
{"apple"},
{"oracle"},
{"yahoo"},
{"jetbrains"},
{"intellij idea"},
{"selenium"},
{"java"},
{"testng"},
{"code"}
};
}
}
我抛出了一些本地事件,因为我在测试套件中大量使用了它们.
I threw in some native events since I use them heavily in my test suite.
这是TestNg xml配置文件
And here is the TestNg xml config file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite thread-count="4" name="vfr6-ui-tests" parallel="methods">
<test name="parallel-test-firefox">
<parameter name="browser" value="firefox"/>
<classes>
<class name="tests.ParallelTest"/>
</classes>
</test>
<test name="parallel-test-chrome">
<parameter name="browser" value="chrome"/>
<classes>
<class name="tests.ParallelTest"/>
</classes>
</test>
</suite>
我读到每个测试实例化一个驱动程序往往是最可维护的.问题在于,firefox测试以串行方式运行,而chrome测试将所有数据点作为测试用例吐出,尝试打开大量浏览器实例,然后一切都失败了.我的测试将具有10-25或300-500个数据点(在客户或客户x产品之间循环).
I read instantiating one driver per test tends to be the most maintainable. The problem is that the firefox test runs in serial while the chrome test spits out all of the data points as test cases, attempts to open a trove of browser instances, then everything fails. My tests will have either 10-25 or 300-500 data points (cycling between either clients or clients x products).
设置驱动程序,数据提供程序和测试运行程序以在运行测试中实现最佳并行性的最佳方法是什么?
What is the best way to set up the driver, dataprovider, and test runner to achieve the best parallelism in running tests?
推荐答案
我对dataProvider也有相同的经验.在我的情况下,我使用了dataProvider的(parallel = true)属性.有两种解决您的问题的方法.
I had the same experience about dataProvider. In my case I used dataProvider's (parallel=true) attribute though. There are two solutions to your problem.
-
在测试类中使用dataProvider,并为构造函数使用工厂注释.在工厂注释的属性中,使用dataProvider =您的dataProvider的名称".在testng.xml中,使用parallel = instances而不是parallel = methods.
Use dataProvider and in test class and use factory annotation for your constructor.In the factory annotation's attribute, use dataProvider="Your dataProvider's name".In the testng.xml, instead of parallel=methods, use parallel=instances.
上述方法的缺点是当您获取报告时;可能是行家-surefire,testng Eclipse报告或reportNG报告,您看不到传递的参数正面.为了克服这个问题,您可以使用以下方法.
The drawback of the above approach is that when you get the report; may be it is maven-surefire, testng Eclipse report or reportNG report, you do not see parameters passed upfront. To overcome this, you can use the following approach.
创建一个工厂类,并使用for循环. (从0开始循环.)在测试类中定义一个构造函数,该构造函数从工厂类接收参数.在此测试类中定义一个dataProvider,可以使用构造函数中接收到的参数(数据点).定义一个BeforeMethod或BeforeClass可以使用该参数或数据点,并且您的测试方法应使"dataProvider"属性指向所需的dataProvider.再次,在testng.xml使用parallel ="instances".
Create a factory class and instantiate your test class in the factory method using afor loop. (Start for loop from 0.) In the test class define a constructor whichreceives a parameter from factory class. Define a dataProvider in this test class whichcan use the parameter (data-point) received in the constructor. Define a BeforeMethodor BeforeClass which can use that parameter or data point and Your test methods shouldhave the "dataProvider" attribute pointing to the desired dataProvider. Again, intestng.xml use parallel="instances".
此外,使用try/catch块实例化驱动程序对象并关闭浏览器.这将帮助您避免由于tearDown方法的setUp失败而导致的跳过.
Also, use try/catch block for instantiating driver object and closing the browser. Thiswill help you in avoiding skips due to failure of setUp of tearDown method.
这篇关于使用dataprovider执行并行TestNG硒测试的驱动程序行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!