Selenium [Java] PageFactory 设计:在 Page Object 模型之后,我应该在哪里编写我的断言

Selenium [Java] PageFactory Design : Where do I write my Assertions following Page Object Model

我正在关注页面 Object 模型以在一个应用程序中自动化流程。在其中一个模块中,我必须声明页面标题和更多消息。截至目前,我将我的断言代码放在 PageFactory 本身中,如下所示:

public class EditPost {

    WebDriver driver;

    public EditPost(WebDriver editPostDriver)
    {
        this.driver=editPostDriver;
    }

    @FindBy(how=How.XPATH,using="//*[@id='message']/p")
    WebElement post_published;

    public void assert_message()
    {
        String actual_message_title=post_published.getText();
        Assert.assertEquals(actual_message_title, "Post published. View post");
        System.out.println("Message: Post published, Successfully Verified");
    }
}

我正在从实现 TestNG 的主文件中调用断言方法,如下所示:

@Test (priority=5)
public void assert_message()
{
    //Created Page Object using Page Factory
    EditPost edit_post = PageFactory.initElements(driver, EditPost.class);
    edit_post.assert_message();

}

目前,我运行执行了3个包。 "Helper" 浏览器工厂包,"Pages" 页面工厂包和 "Testcase" 测试用例包。

我的 objective 正在向前发展我想重用为所有不同实用程序编写的代码。

我的问题是:

  1. 根据 PageFactory 和 Page Object 模型的概念,我的方法是否正确?或者我是否需要将断言移至 "Helper" 包?或者我应该为断言创建一个单独的 library/package 吗? (在接下来的日子里,我可能需要在一个页面上执行多个断言)

  2. 在下一个冲刺中,我可能需要做一些其他活动,比如拍摄 All/Failed 测试用例的屏幕截图。那么,我该如何保持设计的结构和组织性,以便我可以以最佳方式重用 code/libraries/utilize 它们?

根据我见过的大多数网站,最佳做法是将断言保留在页面对象之外。下面是 Selenium 文档中的一个示例。

http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern

There is a lot of flexibility in how the page objects may be designed, but there are a few basic rules for getting the desired maintainability of your test code.

Page objects themselves should never make verifications or assertions. This is part of your test and should always be within the test’s code, never in an page object. The page object will contain the representation of the page, and the services the page provides via methods but no code related to what is being tested should be within the page object.

There is one, single, verification which can, and should, be within the page object and that is to verify that the page, and possibly critical elements on the page, were loaded correctly. This verification should be done while instantiating the page object. In the examples above, both the SignInPage and HomePage constructors check that the expected page is available and ready for requests from the test.

页面对象应 return 产品名称、产品价格、当前选择的数量等内容。然后测试代码将断言 returned 字符串与预期匹配。

assert_message() 会变成 getMessage() 并且 return 消息会变成 String。见下文。

public String getMessage()
{
    return driver.findElement(messageLocator).getText();
}

(注意:请继续阅读我为何将 PageFactory 元素更改为定位器的原因。)

然后在你的测试代码中,你会

Assert.assertEquals(editPost.getMessage(), "Post published. View post");

现在您已将断言代码保留在测试脚本中并保留在页面对象之外。

看看你的代码,我会提出一些进一步的建议。

  1. 我建议您阅读一些 Java 命名约定。有很多网站都有推荐,我认为它们之间有很多相似之处,但首先要从 oracle recommendations 开始。您的方法名称应该是

    verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

    所以 assert_message() 会变成 assertMessage() 等等。 _s 使它看起来更像 python.

  2. 定位器的优先顺序:ID、CSS 选择器,在极少数情况下为 XPath。 ID 应该始终是您的首选,因为它(根据 W3C 定义)在页面上应该是唯一的。 CSS 选择器应该是下一个,因为它是最快的(在我的测试中比 ID 快),具有最好的浏览器支持,并且跨浏览器实现最一致。 XPath 应该只保留用于 CSS 选择器无法完成的事情,例如通过包含的文本查找元素。与 CSS 选择器相比,XPath 定位器的性能较差,并且没有与 CSS 选择器相同的支持级别。例如,您的 XPath 定位器可以轻松转换为 CSS 选择器,“#message > p”。

    这里有一些 CSS 选择器参考,可以帮助您入门。

    CSS Selectors reference

    CSS Selector tips

  3. 掉落PageFactory。是的,它似乎让事情变得更容易,但我认为在很多情况下它会导致更多问题,比如陈旧的元素异常等等。更喜欢根据需要抓取页面。在 class 的顶部声明所有定位器,并在需要时在方法中使用它们。

    public class EditPost {
    
        WebDriver driver;
    
        By messageLocator = By.cssSelector("#message > p")
    
        public EditPost(WebDriver editPostDriver)
        {
            this.driver = editPostDriver;
        }
    
        public String getMessage()
        {
            return driver.findElement(messageLocator).getText();
        }
    }
    

我知道这比你问的要多,但希望它有用。