package selenium.setup;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Parameters;
public class SeleniumBaseTest {
protected final static ThreadLocal<WebDriver> webDriver = new ThreadLocal<>();
@BeforeClass
@Parameters({"browser","baseURL"})
public void Setup(String browser, String baseURL) throws Exception{
webDriver.set(BrowserManager.doBrowserSetup(browser));
System.out.println("Before Test Thread ID: "+Thread.currentThread().getId());
//get URL
webDriver.get().get(baseURL);
webDriver.get().manage().window().maximize();
webDriver.get().manage().deleteAllCookies();
webDriver.get().manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
@AfterClass
public void tearDown(){
webDriver.get().quit();
System.out.println("After Test Thread ID: "+Thread.currentThread().getId());
webDriver.remove();
}
}
`package selenium.trials;
import java.time.Duration;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.testng.ITestContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import selenium.setup.SeleniumBaseTest;
import selenium.utils.WebElementUtility;
public class SeleniumDragnDrop extends SeleniumBaseTest{
Logger logger;
WebDriver driver;
@BeforeTest(alwaysRun=true)
public void beforeTest(ITestContext testContext){
logger = LogManager.getLogger(this.getClass());
driver = webDriver.get();
logger.info("In dragNDrop beforeTest: Thread ID: "+Thread.currentThread().getId());
}
@Test
public void dragNDrop() throws InterruptedException {
logger.info("In dragNDrop Thread ID: "+Thread.currentThread().getId());
WebElementUtility.clickOn(driver,driver.findElement(By.linkText("Drag and Drop")), Duration.ofSeconds(15));
WebElement source = driver.findElement(By.id("column-a"));
WebElement dest = driver.findElement(By.id("column-b"));
Actions action = new Actions(driver);
action.dragAndDrop(source, dest).build().perform();
logger.info("After dragNDrop Thread ID: "+Thread.currentThread().getId());
}
@AfterTest
public void tearDown() {
logger.info("In dragNDrop tearDown : Thread ID: "+Thread.currentThread().getId());
}
}`
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestSuite" thread-count="2" parallel="classes">
<parameter name="browser" value="Chrome"/>
<parameter name="baseURL" value="https://the-internet.herokuapp.com"/>
<test name="SeleniumTrials" preserve-order="true">
<!--
<packages>
<package name="selenium.trials"/>
</packages> -->
<classes>
<class name="selenium.trials.SeleniumDragnDrop"/>
<class name="selenium.trials.SeleniumAlerts"/>
</classes>
</test>
</suite>
当我运行 testngSuite 时,父类 - SeleniumBaseTest.java 中的 @BeforeClass 方法 setup() 被执行。但是,子类 - SeleniumDragnDrop.java 中的 @BeforeTest 方法不会执行。 因此测试失败,因为驱动程序变量未初始化
我在父类 @BeforeClass 方法中初始化 ThreadLocal
我可以在这篇文章中找到答案 - TestNG 中 BeforeClass 和 BeforeTest 之间的区别。
@BeforeTest 在@BeforeClass 之前运行。因此,驱动程序变量为 null,因为它是在 BeforeTest 之后运行的 BeforeClass 中初始化的。