问题
I trying to make a test design using Selenium and TestNG, I put each @Test in a separate class, and using once @BeforeSuite & @AfterSuite for all classes, the reason is:
- The code is easy to maintain
- Data Driven, in order to be able to choose which classes to run through the
xml
file.
Then what I think is how I only login once and the session can be used by all subsequent tests, what I've done so far is:
Base class:
public class Base {
protected static WebDriver driver;
@BeforeSuite
public void setup() {
System.setProperty("webdriver.chrome.driver", "/Users/.../chromedriver");
driver = new ChromeDriver();
}
@AfterSuite
public void tearDown() {
driver.quit();
}
}
LoginApps class:
public class LoginApps extends Base{
@Test(groups= {"logintest"})
@Parameters({"data"})
public void loginApps(String data) {
driver.get("https://TheUrl.com/");
//some code here
}
}
Case1 class:
public class Case1 extends Base{
@Test(dependsOnGroups= {"logintest"})
@Parameters({"data"})
public void case1(String data) {
driver.get("https://TheUrl.com/");
//some code here
}
}
Note : The above code fine work if it is run with single <test>
in suite.
The problem is if it is run parallel like the following xml
configuration.
testng.xml:
<suite name="SuiteTest" parallel="tests" thread-count="2">
<test name="Test1">
<parameter name="data" value="data1"></parameter>
<classes>
<class name="com.main.LoginApps"/>
<class name="com.main.Case1"/>
.....
More class
</classes>
</test>
<test name="Test2">
<parameter name="data" value="data2"></parameter>
<classes>
<class name="com.main.LoginApps"/>
<class name="com.main.Case1"/>
.....
More class
</classes>
</test>
</suite>
The code runs by creating driver
instance just once, and the both <test>
runs overlapping in the same session. I think this is because of the way I declare driver
as static
in the Base class. But if I remove the static
, it will make matters worse, still creating driver
instance just once and the code only run the first @Test
(in this case only LoginApps), all subsequent tests will get a NullPointerException
exception.
I use TestNG v7.0.0 with Maven :
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0</version>
<scope>compile</scope>
</dependency>
To run the design that I imagined in parallel, how I can fix it?
回答1:
Create driver with thread safety to ensure both times driver session is unique.
public class ThreadLocalDriver {
private static ThreadLocal<WebDriver> threadLocalDriver = new ThreadLocal<>();
public synchronized static void setTLDriver(WebDriver driver) {
threadLocalDriver.set(driver);
}
public synchronized static WebDriver getTLDriver() {
return threadLocalDriver.get();
}
}
public class BaseClass {
@BeforeMethod
public void setup (String deviceName, String platformVersion) throws IOException {
DesiredCapabilities caps = new DesiredCapabilities();
// Add caps here
ThreadLocalDriver.setTLDriver(new ChromeDriver(caps));
}
@AfterMethod
public synchronized void teardown(){
ThreadLocalDriver.getTLDriver().quit();
}
}
来源:https://stackoverflow.com/questions/61409468/how-to-create-a-correct-parallel-selenium-execution-using-beforesuite-and-each