python基于selenium进行自动化测试,实现断言失败进行截图
进行自动化测试过程中,经常会遇见断言失败,时候补查失败的场景,要么是保存日志,要么就是保存失败的截图。尝试实现,在断言失败时候,加入实时截图:
编码出错 遇到问题: 截图文件名编码格式转换时候,会报错(以下写法在python 2.7可以使用)
1 pic_path = os.path.join(save_path, str(pic_name).decode("utf-8").encode("gbk") + ".png")
报错:
1 AttributeError: 'str' object has no attribute 'decode'
查找原因: 既然python 2.7可以正常执行,那就应该是python 3对于编码进行了变更。
Stack Overflow上大家好像都是经常踩我踩过的所有坑..又找到答案了: 这位大哥的回答:
1 2 3 4 Begin with Python 3, all string is unicode object. a = 'Happy New Year' # Python 3 b = unicode('Happy New Year') # Python 2 the code before are same. So I think you should remove the .decode('utf-8'). Because you have already get the unicode object.
python3的普通字符串是str,所以python3的str就相当于python2的Unicode。大致意思好像就是python3使用的str类型并不关心你最终是什么编码,无论是utf-8还是gb2312,它只是用Unicode字符集编码来表示每一个字符,直到输出到文件流,需要转换为bytes类型时,才用encode指定具体的编码实现方式。
python的中间编码是Unicode,所以python2就需要先进行解码(decode)到中间编码,再进行编码(encode)到指定编;,而python3直接可以转换到指定编码(encode)
1 在python3中,str-- encode -> bytes-- decode -> str
python3编码 系统编码
1 2 3 4 5 6 7 8 9 10 11 12 import sys # 系统默认编码 print(sys.getdefaultencoding()) # 字符串编码 s = "中文" s_utf8 = s.encode('utf-8') print(type(s)) print(type(s_utf8)) utf-8 <class 'str'> <class 'bytes'>
可以看到,python3的系统编码就是utf-8,为了避免自找麻烦,牢记使用utf-8即可! 所以上述报错代码可以更改为:
1 pic_path = os.path.join(save_path, str(pic_name) + ".png")
断言失败截图实例 实现目标是在进行自动化测试过程中,一旦发生断言失败,就根据当前时间,在工程下创建名称为当前日期的目录,,目录下创建名称为当前时间的文件夹,文件夹中保存断言失败的屏幕截图
获取当前日期和时间 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import time from datetime import datetime as dt """ 用于获取当前的日期以及时间 用于生成保存截图文件目录名 """ def current_date(): date = time.localtime() # 构造今天的日期字符串 today = str(date.tm_year) + "-" + str(date.tm_mon) + "-" + str(date.tm_mday) return today def current_time(): time_str = dt.now() # 构建当期时间字符串 now = time_str.strftime('%H-%M-%S') return now
创建目录和文件夹 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #!/usr/bin/env python3 # -*- coding: utf-8 -*- from DateUtil import current_time, current_date import os """ 用于创建目录,用于存放异常截图 """ def create_dir(): # 获得当前文件所在目录的绝对路径 current_path = os.path.abspath('.') # 获取今天的日期字符串 today = current_date() # 构造以今天日期命名的目录的绝对路径 date_dir = os.path.join(current_path, today) print(date_dir) if not os.path.exists(date_dir): # 如果以今天日期命名的目录不存在则创建 os.mkdir(date_dir) # 获取当前的时间字符串 now = current_time() # 构造以当前时间命名的目录的绝对路径 time_dir = os.path.join(date_dir, now) print(time_dir) if not os.path.exists(time_dir): # 如果以当前时间命名的目录不存在则创建 os.mkdir(time_dir) return time_dir
百度搜索示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #!/usr/bin/env python3 # -*- coding: utf-8 -*- from selenium import webdriver from FileUtil import create_dir from nose.tools import assert_true import time,os import traceback # 创建存放异常截图的目录,并得到本次实例中存放图片目录的绝对路径,作为全局变量,供本次所有测试用例调用 pic_dir = create_dir() def take_screenshot(driver, save_path, pic_name): # 封装截屏方法 # 构造屏幕截图路径及图片名 # 因为windows默认编码是GBK,而传入的图片名是utf-8编码,所以需要进行转码,以便让图片名中的中文字符能够正常显示 pic_path = os.path.join(save_path, str(pic_name) + ".png") try: # 调用webdriver提供的get_screenshot_as_file()方法,将截取的屏幕图片保存为本地文件 driver.get_screenshot_as_file(pic_path) except Exception as e: print(traceback.print_exc(), e) class TestFailCaptureScreen(): def __init__(self): """启动浏览器""" self.browser = webdriver.Chrome() def test_baidu_search(self): url = "https://www.baidu.com" self.browser.get(url) try: self.browser.find_element_by_id('kw').send_keys(u"自动化测试") self.browser.find_element_by_id('su').click() time.sleep(3) # 断言页面的代码中是否存在“自动化测试框架_百度百科”这几个字 assert_true(u"纯净方糖" in self.browser.page_source) # 页面中没有断言的几个字,所以会触发except语句的执行,并触发截图操作 except AssertionError as e: take_screenshot(self.browser, pic_dir, e) except Exception as e: take_screenshot(self.browser, pic_dir, e) time.sleep(2) self.browser.quit() if __name__ == '__main__': testfailscreen = TestFailCaptureScreen() testfailscreen.test_baidu_search()
感觉是时候研究一波python字符编码了…