🔥《手把手教你》系列进阶篇之4-python+selenium自动化测试-python几种神操作你都知道吗?(详细教程)
1.简介
今天分享和讲解的超神操作,对于菜鸟来说是超神的操作,对于大佬来说也就是几个简单方法的封装和调用。这里讲解和分享这部分主要是为了培养小伙伴们和童鞋们的面向对象的开发思维,对比这样做的好处让你自己身临其境的感受一番。
2.自定义封装一个简单的Log类
本文介绍如何写一个Python日志类,用来输出不同级别的日志信息到本地文件夹下的日志文件里。为什么需要日志输出呢,我们需要记录我们测试脚本到底做了什么事情,最好的办法是写事件监听。这个事件监听,对我们现在来说,还是有点复杂去理解,所以我这里,选择封装一个简单的日志类,同样达到这个效果。
我们大概需要如下日志输出效果:
2.1问题分析
我们需要封装一个简单的日志类,主要有以下内容:
1.生成的日志文件格式是年月日时分秒.log
2.生成的xxx.log文件存储在项目根目录下Logs文件夹下
3.这个日志类,支持INFO,ERROR两种日志级别
4.日志里,每行日志输出,如上图,时间日期+执行类名称+日志级别+日志描述
2.2解决问题思路
1.在根目录下新建一个Logs的文件夹,如何获取这个Log的相对路径,前面介绍过。
2.日志的保存命名,需要系统时间,前面也介绍过时间格式化输出
3.Python中有一个logging模块来支持我们自定义封装一个新日志类。
4.在脚本里,初始化一个日志类的实例对象,然后去控制输出INFO还是ERROR日志信息。
自定义日志类封装如下:logger.py,新建在test包下
2.3代码实现
2.4参考代码
#coding=utf-8🔥
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Createdon2019-12-16
@author:北京-宏哥QQ交流群:705269076
Project:《手把手教你》系列进阶篇之4-python+selenium自动化测试-python基础扫盲
'''
#3.导入模块
importlogging
importos.path
importtime
classLogger(object):
def__init__(self,logger):
"""
指定保存日志的文件路径,日志级别,以及调用文件
将日志存入到指定的文件中
:paramlogger:
"""
#创建一个logger
self.logger=logging.getLogger(logger)
self.logger.setLevel(logging.DEBUG)
#创建一个handler,用于写入日志文件
rq=time.strftime('%Y%m%d%H%M',time.localtime(time.time()))
print(os.getcwd())
log_path=(os.path.dirname(os.getcwd()+'\\Logs\\'))
print(log_path)
log_name=log_path+rq+'.log'
fh=logging.FileHandler(log_name)
fh.setLevel(logging.INFO)
#再创建一个handler,用于输出到控制台
ch=logging.StreamHandler()
ch.setLevel(logging.INFO)
#定义handler的输出格式
formatter=logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
#给logger添加handler
self.logger.addHandler(fh)
self.logger.addHandler(ch)
defgetlog(self):
returnself.logger
2.5新建日志测试类
新写一个测试日志类,相关代码如下:
2.5.1代码实现
2.5.2参考代码
#coding=utf-8🔥
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Createdon2019-12-16
@author:北京-宏哥QQ交流群:705269076
Project:《手把手教你》系列进阶篇之4-python+selenium自动化测试-python基础扫盲
'''
#3.导入模块
importtime
fromseleniumimportwebdriver
fromtest1.loggerimportLogger
mylogger=Logger(logger='test_log').getlog()
classTestMyLog(object):
defprint_log(self):
driver=webdriver.Chrome()
mylogger.info("打开浏览器")
driver.maximize_window()
mylogger.info("最大化浏览器窗口。")
driver.implicitly_wait(8)
driver.get("https://www.baidu.com")
mylogger.info("打开百度首页。")
time.sleep(1)
mylogger.info("暂停一秒。")
driver.quit()
mylogger.info("关闭并退出浏览器。")
testlog=TestMyLog()
testlog.print_log()
2.5.3运行结果
运行代码后,控制台打印如下图的结果
2.5.4文件保存结果
运行代码后,在Logs文件夹下可以看到日志文件,如下图的结果
在PyCharm里运行下这个测试类,会在根目录下的Logs文件下,新建一个日志文件,打开效果如文章开头的日志输出图。好了,关于自定义封装log类,自己好好去读下代码,理解下每行代码的意思,日志类的封装和调用就介绍到这里。
3.把截图类方法封装到前面的BasePage.py
本文介绍把截图类方法封装到BasePage.py文件里,这个文件是在前面Selenium方法二次封装文章里创建的,具体代码请到前面这篇里找。我们截图类写死了把截图图片保存到根目录下的Screenshots文件夹里,图片名称是当前系统时间,图片后缀名是png。
新的BasePage.py内容如下:
3.1代码实现
3.2参考代码
#coding=utf-8🔥
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Createdon2019-12-16
@author:北京-宏哥QQ交流群:705269076
Project:《手把手教你》系列进阶篇之4-python+selenium自动化测试-python基础扫盲
'''
#3.导入模块
importos
importtime
fromtest1.loggerimportLogger
mylog=Logger(logger='BasePage').getlog()
classBasePage(object):
"""
主要是把常用的几个Selenium方法封装到BasePage这个类,我们这里演示以下几个方法
back()
forward()
get()
quit()
"""
def__init__(self,driver):
"""
写一个构造函数,有一个参数driver
:paramdriver:
"""
self.driver=driver
defback(self):
"""
浏览器后退按钮
:paramnone:
"""
self.driver.back()
defforward(self):
"""
浏览器前进按钮
:paramnone:
"""
self.driver.forward()
defopen_url(self,url):
"""
打开url站点
:paramurl:
"""
self.driver.get(url)
defquit_browser(self):
"""
关闭并停止浏览器服务
:paramnone:
"""
self.driver.quit()
deftake_screenshot(self):
"""
截图并保存在根目录下的Screenshots文件夹下
:paramnone:
"""
file_path=os.path.dirname(os.getcwd())+'/Screenshots/'
rq=time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
screen_name=file_path+rq+'.png'
try:
self.driver.get_screenshot_as_file(screen_name)
mylog.info("开始截图并保存")
exceptExceptionase:
mylog.error("出现异常",format(e))
3.3新建截图类
主要看最后一个截图类方法的封装。
测试类相关代码如下:
3.3.1代码实现
3.3.2参考代码
#coding=utf-8🔥
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Createdon2019-12-16
@author:北京-宏哥QQ交流群:705269076
Project:《手把手教你》系列进阶篇之4-python+selenium自动化测试-python基础扫盲
'''
#3.导入模块
importtime
fromseleniumimportwebdriver
fromblog.basepageimportBasePage
classTestScreenshot(object):
driver=webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
basepage=BasePage(driver)
deftest_take_screen(self):
self.basepage.open_url("https://www.baidu.com")
time.sleep(1)
self.basepage.take_screenshot()
self.basepage.quit_browser()
test=TestScreenshot()
test.test_take_screen()
3.3.3运行结果
运行代码后,控制台打印如下图的结果
3.3.4截图保存结果
运行代码后,在Screenshots文件夹下可以看到截图文件,如下图的结果
运行后,可以在根目录下Screenshots文件夹里找到百度首页截图。
本文就介绍了截图类方法添加到BasePage里,介绍了如何保存到根目录下的Screenshots文件夹。
4.Python中的继承的使用
本文开始介绍一个面向对象设计领域里,很常见的一种思想,继承。继承有很多好处,常听到的一句话就是,子类能够直接使用父类的方法,这样就可以减少子类代码量。其实,在自动化测试框架设计过程中,是很有必要把继承加入到你的测试脚本中去。接下来我们,简单写一个Python文件,来演示下继承的基本使用。
4.1新建classA.py
1.在test1包名下新建一个classA.py,这个就是我们的父类,里面有一个打开chrome浏览器和打开百度首页的方法。
4.1.2代码实现:
4.1.3参考代码
#coding=utf-8🔥
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Createdon2019-12-16
@author:北京-宏哥QQ交流群:705269076
Project:《手把手教你》系列进阶篇之4-python+selenium自动化测试-python基础扫盲
'''
#3.导入模块
fromseleniumimportwebdriver
importtime
classClassA(object):
defopen_baidu(self):
driver=webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com")
time.sleep(1)
driver.quit()
4.2新建classB.py
1.在test2包下新建一个classB.py文件,这个继承classA.py里的ClassA类。
4.2.1代码实现
4.2.2参考代码
#coding=utf-8🔥
#1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''
Createdon2019-12-16
@author:北京-宏哥QQ交流群:705269076
Project:《手把手教你》系列进阶篇之4-python+selenium自动化测试-python基础扫盲
'''
#3.导入模块
fromtest1.classAimportClassA
classClassB(ClassA):
deftest_inherit(self):
self.open_baidu()
test=ClassB()
test.test_inherit()
4.2.3运行结果
运行代码后,控制台打印如下图的结果
通过上面可以看出,只需要一句代码就可以实现ClassA中的方法,这个就是继承的好处,减少了很多代码的书写,提高代码的复用。在定义ClassB的时候就要指明ClassB的父类是ClassA.继承相关的话题就介绍到这里,将在后面自动化框架设计会再次提到。
5.小结
5.1中文乱码
遇到的问题:细心地小伙伴或者同学们会发现在日志文件中的内容或出现中文乱码,如下图示:
解决办法:在FileHandler此处要设置encoding格式,
fh=logging.FileHandler(log_name,encoding='utf-8')
修改后,运行代码日志文件内容如下图所示:
5.2路径问题
因为宏哥在代码实践的过程中这部分遇到小问题,就是日志文件和截图放不在指定的文件夹下,所以这里拿出来单独说一下。
#创建一个handler,用于写入日志文件
rq=time.strftime('%Y%m%d%H%M',time.localtime(time.time()))
#当前目录
print(os.getcwd())
#根目录
print(os.path.dirname(os.getcwd()))
#log_path=(os.path.dirname(os.getcwd())+'\\Logs\\')
log_path=os.getcwd()+'\\Logs\\'
print(log_path)
代码说明:
os.getcwd():获取的当前最外层调用的脚本路径,即getPath所在的目录也可描述为起始的执行目录,A调用B,起始的是A,那么获取的就是A所在的目录路径。
os.path.dirname():去掉脚本的文件名,返回目录。
好了,今天的分享就到这里吧!!!谢谢各位的耐心阅读。