简体   繁体   中英

TestNG NullPointerException with Selenium and Page Object Pattern

I'm getting NullPointerException when trying to create test by extending abstract class and test class. Error:

java.lang.NullPointerException at pages.UserRegistrationPage.fillName(UserRegistrationPage.java:61) at UserRegistrationpageTest.fillName(UserRegistrationpageTest.java:26) 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:124) at org.testng.internal.Invoker.invokeMethod(Invoker.java:571) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:707) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:979) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109) at org.testng.TestRunner.privateRun(TestRunner.java:648) at org.testng.TestRunner.run(TestRunner.java :505) at org.testng.SuiteRunner.runTest(SuiteRunner.java:455) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415) at org.testng.SuiteRunner.run(SuiteRunner.java:364) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1187) at org.testng.TestNG.runSuitesLocally(TestNG.java:1116) at org.testng.TestNG.runSuites(TestNG.java:1028) at org.testng.TestNG.run(TestNG.java:996) at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72) at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

The driver gets initialized, opens the test page and exception is thrown when trying to fill in the field. My classes:

    public abstract class AbstractPage {
        private WebDriver driver;
        public AbstractPage(WebDriver driver){
            this.driver = driver;
        }
    }

    public class UserRegistrationPage extends AbstractPage{

        @FindBy(id = "input-firstname")
        private WebElement firstName;

        @FindBy(id = "input-lastname")
        private WebElement lastName;

        @FindBy(id = "input-email")
        private WebElement email;

        @FindBy(id = "input-telephone")
        private WebElement telephone;

        @FindBy(xpath = "//*[@id=\"input-fax\"]")
        private WebElement fax;

        @FindBy(id = "input-address-1")
        private WebElement address;

        @FindBy(id = "input-city")
        private WebElement city;

        @FindBy(id = "input-postcode")
        private WebElement postcode;

        @FindBy(id = "input-country")
        private WebElement country;

        @FindBy(id = "input-zone")
        private WebElement zone;

        @FindBy(id = "input-password")
        private WebElement password;

        @FindBy(id = "input-confirm")
        private WebElement passwordConfirm;

        @FindBy(css = "#content input[type=\"checkbox\"]:nth-child(2)")
        private WebElement agreeCheckbox;

        @FindBy (xpath = "//*[@id=\"content\"]/form/div/div/input[2]")
        private WebElement submitButton;

        public UserRegistrationPage(WebDriver driver) {
            super(driver);
        }


        public void fillName(String name){
            this.firstName.sendKeys(name);
        }
    }

public abstract class AbstractTest {

    protected WebDriver driver;
    @BeforeSuite
    public void setUpDriver(){
        driver = new FirefoxDriver();
    }
}

public class UserRegistrationpageTest extends AbstractTest{

    private UserRegistrationPage userRegistrationPage = new UserRegistrationPage(driver);


    @BeforeTest
    void openURL(){
        driver.get("http://88.119.151.54/opencartone/index.php?route=account/register");
    }

    @AfterTest
    void closeBrowser(){
        driver.quit();
    }

    @Test
    void fillName(){
        userRegistrationPage.fillName("John");
    }

}

What I'm missing here?

Reason being : 'driver' member of 'UserRegistration' page remains null , when you reach at 'userRegistrationPage.fillName("John")' line .

see this

在此处输入图片说明

This is because @BeforeSuite (method lying inside 'AbstractTest' test gets called after constructor of UserRegistrationPage gets called . So sequence right now is

1) Constructor of AbstractPage . (here your driver is null)

2) Constructor of UserRegistrationPage . (here your driver is null)

3) @BeforeSuite of AbstractTest. (here your driver will not be null , but till this time you have already initialized object of 'UserRegistrationPage' using line in 'UserRegistrationpageTest' class

private UserRegistrationPage userRegistrationPage = new UserRegistrationPage(driver);

To solve this , change initialization location of 'UserRegistrationPage' object inside 'openURL' as shown below

在此处输入图片说明

When using 'PageFactory' you need to initialize the WebElements . add it to the 'AbstractPage'

public AbstractPage(WebDriver driver) {
    this.driver = driver;
    PageFactory.initElements(driver, this);
}

The UserRegistrationPage which extends the AbstractPage uses the WebDriver instance driver . Hence you need to define the constructor as :

WebDriver driver;

//constructor
public UserRegistrationPage(WebDriver driver)
{
    this.driver=driver;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM