繁体   English   中英

如何通过使用 TestNG 和 Selenium 的方法并行运行测试

[英]How to run tests in parallel by methods with TestNG and Selenium

问题如下。 我正在使用 TestNG v.7.6.0 和 Selenium v​​.4.2.2。 我尝试与 invocationCount 和 threadPoolSize 并行运行相同的测试方法。 这是我的测试类的一个例子(AUT 是“https://www.saucedemo.com/”):

import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.time.Duration;

public class LoginTest {

    ThreadLocal<WebDriver> driver;

    @BeforeMethod()
    public void setup() {
        WebDriverManager.chromedriver().setup();
        WebDriver webDriver = new ChromeDriver();
        webDriver.manage().window().maximize();
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        webDriver.get("https://www.saucedemo.com/");
        this.driver = new ThreadLocal<WebDriver>();
        this.driver.set(webDriver);
    }

    @Test(invocationCount = 2, threadPoolSize = 2)
    public void test() {
        this.driver.get().findElement(By.id("user-name")).sendKeys("standard_user");
        this.driver.get().findElement(By.id("password")).sendKeys("secret_sauce");
        this.driver.get().findElement(By.id("login-button"));
    }
}

第一次测试运行正常,但第二次测试失败并出现错误

java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebDriver.findElement(org.openqa.selenium.By)" because the return value of "java.lang.ThreadLocal.get()" is null

    at LoginTest.test(LoginTest.java:36)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
    at java.base/java.lang.reflect.Method.invoke(Method.java:577)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:139)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:677)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:221)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:962)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:194)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:148)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
    at org.testng.internal.thread.ThreadUtil.lambda$execute$0(ThreadUtil.java:58)
    at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)

因此,驱动程序在第二次测试中没有正确设置。 为什么? 我该如何解决?

如果我不使用 ThreadLocal,我的测试会相互混合。 例如,第二次测试运行的密码设置在第一个浏览器的密码字段中。 通过方法案例与驱动程序并行工作的正确方法是什么? 先感谢您

当您在setup中使用此行时this.driver = new ThreadLocal<WebDriver>(); 当第二个线程启动时,第二个测试用新值覆盖threadlocal

因此,当第一个线程试图获取它之前保存到threadlocal的值时,它无法找到,因为此时this.driver字段引用了第二个线程创建的对象。

要解决此问题,您需要在字段声明中初始化threadlocal ,因此您的代码如下所示:

PS - 将该字段设为静态也是值得的,这样您还可以处理为每个测试创建新的LoginTest实例的情况(但是我不确定 TestNg 是否会出现这种情况)。

public class LoginTest {

    static ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>();

    @BeforeMethod()
    public void setup() {
        WebDriverManager.chromedriver().setup();
        WebDriver webDriver = new ChromeDriver();
        webDriver.manage().window().maximize();
        webDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        webDriver.get("https://www.saucedemo.com/");
        driver.set(webDriver);
    }

    @Test(invocationCount = 2, threadPoolSize = 2)
    public void test() {
        driver.get().findElement(By.id("user-name")).sendKeys("standard_user");
        driver.get().findElement(By.id("password")).sendKeys("secret_sauce");
        driver.get().findElement(By.id("login-button"));
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM