PageObject模式最佳实践

想要事半功倍地提高WEB自动化的开发和维护效率,解决实现page object模式过程中的各种问题才是首要考虑因素。

When you write tests against a web page, you need to refer to elements within that web page in order to click links and determine what's displayed. However, if you write tests that manipulate the HTML elements directly your tests will be brittle to changes in the UI. A page object wraps an HTML page, or fragment, with an application-specific API, allowing you to manipulate page elements without digging around in the HTML.

--Martin Fowler

当我们试图去测试一个WEB页面时,不得不依赖页面上的元素去进行交互并确认程序应用是否正常运行。然而当你的脚本试图直接操作页面上的HTML元素时,一旦有相关UI的变更,那测试将会变得十分脆弱。Page object模式就是对HTML页面以及元素细节的封装,并对外提供应用级别的API,使你摆脱与HTML的纠缠。

--Martin Fowler

处理繁杂冗长的元素交互

PageObject模式最佳实践_第1张图片

从上述代码中可以看出,一个最简单的登陆页面,只接收用户名、密码两个参数,剩下的就是与页面上元素交互的细节了。

此处的问题在于,虽然已遵循了page object模式,并将元素的细节进行了封装,但是一个简单的登陆动作,却不得不用许多冗余的代码去实现交互逻辑。

如下图所示:

PageObject模式最佳实践_第2张图片

查找元素——>操作元素——>查找元素——>操作元素….

代码行数随着元素的增加而变得越来越冗长,更不用说为了保证与每个元素交互的稳定性问题而加入的异常处理和等待时间了,一旦UI层有较大的交互逻辑变更,将直接导致每个page object的维护成本急剧上升,直至难以维护的地步。

因此,可以预见到随着页面以及元素交互越来越多,代码会变得又臭又长。

统一的元素交互入口

我们不妨改变一下思路,以单个行为为单位将所有需要进行交互的元素一并打包进行统一处理。

PageObject模式最佳实践_第3张图片

优化后的代码:

PageObject模式最佳实践_第4张图片

可以看到这里的元素交互远比之前的登陆操作冗长且复杂得多,但代码却更简洁了。这样在页面元素或交互逻辑有变更时(UI层的变化可谓家常便饭),只需适当修改元素的定位器和元素的传入顺序就行了,也就极大的降低了UI测试的维护成本。

然而要真正实现这样的模式,还需要考虑以下几点:

动态匹配元素类型以及对应的处理方式

PageObject模式最佳实践_第5张图片

这里需要注意的是除了支持标准的HTML元素操作外,还需要支持自定义的标签。也就是说对于一个标准的button元素来说对它的操作只有click,然而对一个div来说可能支持所有的类型操作(click,input,drag drop…等等)。

以可以进行拖拽操作的span为例,我们还需要对它的定位器进行重写,这样在程序处理此类元素时才能被正确处理。

统一的异常处理

为了保证UI自动化运行的稳定性,我们通常会在每个交互之间添加一些异常处理,也就是对元素的识别和交互进行等待和重试的过程,然而由于现代前端实现的复杂性和功能的多样性使得对进行稳定的交互操作更加困难,以至于在page object交互操作逻辑中的任意一个步骤都可能产生不能识别、不能操作等异常。通常的解决方式是直接在交互步骤中嵌入异常处理的代码。但显而易见的是这么做肯定会导致又臭又长甚至源源不绝的异常处理逻辑,同样会导致无法维护的恶果。

使用代理模式拦截所有的异常并进行统一处理。

PageObject模式最佳实践_第6张图片
PageObject模式最佳实践_第7张图片

如此一来我们会发现,当在perform_actions中处理被代理元素对象时再也不用担心访问其属性时出现异常而导致测试失败了,不用添加额外代码就能使测试稳定运行。

关于建模粒度

有时在对页面进行建模时,除了创建page object外,经常会遇到另外一个问题,那就是是否还需要对页面上的元素进行建模呢?

答案是否定的。

PageObject模式最佳实践_第8张图片

原因是UI经常变化,而页面元素则更易变,如果按照上图方式对每个元素都进行建模,那肯定是事倍功半的,因为你很有可能会花绝大部分的时间在添加和删除代码文件上。

PageObject模式最佳实践_第9张图片
PageObject模式最佳实践_第10张图片

其实我们可以把存在于一个页面中某些逻辑紧密的UI元素直接定义为若干个page objects,这样做可以大幅度减少不必要的关于元素代码的文件产生,并且使原本看似十分松散凌乱的UI元素以更合理的结构呈现出来,弱化了元素间的耦合度。

结语

以上就是关于在实现page object模式过程中遇到的一些实际问题。可以看出一旦处理好对页面元素的交互与控制,将会极大提高WEB自动化的开发与维护效率。

本文编译:钱俊杰 Chester Qian(点融黑帮),现任点融网高级测试开发工程师。负责公司贷款业务应用质量保证,测试框架、工具开发与维护。

你可能感兴趣的:(PageObject模式最佳实践)