译者注:这篇文章翻译自马丁·福勒(Martin Flower,对,没错,就是软件教父)官网的一篇文章,原文出处在文底。如果你正在做WEB自动化测试,那么我强烈推荐你看这篇文章。另外透露Martin Flower将于10月份左右来成都ThoughtWorks办公室,大家有机会一睹他的风采。

当你在为web页面编写测试时,你需要操作该web页面上的元素来点击链接或确定显示的内容。然后,如果你在测试代码中直接操作html元素,那么你的代码是机器脆弱的,因为UI会经常变动。一个page对象可以封装一个html页面或部分页面,通过提供的应用程序特定的API,你可以操作页面元素而不需要在HTML中四处搜寻。

page对象的一个基本的经验法则是page对象应该允许软件客户端能够做任何人类能做的事。它也应当提供一个易于编程的接口,并隐藏窗口中低层的部件。所以访问一个文本框,可以通过一个访问方法获取一个字符串,复选框应当使用布尔值,按钮应当被表示为行为导向的方法名。page对象应当封装所有的在gui控件本身上查找和操作数据的方法。一个好的经验法则是即使改变具体的控制,这种情况下page对象接口不应当发生变化。

尽管该术语是”页面“对象,并不意味着给每个页面都要建立一个这样的对象,但页面有重要意义的元素除外[1]。所以一个显示多个相册的页面可以有一个相册列表的page对象,里面包含了几个相册page对象。也有可能会有一个页眉page对象及一个页脚page对象。经验法则是给通过给页面建模,从而对应用程序的使用者变得有意义。

同样,如果你导航到另一个页面,初始page对象应当返回另一个page对象作为新页面[2]。一般page对象的操作应当返回 基本类型(字符串,日期)或另一个page对象。

有一个意见分歧的地方是page对象是由应当包含自身的断言,或者仅仅提供数据给测试脚本来设置断言。在page对象中包含断言的倡导者认为这有助于避免在测试脚本中出现重复的断言,可以更容易的提供更好的错误信息,并且提供更接近TellDontAsk风格的API。不在page对象中包含断言的倡导者则认为包含断言会混合使用断言逻辑访问页面数据的职责,并且导致page对象过于臃肿。

我赞成在page对象中不包含断言。我认为你可以通过为常用的断言提供断言库的方式来消除重复。这可可以提供更好的诊断。[3]

page对象通常用于测试中,但自身不应包含断言。它们的职责是提供对基本页面状态的访问。而与测试客户端实现断言逻辑。

我所描述的这个模式针对HTML,但同样的模式也同样适用于任何UI技术。我见过这种模式有效的隐藏了Java swing UI的细节,并且我深信它已经被广泛的应用于几乎所有其他的UI框架。

并行问题是另一个page对象可以封转的话题。这可能涉及异步操作中隐藏不作为异步呈现给用户的异步性。也有可能涉及封装UI框架中你不得不担心的UI和工作线程之间分配行为的线程问题。

page对象在测试中的使用非常常见,但是也被用于在应用程序上层提供一个脚本接口。最好将脚本接口置于UI下层,这样脚本通常不复杂并且执行速度快。然而应用程序在UI层有太多的行为,那么使用page对象可能在槽糕的工作中最好的选择。(但是尽量将逻辑移入page object,长期来看会导致更好的脚本即更健康的UI。)

使用一些领域特定语言来书写测试非常普遍,比如Cucumber或一门内部DSL。如果你尽量在page对象层级之上编写测试DSL,那么你可以通过一个解析器将DSL声明转换为调用page对象。

如果你在测试方法中使用了WebDriver API,那么你做错了 – Simon Stewart.

模式有助于将逻辑从页面元素中剥离(例如 Presentation Model, Supervising Controller, 及Passive View),从而少通过UI做测试,并且减少对page对象的需要。

page对象是封转的一个典型示例。它们从其它组件(如测试)部件中隐藏了UI结构的细节。。如果你自问“我如何能从软件测试中隐藏细节?”,当你做开发时在这样的情况采用page对象不失于一个好的设计原则。封转体现了两方面的好处。我已经强调,通过将操作UI的逻辑限制到单个地方有助于你修改逻辑而不影响系统的其他组件。一个间接的好处是使测试端代码更容易理解,因为逻辑是关于测试的意图,而会被UI细节搞乱。

进一步阅读

I first described this pattern under the name Window Driver. However since then the term “page object” was popularized by the Selenium web testing framework and that’s become the generally used name.

我刚开始将这种模式命名为窗口驱动(Window Driver)。然而自从Selenium web测试框架使用“page object”这个名称,page对象变成了常用的名称。

Selenium的维基强烈推荐使用page对象,并提供了如果使用的建议。它也赞成page对象不包含断言。

致谢

Perryn Fowler, Pete Hodgson及Simon Stewart为这篇博客的草稿提供了及其有用的意见。同样像往常一样我非常感激ThoughtWorks软件开发列表中的各种各样的居民提供的建议和修正。

脚注

  1. 有观点认为”page对象“名称是一个误导。因为它让你认为一个页面只能有一个page对象。类似面板对象可能会更好,但是page对象已经被广泛接受。为什么命名的另一个例证是TwoHardThings中的其中之一。

  2. page对象负责创建其他的page对象(比如导航)是共同的意见。然而,一些从业者更喜欢page对象返回一些通用的浏览器上下文,通过建立在上下文上层的page对象的测试控制是基于测试的流程(特别是条件流).
    他们偏好基于测试脚本知道那个页面是期待的下个页面这一事实,并且该知识不需要在page对象之间重复。特别是使用静态类型语言通常以类型标记的方式显示页面导航,这样会增加他们的喜好。

  3. page对象中包含断言也行,尽管大多数人(比如我)更青睐无断言风格。这些断言可以检查页面或应用程序在此时此刻的不变量,而不是测试探索的具体东西。

