如何使用testng并行运行我的硒测试方法

时间:2017-10-11 21:52:46

标签: java selenium testng selenium-grid parallel-testing

我正在尝试使用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%的测试都失败了,你可以看到我试图在我的每个方法中实例化驱动程序,虽然它不是我的框架如何工作,但我试图找到这个问题的瓶颈。 任何帮助将非常感激 提前致谢

2 个答案:

答案 0 :(得分:5)

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

  1. 您使用ThreadLocal变体,因为TestNG向您保证它将在同一个帖子中执行@BeforeMethod@Test@AfterMethod
  2. 这是一个示例,向您展示了这一点

    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;
        }
    
    }
    
    1. 您可以通过ITestResult对象共享webdriver实例。这是一个展示实际情况的示例。
    2. 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;
          }
      }
      
      1. 您将webdriver实例化和清理提取到TestNG侦听器(实现org.testng.IInvokedMethodListener的侦听器,该侦听器将创建的webdriver设置为ITestResult(如选项2所示)或{{1 (如选项1所示)。您可以在blog post中找到有关此选项的更多详细信息以及代码段。

答案 1 :(得分: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