学习自动化设计框架的小伙伴稍微总结一下就会发现线性测试有大量的重复代码,新人上手学习成本高, 元素定位信息过于分散,概括为:开发成本、维护成本高。所以使用起来小项目还可以,大项目特别是测试人员需要共同维护一套的时候就比较吃力。
那我们以模块化驱动设计框架发现就会好很多,假如是简单的模块那我们就把重复代码独立成公共模块来设计。如果模块比较多,那我们以页面工厂模式 PageFactory,也就是非常强大的 PO(PageObject)模式来设计,PageObject 设计模式定义:将测试对象及单个的测试步骤封装在每个 Page 对象中,以 page 为单位进行管理。换句话说就是每个页面就是一个类,这个页面里面的元素定位信息是以类的属性存在,页面上的操作是以方法提供的 ,以页面为单位对用例进行管理和分层。
那下面我浅谈一下这个模式,希望能对初次探索自动化测试的小伙伴们有一些思路上的帮助。
◆ 每个页面抽象成独立的类
1.页面中元素的定位信息,都是类的属性,以元组形式进行管理
2.页面中的业务操作都是类的方法
3.所有的具体页面都扩展自页面基础类 BasePage
作用:不用引包、少写 driver、简化 selenium 常用操作、提供整个网站或 app 的通用行为封装。
补充一下其他函数的封装,例如异常弹框处理,有关闭广告,关闭升级,关闭好评,关闭 tips 等。
◆ PO 模式的基本原则
解读如下
设计步骤如下:
我以 python+selenium+unittest 一个登录页面为例来简单说一下怎么用 PO 模式写,我们先不着急写测试用例,我们新建一个包叫 Pages, 放所有测试页面 page 用的。不知不觉我们就分层了,创建第一个页面叫 LoginPage.py 文件,代码如下:
上面的 page 里面的定位元素信息和方法写完后我们就可以写测试用例了,我们再新建一个包叫 Cases, 放所有测试用例用的。新建一个 Login.py 文件,代码如下:
如果登录里面有一个登录成功,有一个登录失败,我们要写 2 个方法,虽然操作是一样的,但是结果是不一样的。登录成功我们返回的是 homepage 对象,登录失败我们需要返回的是登录失败的提示信息,方便用例下一步做断言使用。
我们写了很多 Page 发现里面还是有很多重复的代码,比如点击,发送等操作,我们还可以进行进一步的封装,新建一个 BasePage.py 文件,代码如下:
如果在之后的测试中有新的需要补充的方法在后面接着添加即可。
有了 BasePage.py 那我们就可以进一步的改造 LoginPage.py 文件,LoginPage 就可以继承 BasePage,代码如下:
完成一个用例后我们就可以写下一个 Page 页面,这样下来我们发现我们测试用例里面只用几行代码就可以,大部分且大量的工作都在中间的 page 这一层。
完成所有用例的代码的编写后,我们再新建一个 run.py 文件,这个 run 文件放到和其他包同级的位置来运行我们的用例,这里我们写一个运行 Cases 包里面的所有测试用例的代码,如下:
运行所有的测试用例缺点就是所有的测试用例都会运行,不想跑都不行。
也可以一个一个添加用例,好处精准不容易出错,不想跑的用例可以不添加在里面,但缺点是太麻烦了。代码如下:
最后我们就可以看到一个简单的框架层如下,有时间还可以通过 HTMLTestRunner 补充测试报告。
最后总结来说 PO 模式就是在 Page 页面里面放对象,放方法,然后用例里面不用操作对象直接调方法,我们只要维护 Page 页里面的对象和方法,尽量不要把页面元素裸露给用户让他来用,也尽量把方法设计好,如果方法直接出结果就返回结果,如果方法操作完了还有下个页面我们就返回下一个页面对象,这样我们整体的测试用例写起来很规范。
我们说的 Page 不一定是 Page,比如搜索框,不是一个页面但我们可以抽象成一个功能,抽象成一个 page,因为它有独立的元素和统一的功能。它虽然叫 Page,但是 Page 只是一个抽象的概念,你把你认为可以归类成一个页面的东西抽象在一起就可以,既可以是页面的抽象,也可以是功能或模块的抽象。
以上就是个人对 PO 模式的一些简单的理解。不一定非常准确,但希望对新上手的测试人员有帮助。感谢,欢迎大家一起讨论。