如何在 Selenium 中将页面对象与代码逻辑分开- java

How to separate page objects from code logic in Selenium- java

我正在学习并尝试将定位器与 selenium 中的实际代码分开。我已经把它们分开了,但我需要更多优化方面的指导,我怎样才能进一步优化代码?页面对象设计模型是否仅用于存储定位器?或者我们也可以存储他们的方法。有人可以参考下面的代码解释一下吗?

Link: https://www.goibibo.com/

带逻辑的实际代码(TC_01Test.java)和Base.java class初始化驱动程序


public class TC_01Test extends Base {

    WebDriver driver;

    @BeforeTest
    public void initialize() throws IOException {

        driver = initializeDriver();
    }

    // Sign In functionality
    @Test
    public void SignIn() throws InterruptedException {

        TC_01 tc02 = new TC_01(driver);
        tc02.siginLink().click();
        System.out.println(driver.getWindowHandle());
        driver.switchTo().frame("authiframe");
        System.out.println(driver.getWindowHandle());
        tc02.mobileNumber().sendKeys(prop.getProperty("phoneNumber"));
        System.out.println("number entered");
        tc02.submitButton().click();
        System.out.println("button clicked");
        driver.switchTo().defaultContent();
        System.out.println(driver.getWindowHandle());
        tc02.closePopup().click();

    }

    // SignUp functionality
    @Test
    public void SignOut() {
        TC_01 tc01 = new TC_01(driver);
        tc01.sigupLink().click();
        driver.switchTo().frame("authiframe");
        tc01.mobileNumber().sendKeys(prop.getProperty("phoneNumber"));
        tc01.submitButton().click();
        driver.switchTo().defaultContent();
        tc01.closePopup().click();

    }

    @AfterTest
    public void closeBrowser() {
        driver = tearDown();
    }

}

下面是为上述测试用例创建的页面对象 (TC_01.java) 的代码。

public class TC_01 {

    WebDriver driver;

    public TC_01(WebDriver driver) {
        this.driver = driver;
    }

    // driver.findElement(By.xpath("//a[@id='get_sign_in']"))

    // mobileNumber= driver.findElement(By.xpath("//input[@id='authMobile']")

    // driver.findElement(By.id("mobileSubmitBtn"))

    // driver.findElement(By.xpath("//div[@class='popContent']/a"))

    By signinLink = By.xpath("//a[@id='get_sign_in']");
    By signupLink = By.xpath("//a[@id='get_sign_up']");
    By mobileNumber = By.xpath("//input[@id='authMobile']");
    By submitButton = By.id("mobileSubmitBtn");
    By closePopup = By.xpath("//div[@class='popContent']/a");

    public WebElement siginLink() {

        return driver.findElement(signinLink);
    }

    public WebElement sigupLink() {

        return driver.findElement(signupLink);
    }

    public WebElement mobileNumber() {

        return driver.findElement(mobileNumber);
    }

    public WebElement submitButton() {

        return driver.findElement(submitButton);
    }

    public WebElement closePopup() {

        return driver.findElement(closePopup);
    }
}

回答您的问题 - 是的,您也可以将方法存储在 PO classes 中。此外,这是一个很好的做法。 关于您的代码优化 - 最好表达业务行为而不是细粒度的技术操作。此外,无需返回 WebElement 方法然后在测试 class 中执行操作(单击、发送键等),您只需在 PO class 中执行此类操作即可。 检查下面的代码。

    public void enterFirstName() {

        driver.findElement(firstName).sendKeys("abc");
    }

    public void enterLastName() {

        driver.findElement(lastName).sendKeys("qwerty");
    }

    public void pressSubmitButton() {

        driver.findElement(submitButton).click();
    }
// instead of invocation all of these methods above in test class you can simply do this:

    public void loginWithValidCredentials(String firstNameValue, String lastNameValue) {
        driver.findElement(firstName).sendKeys(firstNameValue);
        driver.findElement(lastName).sendKeys(lastNameValue);
        driver.findElement(submitButton).click();
    }

// Thus your test will look like:

@Test
public void loginTest() {
    POclass po = new POclass();
    po.loginWithValidCredentials("yourName", "yourNameABC");
    // some assert() methods...
}

这样就简单多了。 顺便说一句,了解和使用 PageFactory 概念很有用 - https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html

P.S。 - 阅读 "Chain of responsibilities" 模式,但如果你擅长 Java,因为这是一个相当高级的主题。