当前位置: 首页 > 知识库问答 >
问题:

Selenium、TestNg并行运行不按预期工作

邓才
2023-03-14

我有3个测试类,由我想要并行运行的多个测试方法组成。我使用ThreadLocal来隔离每个线程的webdriver实例。当我按顺序运行测试时,一切看起来都很好,但是当我并行运行它们时,问题就出现了。下面是我的套件文件

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="platform" parallel="classes" thread-count="5">
    <test name="platform">
        <classes>
            <class name="com.sat.platform.mobile.PlatformMobileIdCaptureMonitoringWf11"></class>
            <class name="com.sat.platform.mobile.PlatformMobileIdVerificationMonitoringWf2"></class>
            <class name="com.sat.platform.mobile.PlatformMobileIdandIVMonitoringWf3"></class>
            <class name="com.sat.platform.mobile.PlatformMobileLivenessMonitoringWf6"></class>
            <class name="com.sat.platform.mixed.PlatformMixedIdSimilarityMonitoringWf2and5"></class>
        </classes>
    </test>
</suite>

我在@Beforeclass中初始化Web驱动程序BrowserClient.java如下。

    protected WebDriver driver;
    private static int implicitWaitTime;
    private static int explicitWaitTime;
    private static int fluentWaitTime;
    private static int pollingTime;
    protected static WebDriverWait explicitWait;
    protected static Wait<WebDriver> fluentWait;
    private static String browser;
    protected static Browsers browsers;

    static {
        Properties prop = new Properties();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream stream = loader.getResourceAsStream("browser.properties");
        try {
            prop.load(stream);
        } catch (IOException e) {
        }
        implicitWaitTime = Integer.parseInt(prop.getProperty("browser.implicit.wait.timeout"));
        explicitWaitTime = Integer.parseInt(prop.getProperty("browser.explicit.wait.timeout"));
        fluentWaitTime = Integer.parseInt(prop.getProperty("browser.fluent.wait.timeout"));
        pollingTime = Integer.parseInt(prop.getProperty("browser.wait.polling.time"));
        browser = System.getProperty("browser");
    }

    @BeforeClass
    public void initializeEnv() throws MalformedURLException {
        driver = BrowserFactory.createInstance(browser, implicitWaitTime);
        DriverFactory.getInstance().setDriver(driver);
        driver = DriverFactory.getInstance().getDriver();
        explicitWait = new WebDriverWait(driver, explicitWaitTime);
        fluentWait = new FluentWait(driver).withTimeout(Duration.of(fluentWaitTime, SECONDS))
                .pollingEvery(Duration.of(pollingTime, SECONDS))
                .ignoring(NoSuchElementException.class);
    }

这里使用的类即BrowserFactory.java

public static WebDriver createInstance(String browser, int implicitWaitTime) throws MalformedURLException {
        WebDriver driver = null;
        Browsers browserEnum = Browsers.valueOf(browser);
        String testVideo = ImageProcessingUtils.getAbsolutePath("digital_copy.mjpeg", false);

        switch (browserEnum) {
            case chrome:
                ChromeOptions options = new ChromeOptions();
                options.addArguments("--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream",
                        "--use-file-for-fake-video-capture=" + testVideo, "--start-maximized");
                driver = new ChromeDriver(options);
                break;

            case firefox:
                FirefoxProfile firefoxProfile = new FirefoxProfile();
                firefoxProfile.setPreference("media.navigator.permission.disabled", true);
                firefoxProfile.setPreference("media.navigator.streams.fake", true);
                firefoxProfile .setPreference("browser.private.browsing.autostart", false);
                FirefoxOptions firefoxOptions = new FirefoxOptions();
                firefoxOptions.setProfile(firefoxProfile);
                driver = new FirefoxDriver(firefoxOptions);
                break;
     }
}

驱动程序工厂.java

public class DriverFactory {

    private static DriverFactory instance = new DriverFactory();
    private static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
    private static List<WebDriver> driversList = new ArrayList();

    private DriverFactory(){

    }

    public static DriverFactory getInstance() {
        return instance;
    }

    public WebDriver getDriver(){
        WebDriver localDriver = driver.get();
        driversList.add(localDriver);
        return localDriver;
    }

