更多内容请查看:
从零开始搭建WEB自动化框架01 —— Pytest 使用
本系列学习文章适合的对象为已经掌握 Selenium 基础用法,并有一定实践经验的同学。同时,希望你可以理解 Page Object Model 设计模型。
开始本篇前,请确认已经完成此前文章的阅读。
POM 设计模式
这个设计概念,其实是 MVC 模式的一种变形。
MVC会将页面,数据和控制器完全的分离,这样在开发时只需要专注在一端即可。
而POM也有类似的好处,我们在编写UI自动化用例的时候,经常受困于某个按钮,文字的修改,从而导致大量的修改,尤其是当用例量变大的时候,更是会陷入无法修改的情况。如果将按钮当成一个对象,而用例的操作是调用这个对象,那么当这个对象有修改的时候,我们只需要修改这个对象,就可以将相关的用例都修改,减少了非常多操作。
总而言之,就是让页面内容和底层逻辑,用例代码进行分离,以更好,更快的响应 APP 的改变。
当然在理解 POM 之前,你应该是一个对类有一定了解的人。
初次接触 POM ,其实只需要理解这几个东西就可以了:页面对象,元素对象,类函数。
页面对象化
接上篇,先复习一下登录代码:
# test_1.py
class Test1(object):
def test_js_login_success(self, driver):
phone_input = driver.find_element_by_xpath("//input[contains(@id,'session_email_or_mobile_number')]")
pwd_input = driver.find_element_by_xpath("//input[contains(@id,'session_password')]")
login_btn = driver.find_element_by_xpath("//button[contains(@id,'sign-in-form-submit-btn')]")
phone_input.send_keys('139********')
pwd_input.send_keys('********')
login_btn.click()
我们会发现,这段代码和一般没有使用框架的代码一模一样,将各种元素的寻址方式和寻址的值都直接写在测试用例中,这当然是一个非常不好的编码方式。具体的问题网上也说了很多,我们就不细说了。直接开始改造。
新建一个页面类文件 login_page.py
# login_page.py
class LoginPage(object):
def __init__(self, driver):
self.phone_input = driver.find_element_by_xpath("//input[contains(@id,'session_email_or_mobile_number')]")
self.pwd_input = driver.find_element_by_xpath("//input[contains(@id,'session_password')]")
self.login_btn = driver.find_element_by_xpath("//button[contains(@id,'sign-in-form-submit-btn')]")
同时修改测试文件内容。
# test_1.py
from login_page import LoginPage
class Test1(object):
def test_js_login_success(self, driver):
login_page = LoginPage(driver)
login_page.phone_input.send_keys('139********')
login_page.pwd_input.send_keys('********')
login_page.login_btn.click()
可以看到,再将页面元素的定义移动到一个类中时,测试用例明显的简洁了很多。其实,POM最核心的一个概念就是将页面元素的定义,集中到一个类中。
这中间当然还有非常多可以拓展的项目,比如元素的重新定义,操作步骤的LOG输出等等内容,各位如果有兴趣,可以自己去尝试一下。
定义好了页面,改造好了用例,我们再执行一遍。
============================= test session starts ==============================
platform darwin -- Python 3.7.5, pytest-4.5.0, py-1.8.0, pluggy-0.11.0
rootdir: /Users/ning/ddjf/web_learn_jianshu
plugins: rerunfailures-7.0, metadata-1.8.0, html-1.20.0, allure-pytest-2.6.3collected 1 item
test_1.py [100%]
=========================== 1 passed in 3.32 seconds ===========================
最终得到通过的测试结果。因为我们并没有写上任何的日志信息,所以结果非常的单薄和单调。不过我们总算是将一个最简单的基于 POM 设计的测试用例写出来了。
不过我们还是有很多没做好的地方,比如说我们以当前的形式去写一个元素时,他们自身的方法无法直接调用,在使用上会很麻烦。所以我们接下来准备解决这个问题。