Java 当DataProvider-TestNG上的Parallel设置为true时,并行执行测试会引发异常

Java 当DataProvider-TestNG上的Parallel设置为true时,并行执行测试会引发异常,java,selenium-webdriver,automated-tests,testng,testng-dataprovider,Java,Selenium Webdriver,Automated Tests,Testng,Testng Dataprovider,当DataProvider上的Parallel=true时,并行执行测试会引发以下异常。两个浏览器实例将在单独的线程上运行,但只有一个浏览器实例将成功执行,而另一个浏览器实例在尝试查找元素并引发异常时陷入困境。 请问,当dataprovider中的parallel=true时,如何使测试成功执行。我遗漏了一些东西,可能是BasePage中的WebDriver实例。请帮忙。谢谢 [PoolService-1] 15:44:06,447 INFO [Default test] Close driv

当DataProvider上的Parallel=true时,并行执行测试会引发以下异常。两个浏览器实例将在单独的线程上运行,但只有一个浏览器实例将成功执行,而另一个浏览器实例在尝试查找元素并引发异常时陷入困境。 请问,当dataprovider中的parallel=true时,如何使测试成功执行。我遗漏了一些东西,可能是BasePage中的WebDriver实例。请帮忙。谢谢

[PoolService-1] 15:44:06,447 INFO  [Default test] Close driver
PASSED: loginTest("unresticteduser@gmail.com", "123456")
FAILED: loginTest("resticteduser@gmail.com", "123456")

