Selenium 使用带有Cucumber的页面对象模型时出现空指针异常

Selenium 使用带有Cucumber的页面对象模型时出现空指针异常,selenium,Selenium,我使用了页面对象模型设计模式和Cucumber。为此,我创建了两个名为abstractPage和loginPage的页面,但在运行脚本时,即使我已经使用pagefactory初始化webelements,也会出现空指针异常,请查看以下代码: 摘要页面: public class abstractPage { protected WebDriver driver; public static loginPage lpOBJ; public void openBrowse

我使用了页面对象模型设计模式和Cucumber。为此,我创建了两个名为
abstractPage
loginPage
的页面,但在运行脚本时,即使我已经使用pagefactory初始化webelements,也会出现空指针异常,请查看以下代码:

摘要页面:

public class abstractPage {

    protected WebDriver driver;
    public static loginPage lpOBJ;

    public void openBrowsernURLhit() {
        driver=new FirefoxDriver();
        driver.get("http://www.facebook.com");
        PageFactory.initElements(driver, loginPage.class);
    }
}
public class loginPage extends abstractPage {

    @FindBy(name = "email")
    public WebElement username;

    @FindBy(name = "pass")
    public WebElement password;

    @FindBy(id = "u_0_2")
    public WebElement loginButon;

    public void loginIntoApp() {

        String url=driver.getCurrentUrl();
        System.out.println("the url is::::::::::::::::"+url);
        username.sendKeys("testuser");
        password.sendKeys("123");
    }

    public void clicklogn() {
        loginButon.click();
    }
}
@RunWith(Cucumber.class)
@CucumberOptions(
        features= "features", 
        glue= {"stepDefination"},
        plugin= {"html:target/cucumber-html-report"}
        )

public class TestRunner {

}
登录页面:

public class abstractPage {

    protected WebDriver driver;
    public static loginPage lpOBJ;

    public void openBrowsernURLhit() {
        driver=new FirefoxDriver();
        driver.get("http://www.facebook.com");
        PageFactory.initElements(driver, loginPage.class);
    }
}
public class loginPage extends abstractPage {

    @FindBy(name = "email")
    public WebElement username;

    @FindBy(name = "pass")
    public WebElement password;

    @FindBy(id = "u_0_2")
    public WebElement loginButon;

    public void loginIntoApp() {

        String url=driver.getCurrentUrl();
        System.out.println("the url is::::::::::::::::"+url);
        username.sendKeys("testuser");
        password.sendKeys("123");
    }

    public void clicklogn() {
        loginButon.click();
    }
}
@RunWith(Cucumber.class)
@CucumberOptions(
        features= "features", 
        glue= {"stepDefination"},
        plugin= {"html:target/cucumber-html-report"}
        )

public class TestRunner {

}
然后我有一个类
stepDefinition
,在这里我调用上面的登录类方法。浏览器打开良好,url被命中,但当它进入l
OginToApp()
方法时,它会在第一行本身抛出异常

public class SmokeTest {

    @Given("^Open Firefox and start application$")
    public void Open_Firefox_and_start_application() throws Throwable {

        abstractPage obj = new abstractPage();
        obj.openBrowsernURLhit();
    }

    @When("^I enter valid \"([^\"]*)\" and \"([^\"]*)\"$")
    public void I_enter_valid_username_and_password(String arg1, String arg2) throws Throwable {

        loginPage lpobj = new loginPage();
        lpobj.loginIntoApp();
    }

    @Then("^user should be able to login successfully$")
    public void user_should_be_able_to_login_successfully() throws Throwable {

        loginPage lpobj = new loginPage();
        lpobj.clicklogn();
    }
}
我还有一个TestRunner类,其中我粘贴了我的步骤定义:

public class abstractPage {

    protected WebDriver driver;
    public static loginPage lpOBJ;

    public void openBrowsernURLhit() {
        driver=new FirefoxDriver();
        driver.get("http://www.facebook.com");
        PageFactory.initElements(driver, loginPage.class);
    }
}
public class loginPage extends abstractPage {

    @FindBy(name = "email")
    public WebElement username;

    @FindBy(name = "pass")
    public WebElement password;

    @FindBy(id = "u_0_2")
    public WebElement loginButon;

    public void loginIntoApp() {

        String url=driver.getCurrentUrl();
        System.out.println("the url is::::::::::::::::"+url);
        username.sendKeys("testuser");
        password.sendKeys("123");
    }

    public void clicklogn() {
        loginButon.click();
    }
}
@RunWith(Cucumber.class)
@CucumberOptions(
        features= "features", 
        glue= {"stepDefination"},
        plugin= {"html:target/cucumber-html-report"}
        )

public class TestRunner {

}
但是在运行上面的脚本时,我总是在ginToApp()方法的第一行中得到NullPointerException变量未在登录类中初始化,尽管我继承了asbtract类,在该类中我正在实例化驱动程序,因此它会抛出空指针。请查看我在这里做错了什么。错误如下:

1个场景([31m1失败[0m) 3个步骤([31m1失败[0m,[36m1跳过[0m,[32m1通过[0m”) 0m18.149s


谢谢

解决此问题的最简单方法是将驱动程序对象设置为静态

 protected static WebDriver driver;
在使用page factory时,还需要初始化page对象,否则所有
WebElement
null

  public loginPage(){
        PageFactory.initElements(driver, this);
    }
或者,我认为这不是一个好的做法,人们应该避免这种做法

public void loginToApp(){


}请添加以下构造函数。它可能会解决此问题

public loginPage(){
  PageFactory.initElements(driver, loginPage.class);
}

你也可以把它放在外面

 public void loginIntoApp() { 
      String url=abstractPage.driver.getCurrentUrl(); 
      System.out.println("the url is::::::::::::::::"+url); 
      loginPage lp=PageFactory.initElements(abstractPage.driver, loginPage.class); 
      lp.username.sendKeys("testuser");
      lp.password.sendKeys("123");
   }
另一种方式是,

public class SmokeTest extends abstractPage {

    @Given("^Open Firefox and start application$")
    public void Open_Firefox_and_start_application() throws Throwable {
            openBrowsernURLhit();
    }

    @When("^I enter valid \"([^\"]*)\" and \"([^\"]*)\"$")
    public void I_enter_valid_username_and_password(String arg1, String arg2) throws Throwable {

        loginPage lpobj = PageFactory.initElements(driver, loginPage.class);
        lpobj.loginIntoApp();
    }

    @Then("^user should be able to login successfully$")
    public void user_should_be_able_to_login_successfully() throws Throwable {

        loginPage lpobj = PageFactory.initElements(driver, loginPage.class);
        lpobj.clicklogn();
    }
}

实际上,如果从abstractpage类返回我的驱动程序并在openBrowsernURLhit方法n的smoke测试类中接受它,然后使用这个驱动程序变量,那么它就工作了,否则它就不工作了,不知道为什么即使在扩展类之后,它也会得到初始化的驱动程序变量public void loginIntoApp(){String url=abstractPage.driver.getCurrentUrl();System.out.println(“url为:::”+url);PageFactory.initElements(abstractPage.driver,loginPage.class);username.sendKeys(“testuser”);它仍然在username.sendKeys(“testuser”)行上抛出空指针异常;好的,当我把pagefactory代码放在Constructor内时它工作,但当我把它放在LoginToAppMethod()内时它不工作,正如上面提到的,你知道它为什么会这样吗?你可以把public void LoginToApp()放在外面,比如,public void loginToApp(){String url=abstractPage.driver.getCurrentUrl();System.out.println(“url是:::::::::::::::“+url”);loginPage lp=PageFactory.initElements(abstractPage.driver,loginPage.class);lp.username.sendKeys(“testuser”);我喜欢这个bt仍然得到同样的异常:public void loginIntoApp(){String url=abstractPage.driver.getCurrentUrl();System.out.println(“url是:::::::::::::”+url);PageFactory.initElements(abstractPage.driver,loginPage.class);username.sendKeys(“testuser”);}好的,当我把pagefactory代码放在Constructor中时它工作,但当我把它放在LoginToAppMethod()中时它不工作如上所述,你知道它为什么会这样吗?如果你仔细观察,我提供了构造函数,而不是方法。你所做的是将代码放入方法中。只需将代码复制粘贴到loginPage类中,一切都会正常工作。此外,在开始自动化之前,请阅读java。我说它在将代码放入构造函数w中时有效这很好,但我的问题是,为什么把它放在方法中不起作用呢?我知道构造函数部分,我在方法中使用过它,它起作用了。