You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium POM实现遇NullPointerException及多窗口重复问题求助

Selenium POM模式自动化测试问题排查

我正在尝试用Selenium实现Page Object Model(POM),登录页负责打开目标URL、输入用户名和密码。现在代码运行时会打开URL加载页面,但无法定位元素,还会重复打开3-4个空白窗口,最终定位元素时抛出NullPointerException崩溃。多次检查代码没找到问题,附上相关代码、错误栈和配置文件,请求协助排查。


1. Base类代码

public class Base {
    public static WebDriver driver;
    public static Properties prop;
    public Base(){
        try {
            prop = new Properties();
            FileInputStream ip = new FileInputStream("C:\\config\\config.properties");
            prop.load(ip);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void initilization()
    {
        String browsername = prop.getProperty("browser");
        if (browsername.equals("chrome")){
            
            System.setProperty("webdriver.chrome.driver","C:\\Users\\chromedriver.exe");
            driver= new ChromeDriver();
        }
        driver.manage().window().maximize();
        driver.get(prop.getProperty("url"));
        driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(70));
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(70));
        
    }

}

2. LoginPage类代码

public class LoginPage extends Base {
    @FindBy(name = "username")
    WebElement username;

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

    @FindBy(xpath = "//input[@type='submit']")
    WebElement loginbutton;

    @FindBy(xpath = "//button[contains(text(),'Sign Up')]")
    WebElement SignUpButton;

    @FindBy(xpath= "//img[contains(@class='img-responsive')]")
    WebElement crmlogo;

    public void LoginPage()
    {
        PageFactory.initElements(driver,this);
    }

    public boolean logo()
    {
        return crmlogo.isDisplayed();
    }

    public String validatetitleofpage()
    {
        return driver.getTitle();

    }
    public HomePage login(String un,String psd)
    {
        username.sendKeys(un);
        password.sendKeys(psd);
        loginbutton.click();
        return new HomePage();
    }

}

3. LoginPageTest类代码

public class LoginPageTest extends Base {
    LoginPage LoginPage;
    HomePage HomePage;
    
    public LoginPageTest()
    { super();
    }
    @BeforeMethod
    public void setup()
    {
        initilization();
        LoginPage = new LoginPage();
    }

    @Test (priority = 1)
    public void loginPageTitleTest()
    {
        String title = LoginPage.validatetitleofpage();
        Assert.assertEquals(title,"title details");
    }

    @Test (priority = 2)
    public void logoTest()
    {
        boolean logotrue=LoginPage.logo();
        Assert.assertTrue(logotrue);
    }

    @Test(priority = 3)
    public void logintest()
    {
        HomePage= LoginPage.login(prop.getProperty("unme"),prop.getProperty("pwd"));
    }

    @AfterMethod
    public void teardown()
    {
        driver.quit();

    }
}

4. 错误栈信息

java.lang.NullPointerException
   at com.crm.qa.pages.LoginPage.logo(LoginPage.java:31 undefined)
   at com.crm.qa.Testcases.LoginPageTest.logoTe0st(LoginPageTest.java:37 undefined)
   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at 
                java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.base/java.lang.reflect.Method.invoke(Method.java:566 undefined)
                at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
   at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598 undefined)
   at org.testng.internal.TestInvoker.invokeTestMethod
                (TestInvoker.java:173)
   at org.testng.internal.MethodRunner.runInSequence
            (MethodRunner.java:46)
   at 
 org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
   at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146 undefined)

5. 配置文件(config.properties)

url = https://classic.crmpro.com/
unme = abcd
pwd =  Abcd
browser = chrome**

问题根源及修复方案

1. 构造方法错误导致PageFactory未初始化

LoginPage类中的public void LoginPage()是普通方法,不是构造方法。Java构造方法没有返回值类型,正确写法需去掉void:

public LoginPage() {
    PageFactory.initElements(driver, this);
}

原代码中该方法不会自动执行,导致@FindBy注解的WebElement未初始化,调用crmlogo.isDisplayed()时抛出NullPointerException。

2. 配置文件browser值错误

配置文件里browser = chrome**多了两个星号,导致browsername.equals("chrome")判断失败,driver未被实例化。修正为:

browser = chrome

3. 重复打开窗口的原因

  • TestNG的@BeforeMethod会在每个@Test方法执行前运行一次,3个@Test方法会触发3次initilization(),每次新建ChromeDriver实例,导致打开3个窗口。
  • 优化方案:
    • 将driver改为非静态,避免跨实例污染;
    • 或用@BeforeTest替代@BeforeMethod,确保初始化只执行一次(根据测试需求选择)。

4. XPath表达式语法错误

LoginPage中logo的XPath//img[contains(@class='img-responsive')]格式错误,contains的正确写法是contains(@class, 'img-responsive'),修正后:

@FindBy(xpath= "//img[contains(@class, 'img-responsive')]")
WebElement crmlogo;

5. 其他优化点

  • Base类的initilization()方法如果浏览器不是chrome,driver会为null,建议添加else分支或默认浏览器配置;
  • 测试类中的标题断言Assert.assertEquals(title,"title details")需改为目标页面实际标题"CRMPRO";
  • 优先使用显式等待替代隐式等待,比如判断元素显示前添加:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOf(crmlogo));

内容的提问来源于stack exchange,提问作者Sakhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 04:55:04