    public void setDriver(WebDriver driver){
        this.driver.set(driver);
    }

    public static void removeDriver(){
        for(WebDriver driver : driversList) {
            driver.quit();
        }
    }
}

我的测试类扩展了BrowserClient。java,我可以直接使用驱动程序。这三个测试类中的一个常见方法是merchant_gets_auth_token(),如下所示。问题是当测试套件运行时,3个firefox浏览器并行打开,所有浏览器都导航到登录页面,但只有1个,有时2个测试通过,而第3个测试失败(无法登录)。

    @Test
    public void merchant_gets_oauth_token() {
        OAuth2Client client = new OAuth2Client();
        String loginUrl = DslConfigFactory.getEnvConfig("portal.customer.url");
        driver.get(loginUrl);
        CustomerPortalLoginPage loginPage = new CustomerPortalLoginPage(driver);
        log.info("----------merchant logging to customer portal to get oauth token----------");
        loginPage.login(merchantUser.getEmail(), merchantUser.getPassword());
        CustomerPortalHomePage homePage = new CustomerPortalHomePage(driver);
        homePage.clickOnSettings();
        CustomerPortalSettingsPage settingsPage = new CustomerPortalSettingsPage(driver);
        settingsPage.clickOnApiCredentials();
        CustomerPortalApiCredentialsPage apiCredentialsPage = new CustomerPortalApiCredentialsPage(driver);
        clientCredentials = apiCredentialsPage.getOauth2ClientCredentials();
        oauthToken = client.getOauthToken(clientCredentials.get("token"), clientCredentials.get("secret"));
    }

我一直在为这个问题苦苦挣扎了一段时间,并且在没有帮助的情况下查找了很多在线资源。也许这里有人能够做RCA。提前感谢!!

共有1个答案

华烈
2023-03-14
public static void removeDriver(){
        for(WebDriver driver : driversList) {
            driver.quit();
        }
    }

Here, replace driver.quit() with driver.close().
driver.close() method it will close only current driver. driver.close() closes all drivers. 

When first instance executes removeDriver(), it will closes all windows/drivers. Then next instance try to execute removeDriver(),there driver is not available because it is already closed by previous instance of driver.so you get error.
 类似资料:
  • 我使用下面的TestNG配置来启用Selenium测试的并行执行。 Java代码: 硒测试预计将并行运行。我希望有2个浏览器打开并运行测试脚本。 但我只看到一个浏览器,所有3个测试都一个接一个地运行,而不是并行运行。我尝试过使用“并行”属性的测试、方法、类和实例选项。 有什么帮助吗?

  • 实际-我看到的行为是它在1个节点上一次依次运行一个会话(FireFox浏览器)中的所有测试。 预期-本例中的类“IntegrationTest”有20个方法(@Test)。我希望看到该类中有5个测试被选中,并在1节点上的5个FireFox会话中并行运行。 这是我的testng套件文件。线程数为1是有意义的,因为我只想运行一个类。 这是我在中心和节点上运行的grid2命令。 枢纽命令- 节点命令-

  • 根据以下文档:http://testng.org/doc/documentation-main.html “如果测试类上有一个方法tearDown(),那么在每个测试方法之前和之后都会调用它”(JUnit 3) 我使用的是JUnit版本:3.8.1 这里的这个是在我的测试之前运行的,但我希望它会在测试之后。它在测试后没有运行: 我可以通过将第一行更改为: 但是,下一个类(下面)的表示法与第一个类完

  • 当我试图在Selenium Grid 2旁边使用TestNG并行运行测试时,我似乎遇到了一个问题。 尽管打开的浏览器数量与我正在运行的测试数量相匹配,但所有测试的所有指令都被发送到同一个浏览器窗口。例如,每个测试都会打开一个页面并尝试登录。四个浏览器窗口将打开,但一个浏览器窗口将导航到登录页面四次,然后键入用户名四次,而其余的浏览器窗口保持不活动。 以下是我如何启动网格: xml套件是这样设置的:

  • 我试图用TestNG并行运行一个示例测试项目。但它是在一个线程中顺序执行的。我漏掉什么了吗? 谢了。