TestNG使用POM框架操作前序测试用例打开的页面报空指针异常
问题根因
- 第三条测试用例的页面对象初始化时机错误:你在类成员变量定义阶段直接调用
PageFactory.initElements,此时TestNG的@BeforeSuite注解的初始化方法还未执行,driver仍然是null,导致初始化的页面对象元素代理全部无效。前两条用例均是在@Test方法内部初始化页面对象,此时driver已经完成实例化,所以可以正常运行。 - 页面对象类写法不符合POM规范:
MYQC_Login_Page中被@FindBy注解标注的元素加了static修饰符,PageFactory无法正常初始化静态元素,会出现生命周期绑定问题。 - 未切换新窗口句柄:第二条用例点击按钮打开新页面后,driver默认停留在原页面,未切换到新打开的标签页,即使元素初始化正确也无法定位到新页面的元素。
修复方案
1. 修改页面对象类MYQC_Login_Page
移除所有页面元素的static修饰符:
package MYQC_Browser_Pages; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.How; public class MYQC_Login_Page { WebDriver driver; public MYQC_Login_Page(WebDriver driver) { this.driver = driver; } // 移除static修饰符 @FindBy(how = How.ID, using = "loginName") public WebElement userNameField; @FindBy(how = How.ID, using = "loginPassword") public WebElement passwordField; @FindBy(how = How.ID, using = "loginButton") public WebElement clickLogin; public void clickUserName() { userNameField.click(); } public void enterUserName(String user) { userNameField.sendKeys(user); } public void clickPass() { passwordField.click(); } public void enterPassword(String pass) { passwordField.sendKeys(pass); } public void clickLoginButton() { clickLogin.click(); } }
2. 修改第三条测试用例TC003_MYQC_Prepaid_Login_Test
调整初始化时机,增加窗口句柄切换逻辑:
package MYQC_TestCase_Classes; import MYQC_Browser_Pages.MYQC_Login_Page; import MYQC_Reusable_Classes.MYQC_Base_Class; import org.openqa.selenium.support.PageFactory; import org.testng.annotations.Test; import java.util.ArrayList; public class TC003_MYQC_Prepaid_Login_Test extends MYQC_Base_Class { @Test(priority = 3) // 保证用例按顺序执行,数字越小优先级越高 public void MYQC_Login() throws InterruptedException { // 切换到新打开的标签页 ArrayList<String> windowHandles = new ArrayList<>(driver.getWindowHandles()); driver.switchTo().window(windowHandles.get(1)); // driver实例化完成后再初始化页面对象 MYQC_Login_Page login_page = PageFactory.initElements(driver,MYQC_Login_Page.class); Thread.sleep(2000); login_page.clickUserName(); login_page.enterUserName("***"); Thread.sleep(2000); login_page.clickPass(); login_page.enterPassword("***"); login_page.clickLoginButton(); } }
3. 补充用例顺序配置
给前两条测试用例的@Test注解也增加优先级配置,避免执行顺序混乱:
- TC001的
@Test改为@Test(priority = 1) - TC002的
@Test改为@Test(priority = 2)
内容的提问来源于stack exchange,提问作者Faruk
相关产品推荐
相关产品推荐

