演练源代码地址
cookie登录
- 第一次登录一个域名,网站会在response header中加入set-cookie 头
- browser会保存cookie与domain
- 再次发起对相同domain的请求的时候,browser会把domain对应的cookie以cookie头的格式发送给对应的domain
#response set cookie
set-cookie: wwrtx.i18n_lan_key=zh-CN%2Czh%3Bq%3D0.9%2Cen-US%3Bq%3D0.8%2Cen%3Bq%3D0.7; Path=/; Expires=Tue, 03 Sep 2019 06:19:15 GMT
set-cookie: wwrtx.i18n_lan=zh-cn; Path=/; Expires=Tue, 03 Sep 2019 06:19:15 GMT
set-cookie: wwrtx.ref=direct; Domain=.work.weixin.qq.com; Path=/; HttpOnly
set-cookie: wwrtx.refid=18553809571155839; Domain=.work.weixin.qq.com; Path=/; HttpOnly
#第二次reqeust
cookie: wwrtx.i18n_lan_key=zh-CN%2Czh%3Bq%3D0.9%2Cen-US%3Bq%3D0.8%2Cen%3Bq%3D0.7; wwrtx.i18n_lan=zh-cn; wwrtx.ref=direct; wwrtx.refid=18553809571155839; _ga=GA1.2.1434878657.1564899555; _gid=GA1.2.358486227.1564899555
#登录
set-cookie: wwrtx.vst=bwwJzXzX7P30bdCMNff5DBmaUIkdDUQZYG-ynNp8Oi1d87eZZpJv8t-obxiDtpDRbKkRYnjHAbrvkZEeAlRqqcgXmuT1u24LsC7F1HkwrYmlU-zyg1d4vgzEM2jCVmUFD02KuvHf60UpRWs3WGzQ4pS-pc32aM0w7BTNKVE9srAU8jMWxrjgllRJlItc_ap3nKajZLdOVbrEUHw2kRiUn18BMwWNSo1-h2E4dkh5CmZ52AdZjhb_qOXYjQZjeVoC5yajQL041wAFbgkoRvGk5Q; Domain=.work.weixin.qq.com; Path=/; HttpOnly
set-cookie: wwrtx.d2st=a1678792; Domain=.work.weixin.qq.com; Path=/
set-cookie: wwrtx.sid=PvmFAAW3_ZQOnOfp5SzMi8wH6yHkmO-qU5JS55P3PM0Q8lrAI_GgrlcwvKitXKHf; Domain=.work.weixin.qq.com; Path=/; HttpOnly
set-cookie: wwrtx.ltype=1; Domain=.work.weixin.qq.com; Path=/; HttpOnly
set-cookie: wwrtx.tsid=; Domain=.work.weixin.qq.com; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly
set-cookie: wwrtx.tsid=; Domain=.work.weixin.qq.com; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly
set-cookie: wwrtx.gst=; Domain=.work.weixin.qq.com; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly
set-cookie: wxpay.corpid=1970325013047104; Domain=.work.weixin.qq.com; Path=/
set-cookie: wxpay.vid=1688853941438590; Domain=.work.weixin.qq.com; Path=/
#登录后发起请求
cookie: wwrtx.i18n_lan_key=zh-CN%2Czh%3Bq%3D0.9%2Cen-US%3Bq%3D0.8%2Cen%3Bq%3D0.7; wwrtx.i18n_lan=zh-cn; wwrtx.ref=direct; wwrtx.refid=18553809571155839; _ga=GA1.2.1434878657.1564899555; _gid=GA1.2.358486227.1564899555; wwrtx.vst=bwwJzXzX7P30bdCMNff5DBmaUIkdDUQZYG-ynNp8Oi1d87eZZpJv8t-obxiDtpDRbKkRYnjHAbrvkZEeAlRqqcgXmuT1u24LsC7F1HkwrYmlU-zyg1d4vgzEM2jCVmUFD02KuvHf60UpRWs3WGzQ4pS-pc32aM0w7BTNKVE9srAU8jMWxrjgllRJlItc_ap3nKajZLdOVbrEUHw2kRiUn18BMwWNSo1-h2E4dkh5CmZ52AdZjhb_qOXYjQZjeVoC5yajQL041wAFbgkoRvGk5Q; wwrtx.d2st=a1678792; wwrtx.sid=PvmFAAW3_ZQOnOfp5SzMi8wH6yHkmO-qU5JS55P3PM0Q8lrAI_GgrlcwvKitXKHf; wwrtx.ltype=1; wxpay.corpid=1970325013047104; wxpay.vid=1688853941438590
等待
隐式等待: 服务端会帮你轮询查找,全局性的
显式等待:客户端轮询查找 每找一次元素,等待一个间隔再次查找,知道条件匹配,一次性的
sleep:不建议,不稳定,网速差的会超过你的写死的等待时间,设置的大又会导致在网速好的时候,所有的用例都被拖慢速度。
def click_and_find(x):
self.click_by_js(*self._add)
return len(x.find_elements(By.XPATH, '//*[text()="取消"]'))>=1
WebDriverWait(self._driver, 5).until(click_and_find)
Page Object
- 2013 Martin Flower PageObject
- 2015 Selenium https://github.com/SeleniumHQ/selenium/wiki/PageObjects
- Selenium Python Client 6. Page Objects — Selenium Python Bindings 2 documentation
- Mozilla PyPOM https://pypom.readthedocs.io/en/latest/
PO原则
- The public methods represent the services that the page offers
- Try not to expose the internals of the page
- Generally don’t make assertions
- Methods return other PageObjects
- Need not represent an entire page
- Different results for the same action are modelled as different methods
方法意义
- 用公共方法代表UI所提供的功能
- 方法应该返回其他的PageObject或者返回用于断言的数据
- 同样的行为不同的结果可以建模为不同的方法
不要在方法内加断言
字段意义 - 不要暴露页面内部的元素给外部
- 不需要建模UI内的所有元素
企业微信业务用例
- BasePage: 通用的父类Page,完成driver的传递和共用的方法
- ProfilePage ContactPage:具体的页面所提供的方法封装
- TestContact:正常的测试用例
- WeworkPage:封装了driver的初始化过程
课后作业
以PO模式完成如下功能的业务测试
- 通讯录Page 新增
- 搜索结果页Profile 编辑 禁用 启动
- 管理工具Page goto添加图片
- 图片管理Page 添加图片
封装出完整的PO,把代码上传到github并贴项目git地址到回复里