我参与过Selenium和TestNG。但我不是专家。我试着寻找一个合适的答案,但找不到。因此请求帮助。
我有一个初始化类,如下所示。
public class Initialization {
private static Logger logger = Logger.getLogger(Initialization.class);
private WebDriver driver;
@BeforeTest
public void intiDriver() throws MalformedURLException {
logger.debug("Creating driver");
DesiredCapabilities dcap = DesiredCapabilities.firefox();
driver = new RemoteWebDriver(new URL("http://127.0.0.1:4444/wd/hub"), dcap);
logger.debug("Driver created");
}
@AfterTest
public void closeDriver(){
logger.debug("Quitting driver");
if(driver != null){
driver.close();
driver.quit();
logger.debug("Driver destroyed");
}
}
public WebDriver getDriver() {
return driver;
}
}
然后我有2个测试用例类文件,它扩展了上面的类文件(如下所示)
public class SampleTestCase1 extends Initialization {
@Test
public void sampleTest1(){
System.out.println("getDriver1: "+ getDriver());
getDriver().get("http://www.google.com");
}
@Test
public void sampleTest2(){
System.out.println("getDriver2: "+ getDriver());
getDriver().get("http://www.bing.com");
}
}
public class SampleTestCase2 extends Initialization {
@Test
public void sampleTest3(){
System.out.println("getDriver3: "+ getDriver());
getDriver().get("https://en.wikipedia.org/wiki/Main_Page");
}
@Test
public void sampleTest4(){
System.out.println("getDriver4: "+ getDriver());
getDriver().get("http://www.rediff.com/");
}
}
我观察到sampleTest3和sampleTest4测试用例没有被执行,因为getDriver()返回null。我相信在执行sampleTest1和smapleTest2之后驱动程序实例会被破坏。我使用了@afterTest注释,因此理想情况下,在执行所有@Test后,驱动程序实例应该被销毁。
我不知道出了什么问题。有人可以帮忙吗?。
堆栈追踪:
java.lang.NullPointerException
at Sample.SampleTestCase2.sampleTest3(SampleTestCase2.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:643)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
at org.testng.TestRunner.privateRun(TestRunner.java:782)
at org.testng.TestRunner.run(TestRunner.java:632)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:366)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:361)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:319)
at org.testng.SuiteRunner.run(SuiteRunner.java:268)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1244)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.run(TestNG.java:1064)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:74)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
答案 0 :(得分:2)
TestNG不是JUnit。不要错过@BeforeTest/AfterTest
和@BeforeMethod/AfterMethod
。
@BeforeTest: 带注释的方法将在任何测试方法之前运行 属于标签内的类是运行的。
@AfterTest: 在所有测试方法归属后,将运行带注释的方法 标签内的类已经运行。
@BeforeMethod: 带注释的方法将在每个测试方法之前运行。
@AfterMethod: 带注释的方法将在每种测试方法之后运行。
答案 1 :(得分:1)
你可以这样做:
分别将注释更改为@BeforeClass和@AfterClass
更改您的xml。将您的课程置于测试标记
希望,你理解我的意思。
答案 2 :(得分:0)
您必须了解的是在以下配置中使用xml文件执行测试时的TestNG执行顺序
<suite name="Suite1" verbose="1">
<test name="Sample Test">
<classes>
<class name="Sample.SampleTestCase1" />
<class name="Sample.SampleTestCase2" />
</classes>
</test>
</suite>
订单:
@BeforeTest in SampleTestCase1 extends Initialization
sampleTest1
sampleTest2
sampleTest3
sampleTest4
@AfterTest in SampleTestCase1 extends Initialization
忽略:
@BeforeTest in SampleTestCase2 extends Initialization
@AfterTest in SampleTestCase2 extends Initialization
这是因为您已将SampleTestCase1和SampleTestCase2添加为<classes>
到TestNG xml文件中的<test>
。这意味着SampleTestCase1和SampleTestCase2是名为Sample Test
的单个测试的一部分。虽然这两个类都扩展了Initialization类(你会期望为每个测试类调用@BeforeTest和@AfterTest),但TestNG只能看到1个@BeforeTest和1个@AfterTest以及4个测试方法。
SampleTest1和SampleTest2获取驱动程序,因为调用了@BeforeTest in SampleTestCase1 extends Initialization
。 sampleTest3和sampleTest4方法getDriver()方法返回null,因为永远不会调用@BeforeTest in SampleTestCase2 extends Initialization
。
如果你在@BeforeTest中添加一个sysout来打印&#34;开始&#34;和@AfterTest打印&#34;停止&#34;你会在控制台中找到以下证明以下内容。
start
getDriver1: FirefoxDriver: firefox on WINDOWS (8573d6f7-fa66-45bc-9754-1145f5834b82)
getDriver2: FirefoxDriver: firefox on WINDOWS (8573d6f7-fa66-45bc-9754-1145f5834b82)
getDriver3: null
getDriver4: null
stop
===============================================
Suite1
Total tests run: 4, Failures: 2, Skips: 0
===============================================
我将添加众多解决方案中的一个,使其作为单独的答案工作,因为这个答案已经非常冗长!!
答案 3 :(得分:0)
答案继续......
如果您想打开浏览器并仅关闭一次,请在初始化代码中将驱动程序和getDriver()方法设为静态。
public class Initialization {
private static WebDriver driver;
@BeforeTest
public void intiDriver() {
driver = new FirefoxDriver();
System.out.println("start");
}
@AfterTest
public void closeDriver() {
driver.quit();
System.out.println("stop");
}
public static WebDriver getDriver() {
return driver;
}
}
的testng.xml
<suite name="Suite1" verbose="1">
<test name="Sample Test">
<classes>
<class name="Sample.SampleTestCase1" />
<class name="Sample.SampleTestCase2" />
</classes>
</test>
</suite>
如果您打开浏览器多次(1个浏览器/测试类),则可以保留原始的Initialization类(不需要静态驱动程序),只修改TestNG XML文件以包含2个测试。
<suite name="Suite1" verbose="1">
<test name="Sample Test1">
<classes>
<class name="Sample.SampleTestCase1" />
</classes>
</test>
<test name="Sample Test2">
<classes>
<class name="Sample.SampleTestCase2" />
</classes>
</test>
</suite>