TestNG - parallel Test execution, WebDriver nullpointer
TestNG - parallel Test execution, WebDriver nullpointer
I am sure it has to be an easy one to solve but nothing comes to my mind at this moment, here is the situation.
I have one Singleton class (DriverFactory.class) to set and retrieve a ThreadLocal Object.
Two test classes running in parallel (FirstTestClass), (SecondTestClass)
and the third TestListenerAdapter class with a method where I want to use the actual running WebDriver instance(it should be bound to the Thread) but here I am getting null pointer exception even if, here is the code
import config.DriverFactory;
import org.junit.Assert;
import org.testng.annotations.Test;
import org.openqa.selenium.WebDriver;
public class SecondTestClass {
WebDriver driver;
public SecondTestClass()throws Exception{
DriverFactory.getInstance().setDriver();
driver = DriverFactory.getInstance().getDriver();;
}
@Test
public void testInSecondClass() {
System.out.println("n THREAD ID: " + Thread.currentThread().getId() + " " + "n Name: " + Thread.currentThread().getName());
driver.get("https://www.allsaints.com");
System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());
Assert.assertTrue(false);
}
}
package testParallel;
import config.DriverFactory;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
public class FirstTestClass {
WebDriver driver;
public FirstTestClass()throws Exception{
DriverFactory.getInstance().setDriver();
driver = DriverFactory.getInstance().getDriver();;
}
@Test
public void testInFirstClass() throws Exception{
System.out.println("n THREAD ID: " + Thread.currentThread().getId() + " " + "n Name: " + Thread.currentThread().getName());
DriverFactory.getInstance().setDriver();
driver = DriverFactory.getInstance().getDriver();;
driver.get("https://pl.wikipedia.org");
System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());
}
}
package config;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class DriverFactory {
private static DriverFactory instance = null;
public ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
private DriverFactory() {}
@SuppressWarnings("varargs")
public static DriverFactory getInstance() {
if (instance == null) {
instance = new DriverFactory();
}
return instance;
}
public final void setDriver() throws Exception {
System.setProperty("webdriver.gecko.driver", "E:\Projects\allsaints\tess\drivers\geckodriver.exe");
webDriver.set(new FirefoxDriver());
}
public WebDriver getDriver() throws Exception {
return webDriver.get();
}
}
import config.DriverFactory;
import org.openqa.selenium.WebDriver;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
public class testSetup extends TestListenerAdapter {
@Override
public void onTestFailure(ITestResult tr) {
System.out.println(
"n THREAD ID: " + Thread.currentThread().getId() + " " +
"n Name: " + Thread.currentThread().getName()
);
WebDriver driver;
try {
driver = DriverFactory.getInstance().getDriver();
System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());
} catch (Exception e) {
e.printStackTrace();
}
super.onTestFailure(tr);
}
}
<?xml version="1.0"?>
<suite name="All Test Suite" parallel="tests" thread-count="5">
<listeners>
<listener class-name="testParallel.testSetup"/>
</listeners>
<test verbose="3" preserve-order="true" name="test1">
<classes>
<class name="testParallel.FirstTestClass"/>
</classes>
</test>
<test name="test2">
<classes>
<class name="testParallel.SecondTestClass"/>
</classes>
</test>
</suite>
Console output
class testParallel.FirstTestClass THREAD ID: 22 Name: TestNG
class testParallel.SecondTestClass THREAD ID: 23 Name: TestNG
class testParallel.testSetup THREAD ID: 23 Name: TestNG
java.lang.NullPointerException at
testParallel.testSetup.onTestFailure(testSetup.java:21) at
org.testng.internal.Invoker.runTestListeners(Invoker.java:1895) at
org.testng.internal.Invoker.runTestListeners(Invoker.java:1879) at
org.testng.internal.Invoker.invokeMethod(Invoker.java:778) at
org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) at
org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231) at
org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at
org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767) at
org.testng.TestRunner.run(TestRunner.java:617) at
org.testng.SuiteRunner.runTest(SuiteRunner.java:334) at
org.testng.SuiteRunner.access$000(SuiteRunner.java:37) at
org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:368) at
org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64) at
java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745) CURRENT URL IS
:https://pl.wikipedia.org/wiki/Wikipedia:Strona_g%C5%82%C3%B3wna
1 Answer
1
In Listeners, we can't directly access other class instance.Since,It will start listen when the execution begins. If we need to get some particular class instance, then we can access through TestNG Listeners(ITestResult) as below and all your test class should be inherited the DriverFactory class .
ITestResult
DriverFactory
Listener Class Code:
public class testSetup extends TestListenerAdapter {
@Override
public void onTestFailure(ITestResult tr) {
System.out.println(
"n THREAD ID: " + Thread.currentThread().getId() + " " +
"n Name: " + Thread.currentThread().getName()
);
Object currentClass=tr.getInstance();
WebDriver driver;
try {
driver =((DriverFactory) currentClass).getDriver();
System.out.println("CURRENT URL IS :" + driver.getCurrentUrl());
} catch (Exception e) {
e.printStackTrace();
}
super.onTestFailure(tr);
}
}
Test Class 1:
public class FirstTestClass extends DriverFactory {
WebDriver driver;
Test Class 2:
public class SecondTestClass extends DriverFactory {
WebDriver driver;
Glad to know, it is helpful. Please consider to accept the answer by clicking on the tick mark below the down arrow button.
– Subburaj
2 days ago
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thanks, really appreciate :)
– 1. 618
2 days ago