首页 > 解决方案 > 在 POM 设计模式中,哪些方法应该在 Page 类中?

问题描述

我正在使用 POM 设计模式创建一个 UI 测试自动化框架。在阅读了页面对象的 SeleniumHQ 页面后,我正在考虑应该在页面对象中创建哪些所有方法。

让我们举一个登录页面对象的简单示例,该对象由用户名、密码文本框和提交按钮组成。SeleniumHQ 链接创建了以下方法:

1. typeUsername(String username)
2. typePassword(String password)
3. submitLogin()
4. submitLoginExceptionFailure()
5. loginAs(String username, String password)

看着这些方法,我有点困惑。当我已经在创建 loginAs 方法时,为什么要创建前 3 个方法(typeUsername、typePassword、submitLogin)。有什么想法吗?

SeleniumHQ 链接- https://github.com/SeleniumHQ/selenium/wiki/PageObjects

粘贴 LoginPage 的代码 PageObject 代码:

public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;    
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;    
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);    
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);   
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}

标签: seleniumpageobjects

解决方案


您可能想检查是否仅键入用户名然后单击提交按钮显示正确的错误消息,或者仅显示密码等。

我通常会查看页面并尝试总结用户可以在该页面上执行的“操作”,每个操作都成为一种方法。不同的动作可能在不同的“级别”上。例如,在博客网站上,用户可以输入博客标题和博客内容,这是用户可以执行的两个操作,但从另一个抽象层查看用户想要“创建”一篇文章。因此该函数可能会再次调用其他函数。

基本上它就像任何其他编程一样,你有多个抽象层,这就是你首先拥有页面对象的原因。

并且只需使用迭代开发,创建一个执行您想要测试的函数,如果您发现自己在其他函数中重用相同的代码(或标识符),请将它们分开在一个新函数中


推荐阅读