我尝试使用@beforeSuite和@AfterSuite在一个浏览器实例中运行我的测试。但它运行第一个第一个测试类但在第二个类时失败并带有空指针异常。
以下是我的代码:
LaunchBrowser.java类
public class LaunchBrower {
protected WebDriver driver;
public WebDriver getDriver() {
return driver;
}
@Parameters({ "browserType", "appURL" })
@BeforeSuite
public void setUp(@Optional String browsertype, @Optional String appURL) {
System.out.println("Launching google chrome with new profile..");
driver = getBrowserType(browsertype);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.navigate().to(appURL);
}
private WebDriver getBrowserType(String browserType) {
if (driver == null ) {
if (browserType.equalsIgnoreCase("chrome")) {
return new ChromeDriver();
}
else if (browserType.equalsIgnoreCase("InternetExplorer")) {
return new InternetExplorerDriver();
}
}
return driver;
}
@AfterSuite
public void tearDown() {
if (driver != null)
driver.quit();
}
}
LoginPageTest类
public class LoginPageTest extends LaunchBrower {
protected WebDriver driver;
private LoginPage loginpage;
private MyProfile profilepage;
Logger log = Logger.getLogger("Results:");
@BeforeClass(alwaysRun = true)
public void setUp() {
loginpage = PageFactory.initElements(getDriver(), LoginPage.class);
//loginpage = new LoginPage(driver);
//driver=getDriver();
}
@Test(groups = "LoginPage")
public void verifyLogin() throws InterruptedException {
//LoginPage login = new LoginPage(driver);
System.out.println("Sign In functionality details...");
//System.out.println("Sign In functionality details seee...");
Thread.sleep(10000);
//login.enterUserName("11111111");
Assert.assertEquals("11111111",loginpage.enterUserName("11111111"));
log.debug("Correct Username Pass");
//System.out.println("Correct username...");
Assert.assertEquals("fe9245db",loginpage.enterPassword("fe9245db"));
log.debug("Correct Password Pass");
loginpage.clickOnLogin();
log.debug("Login Pass");
}
}
MyProfileTest java class
public class MyProfileTest extends LaunchBrower {
protected WebDriver driver;
private MyProfile profilepage;
@BeforeClass(alwaysRun = true)
public void setUp() {
profilepage = PageFactory.initElements(getDriver(), MyProfile.class);
//driver=getDriver();
}
@Test(groups = "Myprofile")
public void verifyMyprofile() throws InterruptedException {
System.out.println("My profile test...");
//MyProfile profile = new MyProfile(driver);
profilepage.ClickToggleLink();
profilepage.ClickMyProfile();
}
}
答案 0 :(得分:1)
问题在于您的测试代码。 @BeforeSuite
在TestNG中设计为每<suite>
仅调用一次。您将该逻辑与继承相结合,然后依靠@BeforeSuite
方法初始化WebDriver。因此,它会在<suite>
中从第二课开始为第一堂课开始,TestNG将不会调用@BeforeSuite
,因此您的第二课开始时会看到NullPointerException
。
您应该考虑依赖ISuiteListener
实现作为侦听器,然后将其连接到测试执行中。
您的测试现在将开始依赖以这种方式创建的Web驱动程序,然后使用它。
请确保您使用的是TestNG 6.12或更高版本(目前尚不存在)。
这是一个完整的示例,展示了所有这一切。
我的测试类的基类如下所示
package com.rationaleemotions.stackoverflow.qn46323434;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Listeners;
@Listeners(BrowserSpawner.class)
public class MyBaseClass {
protected void launchPage(String url) {
RemoteWebDriver driver = BrowserSpawner.getDriver();
driver.get(url);
System.err.println("Page Title :" + driver.getTitle());
}
}
我在此示例中使用的测试类如下所示
package com.rationaleemotions.stackoverflow.qn46323434;
import org.testng.annotations.Test;
public class MyFirstTestCase extends MyBaseClass {
@Test
public void testGooglePage() {
launchPage("http://www.google.com");
}
@Test
public void testFaceBookPage() {
launchPage("http://www.facebook.com");
}
}
package com.rationaleemotions.stackoverflow.qn46323434;
import org.testng.annotations.Test;
public class MySecondTestCase extends MyBaseClass {
@Test
public void testHerokkuPage() {
launchPage("https://the-internet.herokuapp.com/");
}
@Test
public void testStackOverFlowPage() {
launchPage("http://stackoverflow.com/");
}
}
ISuiteListener实现如下所示
package com.rationaleemotions.stackoverflow.qn46323434;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ISuite;
import org.testng.ISuiteListener;
import org.testng.ITestResult;
import org.testng.Reporter;
public class BrowserSpawner implements ISuiteListener {
private static final String DRIVER = "driver";
@Override
public void onStart(ISuite suite) {
RemoteWebDriver driver;
String browserType = suite.getParameter("browserType");
switch (browserType) {
case "chrome":
driver = new ChromeDriver();
break;
default:
driver = new FirefoxDriver();
}
suite.setAttribute(DRIVER, driver);
}
@Override
public void onFinish(ISuite suite) {
Object driver = suite.getAttribute(DRIVER);
if (driver == null) {
return;
}
if (!(driver instanceof RemoteWebDriver)) {
throw new IllegalStateException("Corrupted WebDriver.");
}
((RemoteWebDriver) driver).quit();
suite.setAttribute(DRIVER, null);
}
public static RemoteWebDriver getDriver() {
ITestResult result = Reporter.getCurrentTestResult();
if (result == null) {
throw new UnsupportedOperationException("Please invoke only from within an @Test method");
}
Object driver = result.getTestContext().getSuite().getAttribute(DRIVER);
if (driver == null) {
throw new IllegalStateException("Unable to find a valid webdriver instance");
}
if (! (driver instanceof RemoteWebDriver)) {
throw new IllegalStateException("Corrupted WebDriver.");
}
return (RemoteWebDriver) driver;
}
}
我使用的套件xml文件如下所示
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="46323434_Suite" parallel="false" verbose="2">
<parameter name="browserType" value="chrome"/>
<test name="46323434_test1">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn46323434.MyFirstTestCase"/>
</classes>
</test>
<test name="46323434_test2">
<classes>
<class name="com.rationaleemotions.stackoverflow.qn46323434.MySecondTestCase"/>
</classes>
</test>
</suite>
当你运行它时,输出将如下所示
...
... TestNG 6.12 by Cédric Beust (cedric@beust.com)
...
Starting ChromeDriver 2.32.498537 (cb2f855cbc7b82e20387eaf9a43f6b99b6105061) on port 45973
Only local connections are allowed.
log4j:WARN No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies).
log4j:WARN Please initialize the log4j system properly.
Sep 20, 2017 10:36:41 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Page Title :Facebook – log in or sign up
Page Title :Google
PASSED: testFaceBookPage
PASSED: testGooglePage
===============================================
46323434_test1
Tests run: 2, Failures: 0, Skips: 0
===============================================
Page Title :The Internet
Page Title :Stack Overflow - Where Developers Learn, Share, & Build Careers
PASSED: testHerokkuPage
PASSED: testStackOverFlowPage
===============================================
46323434_test2
Tests run: 2, Failures: 0, Skips: 0
===============================================
===============================================
46323434_Suite
Total tests run: 4, Failures: 0, Skips: 0
===============================================
这里要记住的最重要的事情是:
ISuiteListener
实施完成。<suite>
依赖一个浏览器实例),您将永远无法并行运行测试。所有测试都应严格按顺序进行。@Test
方法都不会使浏览器崩溃(或)导致清理浏览器实例(这在您处理网格设置时适用,您可能最终会离开浏览器空闲一段时间导致节点从服务器端清除浏览器)。如果您导致任何此类问题,那么您的测试将会失败并产生意外结果。