Java-Selenium如何在测试类中仅初始化一次页面对象?
解决Selenium自动化测试中页面对象重复初始化的问题
以下是几种高效的优化方案,彻底消除重复初始化的代码冗余:
方案1:测试类内声明成员变量,统一初始化
将页面对象提升为测试类的成员变量,通过@BeforeMethod注解的方法一次性完成初始化,每个测试方法执行前自动触发:
public class ContributionTests extends BaseTest { // 声明为测试类私有成员变量 private MainPage mainPageGP; private AssetTabPage assetTabPage; private UnderManagementAssetPage umap; private ContributionTabPage ctp; private NewContributionFormPage ncp; private NewCreatedContributionPage nccp; private ExistingContributionPage ecp; @BeforeMethod public void initPages() { // 统一初始化所有页面对象 mainPageGP = new MainPage(driver); assetTabPage = new AssetTabPage(driver); umap = new UnderManagementAssetPage(driver); ctp = new ContributionTabPage(driver); ncp = new NewContributionFormPage(driver); nccp = new NewCreatedContributionPage(driver); ecp = new ExistingContributionPage(driver); } @Test (priority = 1) @Severity(SeverityLevel.CRITICAL) @Description("Create a Contribution E2E, using only required fields, and validate the new creation contribution name") public void tc1_CreateContribution() throws InterruptedException { mainPageGP.setMainTab("Assets"); assetTabPage.selectUnderManagementTab(); getSleep(500); assetTabPage.selectAsset("new Asset- Test on Edge"); getSleep(500); umap.selectInnerTab("Contributions"); } // 其他测试方法可直接使用已初始化的成员变量 }
适用场景:单个测试类内多个测试方法共用同一批页面对象,灵活性高,可针对不同测试类定制初始化逻辑。
方案2:封装到BaseTest中,全局复用
如果多个测试类都需要用到这些页面对象,可将初始化逻辑迁移到BaseTest中,子类直接继承使用:
修改BaseTest代码:
public class BaseTest { protected WebDriver driver; // 声明为protected,子类可直接访问 protected MainPage mainPageGP; protected AssetTabPage assetTabPage; protected UnderManagementAssetPage umap; protected ContributionTabPage ctp; protected NewContributionFormPage ncp; protected NewCreatedContributionPage nccp; protected ExistingContributionPage ecp; @BeforeClass public void setup() throws InterruptedException { WebDriverManager.chromedriver().setup(); ChromeOptions chromeOptions = new ChromeOptions(); chromeOptions.addArguments("remote-allow-origins=*"); driver = new ChromeDriver(chromeOptions); driver.manage().window().maximize(); PropertyUtils u = new PropertyUtils(); driver.get(u.readProperty("url")); LoginPage lp = new LoginPage(driver); lp.loginToPage(); // 登录完成后初始化共用页面对象 initCommonPages(); } private void initCommonPages() { mainPageGP = new MainPage(driver); assetTabPage = new AssetTabPage(driver); umap = new UnderManagementAssetPage(driver); ctp = new ContributionTabPage(driver); ncp = new NewContributionFormPage(driver); nccp = new NewCreatedContributionPage(driver); ecp = new ExistingContributionPage(driver); } }
测试类简化为:
public class ContributionTests extends BaseTest { @Test (priority = 1) @Severity(SeverityLevel.CRITICAL) @Description("Create a Contribution E2E, using only required fields, and validate the new creation contribution name") public void tc1_CreateContribution() throws InterruptedException { mainPageGP.setMainTab("Assets"); assetTabPage.selectUnderManagementTab(); getSleep(500); assetTabPage.selectAsset("new Asset- Test on Edge"); getSleep(500); umap.selectInnerTab("Contributions"); } }
适用场景:多个测试类共用同一批页面对象,最大化复用代码,减少重复编写量。
可选优化:结合PageFactory简化元素初始化
如果你的页面对象还未使用Selenium的PageFactory,可以进一步优化元素初始化逻辑,减少手动定位代码:
修改页面对象示例(以MainPage为例):
public class MainPage { private WebDriver driver; // 使用PageFactory注解自动定位元素 @FindBy(id = "main-tab-element-id") private WebElement mainTab; public MainPage(WebDriver driver) { this.driver = driver; // 初始化所有注解标记的元素 PageFactory.initElements(driver, this); } public void setMainTab(String tabName) { // 直接使用已初始化的元素 mainTab.sendKeys(tabName); } }
注意事项:
- 若使用
@BeforeClass初始化页面对象,需确保driver在整个测试类生命周期内稳定,无重置或销毁操作;若每个测试方法需要重置页面状态,建议用@BeforeMethod初始化。 - 成员变量建议使用private(方案1)或protected(方案2)修饰,保证代码封装性。
内容的提问来源于stack exchange,提问作者As_Ah
相关产品推荐
相关产品推荐

