原生的 unittest 框架是不支持 case 失败后自动截图的功能的,网上看了大家的解决办法,大体上分为两种:
1、要么加装饰器
2、也有人封装断言
这里我们看看还有没有其他的更加方便的方法值得大家一起探讨一下:
如果使用 selenium 的话(相比于 selenium,我更加喜欢 airtest,这个后面的文章会提到 airtest 的 UI 自动化设计),我们知道不管是 sendkeys、click、doubleclick 等操作还是 assert 都会去调用 find_element 方法,我们完全可以在找不到元素的时候就进行截图呀,这样需要重新封装一下 find_element 方法即可。如下就是一个解决方案:
def find_element(self, *loc):
"""
重封装的find方法,接受元祖类型的参数,默认等待元素5秒,寻找失败时自动截图
:param loc:元组类型,必须是(By.NAME, 'username')这样的结构
:return:元素对象webelement
"""
try:
webelement = WebDriverWait(self.operate_driver, 5).until(lambda x: x.find_element(*loc))
return webelement
#except (TimeoutException, NoSuchElementException,AttributeError) as e:
except Exception as e:
# 截图路保存径,绝对路径,也可以用相对路径
SCREENSHOTURL = r"C:\Users\Administrator\Desktop\UItest\screenshot\\"
# 时间样式
ISOTIMEFORMAT = '%Y%m%d%H%M%S'
#寻找失败时自动截图至指定目录sreenshot,截图名称为调用方法名(测试用例名)+ 时间戳 + png后缀
self.operate_driver.get_screenshot_as_file(SCREENSHOTURL + sys._getframe(1).f_code.co_name + '_' + time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))+".png")
上面所说的当找不到元素的时候会自动截图的方法只能部分的解决的用例失败的截图问题,有时候可能元素能够找到但是 case 依然会失败。这个时候就需要下面的一种方法:用例执行失败后自动截图。这种方法也更加适合 UI 自动化设计的原始目的。
Unittest 支持 setup 和 teardown,是否可以创建一个主类,主类里面设计好每条 case 执行前要做什么,每条 case 执行后要做什么。暂且我们先不管 setup,要满足在每条 case 失败后自动截图的功能,我们可以只在 teardown 里面下点功夫即可。话不多说直接上代码:
# 主测试类继承自测试框架unittest
class MainCase(unittest.TestCase):
# 声明一个webdriver
#driver = WebChrome()
driver = webdriver
base_url = ReadWritePara('common', 'base_url').get_value()
#在allure报告中初始化环境信息
def setUp(self):
# 测试之前,启动浏览器,打开一个设定好的网址
self.driver = webdriver.Chrome()
#print(self.driver)
self.driver.get(self.base_url)
#最大化窗口,防止下窗口情况下图片不匹配
self.driver.maximize_window()
def tearDown(self):
# 当用例执行失败后会自动截图
if len(self._outcome.errors) >= 1:
print(self.driver)
allure.attach(" ", self.driver.get_screenshot_as_png(), type=AttachmentType.PNG)
# 测试完毕的时候关闭浏览器
self.driver.quit()
if __name__ == '__main__':
unittest.main()
单条测试用例可以继承 MainCase 即可,这样就可以做到当 case 执行失败,自动保存截图
上面仅仅个人观点,欢迎大家来探讨