本文出处: http://martinfowler.com/bliki/PageObject.html

[翻译]-马丁·福勒-page对象的更多相关文章

  1. 马丁·福勒-page对象

    马丁·福勒-page对象 译者注:这篇文章翻译自马丁·福勒(Martin Flower,对,没错,就是软件教父)官网的一篇文章,原文出处在文底.如果你正在做WEB自动化测试,那么我强烈推荐你看这篇文章 ...

  2. 马丁 福勒 Martin Fowler 关于依赖注入和反转控制的区别

    马丁 福勒 Martin Fowler 关于依赖注入和反转控制的区别 http://martinfowler.com/articles/injection.html 中文翻译:http://files ...

  3. 首席科学家马丁•福勒(Martin Fowler)

    现任思特沃克公司首席科学家的马丁·福勒先生是当今世界软件开发领域最具影响力的五位大师之一.作为一位敏捷软件开发方法的早期开拓者,福勒先生对IT 业的影响是不可估量的. 思特沃克公司是一家跨国专业IT ...

  4. 为什么page对象不适合用ThreadLocal

    今天测试了下,在action中决定是否设置page,在dao层中取出分页,确实没有问题.但是,有一种情况不行,在service中查询了两次数据库,都共享这个page对象了?结果就乱了. 谁有更好解决方 ...

  5. ASP.NET Page对象各事件执行顺序(转)

    很久没写 asp.net 的东西了,search 了一下 page 的事件执行顺序,找到如下的东西,仅仅做记录用 Page.PreInit 在页初始化开始时发生 Page.Init 当服务器控件初始化 ...

  6. 向Page对象注册脚本

    在madn上ClientScriptManager 类的示例: <%@ Page Language="C#"%> <!DOCTYPE html PUBLIC &q ...

  7. jsp内置对象-page对象

    page对象代表jsp本身,只有在jsp页面才有效.page对象本质上是被转换后的Servlet,因此它可以调用任何被Servlet类所定义的方法. 项目ch05案例:创建HttpJSPPage类的对 ...

  8. Page 对象详解

    Page 对象 由于网页编译后所创建的类由Page派生而来,因此网页可以直接使用Page对象的属性.方法和事件. Page对象的常用属性 1.IsPostBack(bool类型) 获取一个值,该值指示 ...

  9. 使用Puppeteer进行数据抓取(二)——Page对象

    page对象是puppeteer最常用的对象,它可以认为是chrome的一个tab页,主要的页面操作都是通过它进行的.Google的官方文档详细介绍了page对象的使用,这里我只是简单的小结一下. 客 ...

随机推荐

  1. 终极优化_详解Win7旗舰版系统中可以关闭的服务

    Win7旗舰版系统是一款功能强大的系统,不过对于很多用户很多功能却使用不上,而支持功能的很多服务也多少占用了系统资源,那么我们可以通过关闭一些不使用的服务来达到让win7系统运行速度加快的目的.下面小 ...

  2. C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)控制 WebBrowser 控件的外观和行为

    在 CSDN 上经常看到以下两个问题:1.在 MFC 应用程序中,如果创建了一个 WebBrowser 控件(包括 CHtmlView 在内),如何可以把该控件的三维边框禁止掉?2.在 MFC 应用程 ...

  3. JavaScript小功能

    1. JS判断是否为一个有效日期 1 2 3 4 function check(date){     return (new Date(date).getDate()==date.substring( ...

  4. sourceTree忽略跟踪文件

    1.未跟踪文件,直接在.gitignore文件打上文件名字,如果要忽略整个文件夹,要在文字后面加上一个/ .如:gradle/ . 2.已跟踪文件,先删除那些文件,再提交到git上,即删除远程的文件, ...

  5. Deep Learning(1)-Introduction学习总结

    学习DL搁置很久了,终于下定决心开始咯~~ Deep Learning(Ian Goodfellow&&Yoshua Bengio&&Aaron Courville)- ...

  6. css 单位-px、em、rem、百分比

    px像素(Pixel,像素px是相对于显示器屏幕分辨率而言的. em是相对长度单位.相对于当前对象内文本的字体尺寸.如当前对行内文本的字体尺寸未被人为设置,则相对于父级元素字体尺寸(若父级元素未指定f ...

  7. XE3随笔12:TSuperTableString、TSuperAvlEntry

    通过 ISuperObject.AsObject 可获取一个 TSuperTableString 对象. TSuperTableString 的常用属性: count.GetNames.GetValu ...

  8. Java Hotspot G1 GC的一些关键技术

    G1 GC,全称Garbage-First Garbage Collector,通过-XX:+UseG1GC参数来启用,作为体验版随着JDK 6u14版本面世,在JDK 7u4版本发行时被正式推出,相 ...

  9. 水果项目第2集-建立数据库->编写数据访问基础类->实现类的方法->调试通过

    看来写博客对懒人也有好处.监督自己的好处. 今天一打开电脑,就想继续写了. 今天就开始动手做了. 数据库建立,编写访问数据库代码,实现各个类的方法,调试这些方法. 这些基础的代码写完后,就可以写逻辑代 ...

  10. window.open打开窗体和if嵌套

    <script>    function openWindow(){var my=confirm("你要打开窗口吗?")if(my==true){    var url ...