PageObject设计模式实战
将PageObject项目分为七层。分别是:Base、Common、Data、Logs、PageObject、Reports、TestCases。
Base主要是负责一些基础方法,比如自己封装的定位方法、元素click操作、send Keys操作,调用JS脚本以及其他一些与基本浏览器相关的操作。
Common主要是负责一些数据的方法。比如:Excel文件的读取,获取项目的路径、测试系统的URL信息以及日志功能。
Data主要就是存放一些数据文件,例如Excel文件、CSV文件、XML文件。
Logs主要就是存放日志文件。
Reports主要就是存放运行测试脚本后生成的测试报告。
TestCases主要就是一些测试用例。
PageObject是PO的核心层,该层不但设计代码技术,还涉及对项目业务的分析,进而对相关的页面进行分析。
测试Demo:携程的订票
测试步骤:1. 打开 https://trains.ctrip.com/ 输入出发站和到达站,选择出发时间,点击查询,
2. 跳转到搜索详情页,然后找张机票选择预定,
3. 跳转到订单详情,输入乘客信息,然后点击提交按钮。
分析:
整个流程可以分为三个部分,分别是搜索、预定、订单。
搜索部分,我们需要操作的元素有四个,分别是出发站输入框、到达站输入框、出发时间、搜索按钮。
通过对页面分析,我们可以用id或者class对其进行定位。
注意:通过selenium的send_Key()方法,是不能对其进行赋值的,需要先执行JS语句,将readonly属性干掉,然后再清除默认值,最后进行赋值,并让其失去焦点。
那我们怎么判断是否跳转成功?这时就需要获取当前页面的url,然后查看查看当前页面的url是否包含字符串“trainBooking”
所以说搜索流程应该是这样的
# 定义查询火车票的方法 def search_train(self, depart_city, arrive_city, depart_date): """ 需要传递三个值,分别是出发城市、到达城市、出发时间""" # 传递数据 self.search_depart().send_keys(depart_city) sleep(2) self.search_arrive().send_keys(arrive_city) sleep(1.5) # 处理时间无法输入的问题 self.JS("document.getElementById('departDate').removeAttribute('readonly')") # 清空时间的默认值 self.JS("document.getElementById('departDate').value=''") sleep(1.5) self.search_date().send_keys(depart_date) # 使时间输入框失去焦点 self.JS("document.getElementById('departDate').blur()") sleep(1) self.search_btn().click() sleep(2) return self.getURL()
预定部分:预定比较简单,就只有一个操作元素,那就是预定按钮。
通过className获取该元素,然后调用该元素的click方法即可。然后还是获取跳转后的url,看其是否包含“InputPaserage”
注意点:这里的预定比较简单,平日订票肯定还会考虑列车类型、全程时长等因素,在这暂不考虑。
因此,预定的流程如下
# 定义预定操作 def search_reserve(self): self.search_reserve_btn()[1].click() sleep(3) print("预定后,当前页面的链接是" + self.driver.current_url) # return self.getURL() return self.getURL()
最后一部分,填写订单
首先还是要通过id或者className来定位元素,并发送数据。然后点击提交按钮,因为输入的数据不具有合法性,所以提交时会产生提示界面。如何判断我们是否输入成功,就判断该界面是否弹出,换句话说就是该界面的状态是否是block。
订单的流程如下
# 填写信息,并提交订单 def search_order(self, name, card, phone): """姓名、身份证号、手机号""" self.search_inputName().send_keys(name) self.search_card()[0].send_keys(card) self.search_card()[1].send_keys(phone) self.search_phone().send_keys(phone) self.search_btn().click() sleep(2) # 执行JS脚本,获取提示框的状态并返回 默认是none。 block # msg = self.JS("document.getElementById('ordercrrortip').style.display") # msg = self.JS("document.getElementById('ordercrrortip').style.display")/ msg = self.findEle(By.ID, 'ordercrrortip').get_attribute('style') print(msg) return msg
综上所述,携程订票的整体结构应该如下:
POProject
--Base
---base.py 主要是自己封装的定位方法和其他浏览器常用操作
--Common
--excelData.py 对表格数据的读取
--function.py 规定项目的路径、项目测试的URL
--log.py 自己封装的logger类,用于日志的打印
--Data
--testData.xlsx 数据文件
--Logs
--产生的日志文件
--PageObject
--search_Order.py 订单的业务
--search_Reserve.py 预定的业务
--search_Train.py 查询车票的业务
--Reports
--测试报告
--TestCases
--test_01.py 测试用例
config.ini PO分层的配置文件