2017-10-11 207 views
0

我想用testng并行运行我的自动化测试(Selenium webdriver)。这是我正在运行的节点:如何使用testng并行运行我的硒测试方法

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时,我得到两个浏览器ances在第一时间运行,然后他们增加和50%的测试失败,你可以看到我试图在我的每个方法中实例化驱动程序,虽然这不是我的框架如何工作,但我试图去解决这个问题的瓶颈。 任何帮助将不胜感激 在此先感谢

+1

要创建每个测试方法调用两个司机,你也只需要调用退出时,你拆掉 –

+0

我已经修复了我的代码,现在的问题是,铬页面打开一个空白页,就是这样。 –

回答

2

以下是在TestNG中执行此操作的一些方法。您基本上通过@BeforeMethod@AfterMethod配置方法管理您的webdriver实例化和清理。那么您需要决定如何与您的@Test方法共享创建的webdriver实例。对于你有三种选择:

  1. 您使用一个ThreadLocal变种,因为TestNG的保证给你,它会在同一个线程执行@BeforeMethod@Test@AfterMethod所有。

这里的一个样品,显示您这个动作

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对象共享的webdriver实例。以下是一个示例,展示了这一行动。
  • 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; 
        } 
    } 
    
  • 您提取出的webdriver实例化和净化成TestNG的监听器(一个实现一个org.testng.IInvokedMethodListener其设定所创建的webdriver到ITestResult(如图选项2 )或成ThreadLocal(如选项1所示),你可以在我的blog post找到关于使用代码片段沿此选项的详细信息。
  • +0

    非常感谢您的回答! –

    0

    看来你创建每个测试多个驱动程序。我猜你需要保持testSetup以外的代码的一些部分()方法

    SeleniumDriverCore driver = new SeleniumDriverCore("config/chromeDriverConfig"); 
    Properties config = new Properties(); 
    config.load(new FileInputStream("config/testConfig")) 
    

    我分享我的代码,我使用了并行测试的一部分,可能是将你的情况帮enter image description here

    我的xml enter image description here

    +0

    感谢您的评论@Shoaib,在并行方法中运行测试以及在测试方法之外声明驱动程序的问题是驱动程序实例状态在测试执行期间可能会被覆盖 –