簡體   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