我正在尝试使用testng并行运行自动化测试(Selenium webdriver)。这是我正在运行的节点:
java -Dwebdriver.gecko.driver=chromedriver.exe -jar selenium-server-standalone-3.4.0.jar -role node -hub http://localhost:4444/grid/register -browser browserName=chrome,maxInstances=2 -maxSession 2
这是我的测试课:
public class TestParallel { Login login; //@BeforeMethod(alwaysRun = true) public SeleniumDriverCore testSetup() throws FileNotFoundException, IOException{ SeleniumDriverCore driver = new SeleniumDriverCore("config/chromeDriverConfig"); Properties config = new Properties(); config.load(new FileInputStream("config/testConfig")); this.login = new Login(driver); driver.browser.open("https://test.test.xyz"); driver.browser.maximize(); driver.waits.waitForPageToLoad(); return driver; } @Test(groups={"parallel"}) public void test_one() throws FileNotFoundException, IOException{ SeleniumDriverCore driver=testSetup(); login.navigateToPage(Pages.LOGIN); login.assertion.verifyLoginPopupAndTitleDisplayed(); testCleanup(driver); } @Test(groups={"parallel"}) public void test_two() throws FileNotFoundException, IOException{ SeleniumDriverCore driver=testSetup(); login.navigateToPage(Pages.LOGIN); login.assertion.verifyLoginPopupAndTitleDisplayed(); testCleanup(driver); } @Test(groups={"parallel"}) public void test_three() throws FileNotFoundException, IOException{ SeleniumDriverCore driver=testSetup(); login.navigateToPage(Pages.LOGIN); login.assertion.verifyLoginPopupAndTitleDisplayed(); testCleanup(driver); } @Test(groups={"parallel"}) public void test_four() throws FileNotFoundException, IOException{ SeleniumDriverCore driver=testSetup(); login.navigateToPage(Pages.LOGIN); login.assertion.verifyLoginPopupAndTitleDisplayed(); testCleanup(driver); } public void testCleanup(SeleniumDriverCore driver){ driver.close(); driver.quit(); }
}
这是我的xml:
<suite name="Ontega - All Tests Mobile" parallel="methods" thread-count="2"> <test name="Ontega - All Tests Mobile"> <groups> <run> <include name="parallel"/> <exclude name="open-defects"/> </run> </groups> <packages> <package name="tests.*"/> </packages> </test> </suite>
当我运行XML时,我希望我的测试一次在两个线程中的两个浏览器上运行,但是,当我运行XML时,我使两个浏览器实例第一次运行,然后它们分别递增,并且50%测试失败了,您可以看到我正在尝试在每个方法中实例化驱动程序,尽管这不是我的框架如何工作,但我正在尝试解决此问题的瓶颈。任何帮助将不胜感激预先感谢
这是在TestNG中执行此操作的一些方法。您基本上可以通过@BeforeMethod和@AfterMethod配置方法来管理Webdriver实例化和清理。因此,您需要确定如何与您的@Test方法共享创建的webdriver实例。为此,您有三个选择:
@BeforeMethod
@AfterMethod
@Test
ThreadLocal
这是一个示例,向您展示了这一功能
import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; import org.testng.ITestResult; import org.testng.Reporter; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class TestClassSampleUsingThreadLocal { private static final ThreadLocal<RemoteWebDriver> drivers = new ThreadLocal<>(); @BeforeMethod public void instantiateBrowser(ITestResult testResult) { RemoteWebDriver driver = new ChromeDriver(); drivers.set(driver); } @Test(dataProvider = "dp") public void testMethod(String url) { Reporter.log("Launching the URL [" + url + "] on Thread [" + Thread.currentThread().getId() + "]", true); driver().get(url); Reporter.log("Page Title :" + driver().getTitle(), true); } @DataProvider(name = "dp", parallel = true) public Object[][] getData() { return new Object[][]{ {"http://www.google.com"}, {"http://www.stackoverflow.com"}, {"http://facebook.com"} }; } @AfterMethod public void cleanupBrowser() { RemoteWebDriver driver = driver(); driver.quit(); } private RemoteWebDriver driver() { RemoteWebDriver driver = drivers.get(); if (driver == null) { throw new IllegalStateException("Driver should have not been null."); } return driver; } }
ITestResult
import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; import org.testng.ITestResult; import org.testng.Reporter; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class TestClassSample { private static final String WEBDRIVER = "driver"; @BeforeMethod public void instantiateBrowser(ITestResult testResult) { RemoteWebDriver driver = new ChromeDriver(); testResult.setAttribute(WEBDRIVER, driver); } @Test(dataProvider = "dp") public void testMethod(String url) { Reporter.log("Launching the URL [" + url + "] on Thread [" + Thread.currentThread().getId() + "]", true); driver().get(url); Reporter.log("Page Title :" + driver().getTitle(), true); } @DataProvider(name = "dp", parallel = true) public Object[][] getData() { return new Object[][]{ {"http://www.google.com"}, {"http://www.stackoverflow.com"}, {"http://facebook.com"} }; } @AfterMethod public void cleanupBrowser(ITestResult testResult) { RemoteWebDriver driver = driver(testResult); driver.quit(); } private RemoteWebDriver driver() { return driver(Reporter.getCurrentTestResult()); } private RemoteWebDriver driver(ITestResult testResult) { if (testResult == null) { throw new IllegalStateException("testResult should have not been null."); } Object driverObject = testResult.getAttribute(WEBDRIVER); if (driverObject == null) { throw new IllegalStateException("Driver should have not been null."); } if (!(driverObject instanceof RemoteWebDriver)) { throw new IllegalStateException("Driver is not a valid webdriver object"); } return (RemoteWebDriver) driverObject; } }
org.testng.IInvokedMethodListener