java - TestNG - 并行测试执行,WebDriver nullpointer
问题描述
我确信它必须是一个容易解决的问题,但此刻我什么都没有想到,情况就是这样。
我有一个单例类 (DriverFactory.class) 来设置和检索 ThreadLocal 对象。两个并行运行的测试类(FirstTestClass),(SecondTestClass)和第三个TestListenerAdapter类,其中我想使用实际运行的WebDriver实例(它应该绑定到线程)但是在这里我得到空指针异常,即使, 这是代码
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>
控制台输出
类 testParallel.FirstTestClass 线程 ID:22 名称:TestNG
类 testParallel.SecondTestClass 线程 ID:23 名称:TestNG
类 testParallel.testSetup 线程 ID:23 名称: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) 在 org.testng.internal.Invoker.invokeMethod(Invoker.java:778) 在 org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901) 在 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) 在 org.testng.TestRunner.run(TestRunner.java:617) 在 org.testng.SuiteRunner.runTest(SuiteRunner.java:334) 在 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)在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java :617) 在 java.lang.Thread.run(Thread.java:745) 当前 URL 是:concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745) 当前 URL 是:concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745) 当前 URL 是:https://pl.wikipedia.org/wiki/Wikipedia:Strona_g%C5%82%C3%B3wna
解决方案
在 Listeners 中,我们不能直接访问其他类实例。因为,它会在执行开始时开始监听。如果我们需要获取某个特定的类实例,那么我们可以通过ITestResult
如下所示的 TestNG Listeners() 访问,并且您的所有测试类都应该继承DriverFactory
该类。
侦听器类代码:
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);
}
}
测试类 1:
public class FirstTestClass extends DriverFactory {
WebDriver driver;
测试类 2:
public class SecondTestClass extends DriverFactory {
WebDriver driver;
推荐阅读
- c# - 在 Unity 中将 Sprite 数组更改为 GameObject 数组
- javascript - 使用来自 Web 服务的 SAPUI5 和 SOAP 请求和响应
- python - Python RecursionError : Pandas.eval() 的简单操作崩溃
- jenkins - Jenkins 没有从 Workspace 中的 Katalon 测试创建 JUnit 测试报告
- r - 如何使用 R 删除数据框中的第一行和最后 N 行?
- java - 我正在尝试制作一个接受两个数字并在两者之间找到素数、偶数和奇数的程序
- html - 内联时对齐文本
- ibm-cloud - 使用“请求客户端证书”配置 IBM Cloud 应用程序
- batch-file - RENAME 函数不在批处理脚本中重命名
- javascript - Jquery 在 td 中创建带有字典条目的 html 表