【Selenium05篇】python+selenium实现Web自动化:读取ini配置文件,元素封装,代码封装,异常处理,兼容多浏览器执行
一、前言
最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新!
这是python+selenium实现Web自动化第五篇博文
二、Selenium前四篇博文地址:
【Selenium01篇】python+selenium实现Web自动化:搭建环境,Selenium原理,定位元素以及浏览器常规操作!
【Selenium02篇】python+selenium实现Web自动化:鼠标操作和键盘操作!
【Selenium03篇】python+selenium实现Web自动化:元素三类等待,多窗口切换,警告框处理,下拉框选择
【Selenium04篇】python+selenium实现Web自动化:文件上传,Cookie操作,调用 JavaScript,窗口截图
三、Selenium之-读取元素配置文件
经过前面的学习,我们已经可以写一些简单的自动化测试用例,但是你们有没有感觉到我们写了大量的重复代码。例如:页面中关键元素的查找与传值。对于一个自动化测试页面来说页面的元素是相对于比较稳定的,那么我们就可以把这些重复性的代码封装起来,直接去读取页面中相对于稳定的元素就可以了,这些元素信息我们可以写在配置文件中,当页面元素发生变动时,只需要修改相应的页面元素信息即可,不用每次去修改代码,从而尽可能的避免引入bug。
1.创建配置文件
读取配置文件前,按页面元素的特点写进配置文件中。
[RegisterElement]
register_email = id>register_email
register_nickname = id>register_nickname
register_password = id>register_password
getcode_num = id>getcode_num
captcha_code = id>captcha_code
2.读取配置文件
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@Time : 2020/4/17
@Author : 公众号:软测之家 更多技术干货,软测视频,面试资料请关注!
@Contact : 软件测试技术群:695458161
@License : (C)Copyright 2017-2019, Micro-Circle
@Desc : None
""" import configparser class ReadIni(object):
# 初始化配置文件路径及节点加载
def __init__(self, file_name=None, node=None):
if file_name is None:
self.file_name = '../data/RegisterElement.ini'
if node is None:
self.node = 'RegisterElement'
else:
self.node = node self.cf = self.load_ini() # 加载配置文件
def load_ini(self):
cf = configparser.ConfigParser()
cf.read(self.file_name)
return cf # 获取各个配置项的值
def get_value(self, key):
data = self.cf.get(self.node, key)
return data if __name__ == "__main__":
ri = ReadIni()
print(ri.get_value('register_nickname'))
四、Selenium之-元素封装
查找页面元素代码封装。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@Time : 2020/4/17
@Author : 公众号:软测之家 更多技术干货,软测视频,面试资料请关注!
@Contact : 软件测试技术群:695458161
@License : (C)Copyright 2017-2019, Micro-Circle
@Desc : None
""" from util.read_ini import ReadIni class FindElement(object):
def __init__(self, driver):
self.driver = driver def get_element(self, key):
ri = ReadIni()
data = ri.get_value(key=key)
by = data.split('>')[0]
value = data.split('>')[1]
try:
if by == 'id':
return self.driver.find_element_by_id(value)
elif by == 'name':
return self.driver.find_element_by_name(value)
elif by == 'className':
return self.driver.find_element_by_className(value)
else:
return self.driver.find_element_by_xpath(value)
except:
file_path = '../image/no_element.png'
self.driver.save_screenshot(file_path) if __name__ == "__main__":
fe = FindElement()
fe.get_element('register_nickname')
五、Selenium之-代码封装
写到这里是不是感觉代码虽然写出来了,但是很没有条理性。是的,现在就把代码模块化,让其每个模块做一部分事情。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@Time : 2020/4/17
@Author : 公众号:软测之家 更多技术干货,软测视频,面试资料请关注!
@Contact : 软件测试技术群:695458161
@License : (C)Copyright 2017-2019, Micro-Circle
@Desc : None
""" from selenium import webdriver
from time import sleep
from util.read_ini import ReadIni
from basic.find_element import FindElement
import random
from PIL import Image
from api import ShowapiRequest class Register(object):
def __init__(self, url):
self.driver = self.get_driver(url=url) # 启动浏览器,打开目标测试页面url
def get_driver(self, url):
driver = webdriver.Chrome('../tools/chromedriver.exe')
driver.get(url=url)
driver.maximize_window()
return driver # 定位用户信息,获取元素element
def get_user_element(self, key):
find_element = FindElement(self.driver)
user_element = find_element.get_element(key=key)
return user_element # 输入用户信息
def send_user_info(self, key, data):
self.get_user_element(key=key).send_keys(data) # 获取随机数
def get_range(self):
number = ''.join(random.sample('abcdefg123456', 8))
return number # 获取验证码图片
def get_captcha_image(self, file_name):
self.driver.save_screenshot(filename=file_name)
captcha_element = self.get_user_element('getcode_num')
left = captcha_element.location['x']
top = captcha_element.location['y']
right = captcha_element.size['width'] + left
height = captcha_element.size['height'] + top
image = Image.open(file_name)
img = image.crop((left, top, right, height))
img.save(file_name) # 识别图片验证码
def discern_captcha_image(self, file_name):
self.get_captcha_image(file_name=file_name)
# 解析验证码图片中的文字(用第三方的图片验证码识别接口 ShowApiRequest)
r = ShowapiRequest("http://route.showapi.com/184-4", "48120", "12c017278c0845c2bcda177212d2d2ac")
r.addBodyPara("img_base64", "")
r.addBodyPara("typeId", "35")
r.addBodyPara("convert_to_jpg", "0")
r.addBodyPara("needMorePrecise", "0")
r.addFilePara("image", file_name) # 文件上传时设置
res = r.post()
text = res.json()["showapi_res_body"]["Result"]
return text # 主函数
def main(self):
register_nickname = self.get_range()
register_email = self.get_range() + '@163.com'
register_password = self.get_range() + '@123'
file_name = '../image/code_image.png'
captcha_code = self.discern_captcha_image(file_name=file_name)
self.send_user_info('register_nickname', register_nickname)
self.send_user_info('register_email', register_email)
self.send_user_info('register_password', register_password)
self.send_user_info('captcha_code', captcha_code)
self.get_user_element('register-btn').click()
sleep(5)
self.driver.close() if __name__ == "__main__":
register_url = 'http://www.5itest.cn/register'
r = Register(register_url)
r.main()
六、Selenium之-异常处理
测试中我们要让程序畅通运行的同时,也要注意对程序的异常进行处理。例如:由于调用的第三方接口来是被验证码图片,难免会出现识别不了的情况,为了不阻塞程序的正常运行,当识别出错的时候,可以对错误识别进行异常的处理。
# 在 [RegisterElement.ini] 文件添加验证码错误的元素id
captcha_code_error = id>captcha_code-error
# 在 package.py 代码的基础上加上异常处理
# 异常处理:注册失败进行截图,方便问题排查
captcha_code_error = self.get_user_element('captcha_code_error')
if captcha_code_error is None:
print("......恭喜你注册成功了......")
else:
self.driver.save_screenshot('../image/captcha_code_error.png')
sleep(5)
七、Selenium之-兼容多浏览器执行
在实际的测试中,由于不同浏览器的技术标准的差异,导致同一份代码在不同浏览器中的表现形式不一致,所以避免不了多浏览器执行测试用例。
注意:FireFox 驱动与 Chrome 的驱动配置不同
下载地址:https://github.com/mozilla/geckodriver/releases
下载后(根据系统版本选择):
(1)解压取出geckodriver.exe(以64x为例);
(2)将geckodriver.exe放到Firefox的安装目录下,如:(D:\火狐\Mozilla Firefox);
(3)将火狐安装目录(D:\火狐\Mozilla Firefox)添加到环境变量path中;
(4)重启 IDEA,记得一定要
# 兼容多浏览器执行测试
def get_more_driver(self, url, browser):
if browser == 'chrome':
# 版本 76.0.3809.100(64位)对应的驱动
driver = webdriver.Chrome('../tools/chromedriver.exe')
elif browser == 'firefox':
# FireFox 68.0.2(64位) 对应的驱动,和 chrome 驱动使用有差异
driver = webdriver.Firefox()
driver.get(url=url)
driver.maximize_window()
return driver
八、持续更新中请关注
如果你觉得此文对你有帮助,如果你对软件测试、接口测试、自动化测试、面试经验交流感兴趣欢迎加入:
软件测试技术群:695458161,群里发放的免费资料都是笔者十多年测试生涯的精华。还有同行大神一起交流技术哦。
作者:来自公众号:软测之家
出处:https://www.cnblogs.com/csmashang/p/12719064.html
原创不易,欢迎转载,但未经作者同意请保留此段声明,并在文章页面明显位置给出原文链接
【Selenium05篇】python+selenium实现Web自动化:读取ini配置文件,元素封装,代码封装,异常处理,兼容多浏览器执行的更多相关文章
- 【python+selenium的web自动化】- 8种元素定位方式详解
我们在做WEB自动化时,最根本的就是操作页面上的各种元素,而操作的基础便是元素的定位,只有准确地定位到唯一元素才能进行后续的自动化控制,下面将对各种元素定位方式进行总结归纳. 说明:以下操作统 ...
- 【Selenium01篇】python+selenium实现Web自动化:搭建环境,Selenium原理,定位元素以及浏览器常规操作!
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 二.话不多说,直接开干,开始搭建自动化测试环境 这里以前在 ...
- 【Selenium06篇】python+selenium实现Web自动化:日志处理
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第六篇博 ...
- 【Selenium07篇】python+selenium实现Web自动化:PO模型,PageObject模式!
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第七篇博 ...
- 【Selenium04篇】python+selenium实现Web自动化:文件上传,Cookie操作,调用 JavaScript,窗口截图
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第四篇博 ...
- 【Selenium02篇】python+selenium实现Web自动化:鼠标操作和键盘操作!
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第二篇博 ...
- 【Selenium03篇】python+selenium实现Web自动化:元素三类等待,多窗口切换,警告框处理,下拉框选择
一.前言 最近问我自动化的人确实有点多,个人突发奇想:想从0开始讲解python+selenium实现Web自动化测试,请关注博客持续更新! 这是python+selenium实现Web自动化第三篇博 ...
- python读取ini配置文件的示例代码(仅供参考)
这篇文章主要介绍了python读取ini配置文件过程示范,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 安装 pip install configp ...
- 【python+selenium的web自动化】- 元素的常用操作详解(一)
如果想从头学起selenium,可以去看看这个系列的文章哦! https://www.cnblogs.com/miki-peng/category/1942527.html 本篇主要内容:1.元素 ...
随机推荐
- 【Weiss】【第03章】练习3.18:检查平衡符号
[练习3.18]用下列语言编写检测平衡符号的程序 a.Pascal ( begin/end, ( ), [ ], { } ). b.C语言( /* */, ( ), [ ], { }). c.解释如何 ...
- 2. Plugin execution not covered by lifecycle configuration
问题: 找到当前项目的工作空间下的.metadata\.plugins\org.eclipse.m2e.core路径, 然后添加lifecycle-mapping-metadata.xml文件,内容如 ...
- JSP+Servlet+C3P0+Mysql实现的网上蛋糕店
本文存在视频版本,请知悉 项目简介 项目来源于:https://gitee.com/PositiveMumu/CakesShop/tree/master 这次分享一个蛋糕商场系统,还是很简单的系统.界 ...
- 深入理解JAVA字符串常量池
初学JAVA时,在学习如何比较两个字符串是否相等,大量资料告诉我,不能用等于号( = )去比较,需要使用equals方法,理由是String是一个对象,等号此时比较的是两个字符串在java内存堆中的地 ...
- MySQL数据库升级
当前不少系统的数据库依旧是MySQL5.6,由于MySQL5.7及MySQL8.0在性能及安全方面有着很大的提升,因此需要升级数据库.本文通过逻辑方式.物理方式原地升级来介绍MySQL5.6 升级至M ...
- hdu1856 并查集
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1856/ 题目就是要求并查集中各树的大小的最大值,我们只要在根节点处存树的大小就可以,合并也是合并根节点的数,最后 ...
- ImportError: libcusolver.so.8.0: cannot open shared object file: No such file or directory
问题描述: ImportError: libcusolver.so.8.0: cannot open shared object file: No such file or directory 首先检 ...
- NBL小可爱纪念赛「 第一弹 」 游记(部分题解)
比赛链接 洛谷:禁止含有侮辱性质的比赛 . ??? 反正我觉得,gyx挺危险的 不说废话. 首先,比赛经验,前几个小时不打,跟着刷榜. 一看 T1. 发现是道水题,直接切掉了. 然后看到了 T2. 感 ...
- 动态规划-01背包-Tallest Billboard
2020-02-07 17:46:32 问题描述: 问题求解: 解法一:BF 看问题规模看似可以直接暴力解决. 如果直接去解肯定是会超时的,因为每次将原空间划分成A区域,B区域和剩余区域的时间复杂度为 ...
- OSLab:开启保护模式
日期:2019/5/22 关键词:操作系统:OS:保护模式:A20地址线激活:分页开启:二级页表的设置 PS:OSLAB实验课的整理. 本文主要内容是分析操作系统中一个简易的MBR. 建议先阅读:ht ...