使用TestNG自动化测试时Cart类terms元素触发NullPointerException
问题:TestNG自动化测试中Cart类触发NullPointerException
报错信息:
FAILED: Test.Registration.doRegis java.lang.NullPointerException: Cannot invoke "org.openqa.selenium.WebElement.click()" because "this.terms" is null
使用TestNG进行自动化测试时,多数元素交互正常,但Cart类中terms元素触发空指针异常。已验证该元素的XPath可正常定位到元素,且AddToCartPage类运行无问题。
Cart类代码
package POM; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; public class Cart { @FindBy(xpath = "//select[@name='CountryId']") private WebElement coi; @FindBy(xpath="//option[text()='India']") private WebElement india; @FindBy(xpath= "//*[@id='termsofservice']") WebElement terms; @FindBy(xpath = "//*[@id='checkout']") WebElement buttonCheckout; public void selectCountryId() { coi.click(); } public void selectCountry() { india.click(); } public void checkTerms() { terms.click(); } public void clickCheckout() { buttonCheckout.click(); } }
测试类Registration代码
package Test; import org.testng.annotations.Test; import POM.AddToCartPage; import POM.BillingPage; import POM.Cart; import POM.PaymentInfo; import POM.RegistrationPages; import Utils.DriverUtils; public class Registration { @Test public void doRegis() throws InterruptedException { DriverUtils.getDriver().get("https://demowebshop.tricentis.com/register"); Thread.sleep(5000); RegistrationPages r = new RegistrationPages(); r.selGenderClick(); r.enterFirstName("SomeName"); r.enterLastName("SomeLastNAme"); r.enterEmail("Someto34w0dfd00hgt22@ymail.com"); r.enterPassword("Something@123"); r.confirmPassword("Something@123"); r.clickRegister(); Thread.sleep(5000); r.clickContinue(); Thread.sleep(5000); AddToCartPage addtocart = new AddToCartPage(); addtocart.clickAddTOCart(); Thread.sleep(5000); addtocart.clickGotoCart(); Thread.sleep(5000); Cart c = new Cart(); c.selectCountryId(); c.selectCountry(); c.checkTerms(); c.clickCheckout(); Thread.sleep(5000); BillingPage bp = new BillingPage(); bp.selectCountry(); bp.enterCity("Spme City"); bp.enterAdd1("Somwwhere"); bp.enterPostalCode("465629"); bp.enterPhone("54546561"); bp.clickcontinue(); Thread.sleep(5000); bp.againContinue(); Thread.sleep(2000); bp.againClickContinue(); Thread.sleep(2000); bp.selectPaymentMethod(); Thread.sleep(2000); bp.againContinue(); PaymentInfo pi = new PaymentInfo(); pi.enterName("Some Name"); pi.enterCard("54696187987"); pi.clickContinue(); } }
解决方案
空指针的核心原因是PageFactory未初始化Cart类中的WebElement字段:直接new Cart()创建对象时,@FindBy注解不会自动生效,所有元素都未被实例化,调用terms.click()时自然触发空指针。
步骤1:修改Cart类,添加构造方法初始化PageFactory
在Cart类中新增构造方法,传入WebDriver实例并初始化元素:
package POM; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Cart { private WebDriver driver; // 新增构造方法,初始化PageFactory public Cart(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } @FindBy(xpath = "//select[@name='CountryId']") private WebElement coi; @FindBy(xpath="//option[text()='India']") private WebElement india; @FindBy(xpath= "//*[@id='termsofservice']") WebElement terms; @FindBy(xpath = "//*[@id='checkout']") WebElement buttonCheckout; public void selectCountryId() { coi.click(); } public void selectCountry() { india.click(); } public void checkTerms() { terms.click(); } public void clickCheckout() { buttonCheckout.click(); } }
步骤2:修改测试类中Cart对象的创建方式
在Registration类中,创建Cart对象时传入DriverUtils的WebDriver实例:
// 替换原代码中的 Cart c = new Cart(); Cart c = new Cart(DriverUtils.getDriver());
额外优化建议
- 替换
Thread.sleep()为显式等待(WebDriverWait),避免页面加载速度不稳定导致的元素定位问题,示例:
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import java.time.Duration; // 在Cart类的checkTerms方法中修改 public void checkTerms() { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.elementToBeClickable(terms)).click(); }
- 检查其他POM类(如RegistrationPages、AddToCartPage等)是否也使用了PageFactory初始化元素,避免后续出现同类问题。
内容的提问来源于stack exchange,提问作者Rohit Nagar
相关产品推荐
相关产品推荐