WARNING: WebDriverException thrown by findElement(By.xpath: //button[contains(text(), 'NO THANKS')])
org.openqa.selenium.WebDriverException: org.apache.http.conn.HttpHostConnectException: Connect to 
localhost:8478 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
当dataprovider上的parallel=false时,当数据输入测试并成功执行时,测试将一次打开一个浏览器实例

PASSED: loginTest("unresticteduser@gmail.com", "123456")
PASSED: loginTest("resticteduser@gmail.com", "123456")
以下是我编写的代码:

1 Browser工厂

公共类BrowserDriverFactory{ 私有ThreadLocal驱动程序=新ThreadLocal; 私有字符串浏览器; 私人日志记录器; 公共浏览器DriverFactoryString浏览器,日志记录器日志{ this.browser=browser.toLowerCase; this.log=log; } 公共WebDriver createDriver{ //创建驱动程序 log.infoCreate驱动程序:+浏览器; ifbrowser.equalschrome{ System.setPropertywebdriver.chrome.driver,src/main/resources/chromedriver.exe; driver.setnew铬驱动程序; } else ifbrowser.equalsfirefox{ System.setPropertywebdriver.gecko.driver,src/main/resources/geckodriver.exe; driver.setnewfirefoxdriver; } 否则{ System.out.println不知道如何启动:+browser+,启动chrome。; System.setPropertywebdriver.chrome.driver,src/main/resources/chromedriver.exe; driver.setnew铬驱动程序; } 返回driver.get; } } 2基础试验

公共类基类测试{ 受保护的网络驱动程序; 公共网络驱动器,它等待; 受保护的日志记录器日志; 受保护的Firefox配置文件; 受保护的字符串url=http://www.qaclickacademy.com/; 受保护的字符串testSuiteName; 受保护的字符串testName; 受保护的字符串testMethodName; @BeforeMethodalwaysRun=false 公共无效设置方法,ITestContext ctx{ 字符串testName=ctx.getCurrentXmlTest.getName; log=LogManager.getLoggertestName; BrowserDriverFactory=new BrowserDriverFactoryconfig.getBrowser,log; driver=factory.createDriver; driver.geturl; profile=新的FirefoxProfile; //设置文件类型的首选项 profile.setPreferencebrowser.helperApps.neverAsk.openFile,应用程序/八位字节流; driver.manage.window.maximize; 等待=新的WebDriverWaitdriver,5; this.testSuiteName=ctx.getSuite.getName; this.testName=testName; this.testMethodName=method.getName; } @AfterMethodalwaysRun=true public void tearDownITestResult结果{ ifresult.getStatus==ITestResult.FAILURE{ //截图 } log.infoClose驱动程序; //关闭浏览器 driver.quit; } } 3DataProvider

@DataProvidername=SearchProvider,parallel=true 公共对象[][]getDataFromDataprovider{ 返回新对象[][] { { unresticteduser@gmail.com, 123456 }, { resticteduser@gmail.com, 123456 } }; } 4BasePage

公共类基页{ 受保护的网络驱动程序; 公共网络驱动器,它等待; 受保护的日志记录器日志; 公共BasePageWebDriver驱动程序,日志记录器日志{ this.driver=driver; this.log=log; 等待=新的WebDriverWaitdriver,5; } 受保护的空长毫秒{ 试一试{ 线程。睡眠毫秒; }捕捉中断异常e{ e、 打印跟踪; } } 受保护的无效clickStallElementBy定位器{ 试一试{ 等待显示器的可视性,30; findElementlocator.click; } catchorg.openqa.selenium.StaleElementReferenceException ex { 等待显示器的可视性,30; findElementlocator.click; } } /**用给定的URL打开页面*/ 受保护的无效openUrlString url{ driver.geturl; } /**使用给定的定位器查找元素*/ 受保护的WebElement findElementBy定位器{ 返回driver.findElementlocator; } /**使用给定的定位器查找所有元素*/ 受保护列表findAllElementsBy定位器{ 返回driver.findelementslotor; } /**当元素可见时,单击具有给定定位器的元素*/ 受保护的空单击定位器{ 等待显示器的可视性,30; findElementlocator.click; log.infoClicked WebElement; } ... } 5基础测试

public class SignInPageTest extends BaseTest {


    @Test(dataProvider = "SearchProvider", dataProviderClass = DBDataProvider.class)
    public void loginTest(String username, String password) {

        System.err.println("Running Test=> " + this + " -> on thread [" + Thread.currentThread().getId() + "]");

        log.info("Starting LogInTest #  for " + username);

        ClickAcadamyLandingPage home = new ClickAcadamyLandingPage(driver, log);
        home.openPage();

        home.closeNewsLetterPopup();

        // click login
        ClickAcadamyLoginPage loginPage = new ClickAcadamyLoginPage(driver, log);
        loginPage = home.clickLoginBtn();

        loginPage.enterEmailAddress(username);

        loginPage.enterPassword(password);

        ClickAcadamyDashboard dashboard = loginPage.clickLogin();
        dashboard.clickLogout();

    }


 }
6testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" data-provider-thread-count = "2" thread-count="2" verbose="1" parallel="tests">

   <listeners>
     <listener class-name="com.paralleltest.basetest.TestListener"/>
   </listeners>

   <test name="loginTest">
    <classes>
      <class name="com.paralleltest.SignInPageTest"/>  
    </classes>
   </test> 

 </suite> 

问题在于您的测试代码。当您并行运行测试并由数据提供者提供支持时,您的webdriver实例将在测试方法之间共享

下面是BaseTest和BrowserDriverFactory的固定版本,其中包括线程安全

导入java.lang.reflect.Method; 导入org.openqa.selenium.WebDriver; 导入org.openqa.selenium.firefox.Fire foxProfile; 导入org.openqa.selenium.support.ui.WebDriverWait; 导入org.testng.ITestContext; 导入org.testng.ITestResult; 导入org.testng.annotations.AfterMethod; 导入org.testng.annotations.BeforeMethod; 公共类基类测试{ 私有静态最终ThreadLocal驱动程序=新ThreadLocal; 公共网络驱动器,它等待; 受保护的Firefox配置文件; 受保护的字符串url=http://www.qaclickacademy.com/; 受保护的字符串testSuiteName; 受保护的字符串testName; 受保护的字符串testMethodName; 公共WebDriver getDriver{ 返回drivers.get; } @预处理法 公共无效设置方法,ITestContext ctx{ 字符串testName=ctx.getCurrentXmlTest.getName; WebDriver-driver=BrowserDriverFactory.createDriverfirefox; drivers.setdriver; driver.geturl; driver.manage.window.maximize; 等待=新的WebDriverWaitdriver,5; this.testSuiteName=ctx.getSuite.getName; this.testName=testName; this.testMethodName=method.getName; } @AfterMethodalwaysRun=true public void tearDownITestResult结果{ getDriver.quit; 驱动程序。移除; } } BrowserDriverFactory.java

导入org.openqa.selenium.WebDriver; 导入org.openqa.selenium.chrome.ChromeDriver; 导入org.openqa.selenium.firefox.FirefoxDriver; 导入org.openqa.selenium.firefox.FirefoxOptions; 导入org.openqa.selenium.firefox.FirefoxProfile; 公共类BrowserDriverFactory{ 公共静态WebDriver CreateDriversString浏览器{ System.err.printlnCreate驱动程序:+浏览器; if browser.equalschrome{ System.setPropertywebdriver.chrome.driver,src/main/resources/chromedriver.exe; 返回新的镀铬驱动器; }如果browser.equalsfirefox{ System.setPropertywebdriver.gecko.driver,src/main/resources/geckodriver.exe; FirefoxOptions=新的FirefoxOptions; FirefoxProfile profile=新的FirefoxProfile; profile.setPreferencebrowser.helperApps.neverAsk.openFile,应用程序/八位字节流; options.setProfileprofile; 返回新的FirefoxDriveroptions; } System.out.println不知道如何启动:+browser+,启动chrome。; System.setPropertywebdriver.chrome.driver,src/main/resources/chromedriver.exe; 返回新的镀铬驱动器; } } 现在,在需要访问驱动程序对象时扩展BaseTest的所有测试类的测试方法中,可以通过调用getDriver方法来获得它

你可以在我的博客中找到一个完整的解释和更多的解释:

我还创建了一个库,它将webdriver生命周期管理抽象出来,并通过自定义注释使其更加简单


看看

问题在于测试代码。当您并行运行测试并由数据提供者提供支持时,您的webdriver实例将在测试方法之间共享

下面是BaseTest和BrowserDriverFactory的固定版本,其中包括线程安全

导入java.lang.reflect.Method; 导入org.openqa.selenium.WebDriver; 导入org.openqa.selenium.firefox.FirefoxProfile; 导入org.openqa.selenium.support.ui.WebDriverWait; 导入org.testng.ITestContext; 导入org.testng.ITestResult; 导入org.testng.annotations.AfterMethod; 导入org.testng.annotations.BeforeMethod; 公共类基类测试{ 私有静态最终ThreadLocal驱动程序=新ThreadLocal; 公共网络驱动器,它等待; 受保护的Firefox配置文件; 受保护的字符串url=http://www.qaclickacademy.com/; 受保护的字符串testSuiteName; 受保护的字符串testName; 受保护的字符串testMethodName; 公共WebDriver getDriver{ 返回drivers.get; } @预处理法 公共无效设置方法,ITestContext ctx{ 字符串testName=ctx.getCurrentXmlTest.getName; WebDriver-driver=BrowserDriverFactory.createDriverfirefox; drivers.setdriver; driver.geturl; driver.manage.window.maximize; 等待=新的WebDriverWaitdriver,5; this.testSuiteName=ctx.getSuite.getName; this.testName=testName; this.testMethodName=method.getName; } @AfterMethodalwaysRun=true public void tearDownITestResult结果{ getDriver.quit; 驱动程序。移除; } } BrowserDriverFactory.java

导入org.openqa.selenium.WebDriver; 导入org.openqa.selenium.chrome.ChromeDriver; 导入org.openqa.selenium.firefox.FirefoxDriver; 导入org.openqa.selenium.firefox.FirefoxOptions; 导入org.openqa.selenium.firefox.FirefoxProfile; 公共类BrowserDriverFactory{ 公共静态WebDriver CreateDriversString浏览器{ System.err.printlnCreate驱动程序:+浏览器; if browser.equalschrome{ System.setPropertywebdriver.chrome.driver,src/main/resources/chromedriver.exe; 返回新的镀铬驱动器; }如果browser.equalsfirefox{ System.setPropertywebdriver.gecko.driver,src/main/resources/geckodriver.exe; FirefoxOptions=新的FirefoxOptions; FirefoxProfile profile=新的FirefoxP 罗菲勒; profile.setPreferencebrowser.helperApps.neverAsk.openFile,应用程序/八位字节流; options.setProfileprofile; 返回新的FirefoxDriveroptions; } System.out.println不知道如何启动:+browser+,启动chrome。; System.setPropertywebdriver.chrome.driver,src/main/resources/chromedriver.exe; 返回新的镀铬驱动器; } } 现在,在需要访问驱动程序对象时扩展BaseTest的所有测试类的测试方法中,可以通过调用getDriver方法来获得它

你可以在我的博客中找到一个完整的解释和更多的解释:

我还创建了一个库,它将webdriver生命周期管理抽象出来,并通过自定义注释使其更加简单


看一看

非常感谢。你救了我的灵魂。现在一切都运转良好。非常感谢请你接受答案,这样问题就结束了。非常感谢。你救了我的灵魂。现在一切都运转良好。非常感谢请你接受答案,这样问题就结束了?