1

套件 xml 文件

我正在尝试使用@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 类

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();
    }
}
4

1 回答 1

2

问题在于您的测试代码。@BeforeSuite在 TestNG 中设计为每个<suite>. 您将该逻辑与继承相结合,然后依靠该@BeforeSuite方法来初始化您的 WebDriver。所以它会在你的第一堂课上做到这一点,从第二堂课开始<suite>,TestNG 不会调用. 相反,您应该考虑将实现作为侦听器,然后将其连接到您的测试执行中。@BeforeSuiteNullPointerExceptionISuiteListener

您的测试现在将开始依赖以这种方式创建的 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方法都不会使浏览器崩溃(或)导致浏览器实例被清理(这适用于处理网格设置时,您可能最终让浏览器闲置一段时间导致节点从服务器端清理浏览器)。如果你造成了任何这种情况,那么你的测试将会失败并出现意想不到的结果。
于 2017-09-20T17:17:27.050 回答