一尘不染

Selenium [Java] PageFactory设计:我应在何处根据页面对象模型编写断言

selenium

我正在遵循页面对象模型来自动化一个应用程序中的流程。在模块之一中,我必须声明页面标题和更多消息。截至目前,我将我的断言代码放在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的主文件中调用assert方法,如下所示:

@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”软件包,PageFactories的“ Pages”软件包和Testcase的“
Testcase”软件包。

我的目标是向前发展,我想重用为所有不同实用程序编写的代码。

我的问题是:

  1. 根据PageFactory&Page Object Model的概念,我的方法正确吗?还是我需要将断言移到“ Helper”包中?还是应该为断言创建一个单独的库/程序包?(在未来的日子里,我可能需要在一个页面上执行多个断言)

  2. 在下一个冲刺中,我可能需要执行其他一些活动,例如对所有/失败的测试用例进行屏幕截图。那么,如何保持设计的结构化和组织性,以便以最佳方式重用代码/库/利用它们?


阅读 334

收藏
2020-06-26

共1个答案

一尘不染

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

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

页面对象的设计方式具有很大的灵活性,但是有一些基本规则可以使测试代码具有理想的可维护性。

页面对象本身绝不应进行验证或断言。
这是测试的一部分,应始终在测试的代码内,而不是在页面对象中。页面对象将包含页面的表示形式,以及页面通过方法提供的服务,但是与对象测试无关的代码都不应包含在页面对象内。

可以并且应该在页面对象中进行一次单一验证,即验证页面以及页面上可能的关键元素是否已正确加载。实例化页面对象时应进行此验证。在上面的示例中,SignInPage和HomePage构造函数均检查预期的页面是否可用并准备接受测试请求。

页面对象应返回诸如产品名称,产品价格,当前选择的数量等信息。然后,测试代码将断言返回的字符串与期望的字符串匹配。

assert_message()将成为getMessage()并以形式返回该消息String。见下文。

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

(注意:请继续阅读为什么我在PageFactory这里将元素更改为定位符。)

然后在测试代码中,

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

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

查看您的代码,我将提出一些进一步的建议。

  1. 我建议您阅读一些Java命名约定。有很多网站都提出了建议,我认为它们之间有很多相似之处,但这是从oracle开始的建议。您的方法名称应为

动词,首字母小写混合,每个内部单词的首字母大写。

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

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

以下是一些CSS选择器参考,可帮助您入门。

CSS选择器参考

CSS选择器提示

  1. 放下PageFactory。是的,这似乎使事情变得容易,但我认为在许多情况下,它会导致更多问题,例如陈旧的元素异常等。而是根据需要刮取页面。将所有定位符声明在类的顶部,并在需要时在方法中使用它们。
    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();
    }
    

    }

我知道这超出了您的要求,但希望对您有所帮助。

2020-06-26