0
点赞
收藏
分享

微信扫一扫

selenium - 用例执行失败后自动截图(装饰器)

624c95384278 2022-07-12 阅读 75

循序渐进的方式介绍(也可以直接到步骤4中看示例模板)

 

1. 简单示例:

from selenium import webdriver
import time
driver = webdriver.Chrome()


def get_screen():
now_time = time.strftime('%Y_%m_%d_%H_%M_%S')
driver.get_screenshot_as_file(f'{now_time}.jpg')


def screen(func): # 自动截图装饰器
def inner(*args, **kwargs): # 由于我们不知道被调用的函数到底有几个参数,写一个万能装饰器,传可变参数
try:
f = func(*args, **kwargs)
# return f
except:
get_screen() # 失败后截图
# raise
return inner


@screen # 加装饰
def search(driver):
driver.get('http://www.baidu.com')
driver.find_element_by_id('kw11').send_keys('python') # id不对,会运行失败
driver.find_element_by_id('su').click()
time.sleep(5)
driver.quit()


search(driver) # 执行

以上代码,会发现driver作为全局变量存在,无法传入装饰器中。同时,也没有和unittest结合。我们对此进行改良。 

 

2. 不带参数的装饰器

  • 被装饰的函数,传入__init__()
  • 调用被装饰的函数时,自动调用__call__()

__init__()里是初始化参数,__call__()里是原函数参数

class decoratorWithoutArguments(object):
def __init__(self, f): # 被装饰的函数,传入__init__()
print('inside __init__()')
self.f = f

def __call__(self, *args): # 调用被装饰的函数时,自动调用__call__()
print('inside __call__()')
self.f(*args)
print('after self.f(*args)')


@decoratorWithoutArguments # 不带参数
def say_hello(a1, a2):
print('say hello arguments: ', a1, a2)


say_hello(2, 3)

运行结果如下:

inside __init__()
inside __call__()
say hello arguments: 2 3
after self.f(*args)

 

3. 带参数的装饰器

  • 参数写到__init()__里
  • 被装饰的函数传入__call()__

class decoratorWithArguments(object):
def __init__(self, arg1, arg2, arg3): # 传入装饰器参数
print('inside __init__()')
self.arg1 = arg1
self.arg2 = arg2
self.arg3 = arg3

def __call__(self, f): # 可以只给它传一个参数 -- 被装饰的函数
print('inside __call__()')

def wrapped_f(*args):
print('inside wrapped_f()')
print('decorator arguments: ', self.arg1, self.arg2, self.arg3)
f(*args)
print('after f(*args)')
return wrapped_f


@decoratorWithArguments('hello', 'world', 42) # 带参数
def say_hello(a1, a2, a3, a4):
print('say_hell0 arguments: ', a1, a2, a3, a4)


say_hello(1, 2, 3, 4)

运行结果如下:

inside __init__()
inside __call__()
inside wrapped_f()
decorator arguments: hello world 42
say_hell0 arguments: 1 2 3 4
after f(*args)

 

so,可以尝试按此方法,将浏览器驱动传入装饰器中

 

4. 结合unittest

 百度首页为例,有异常时截图,代码如下:

from selenium import webdriver
import unittest
import time


class Screen(object):
def __init__(self, driver):
self.driver = driver

def __call__(self, func):
def inner(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
now_time = time.strftime('%Y_%m_%d_%H_%M_%S') # 异常时,截图
self.driver.get_screenshot_as_file(f'{now_time}.png')
raise # 抛出异常,不然会认为测试用例执行通过
return inner


class MyTest(unittest.TestCase):
driver = webdriver.Chrome()

@classmethod
def setUpClass(cls):
cls.driver.get('http://www.baidu.com')

@Screen(driver)
def test_01(self):
self.driver.find_element_by_id('kw').clear()
self.driver.find_element_by_id('kw').send_keys('python')
self.driver.find_element_by_id('su1').click() # id不对,会报错
time.sleep(3)

@Screen(driver)
def test_02(self):
self.driver.find_element_by_id('kw').clear()
self.driver.find_element_by_id('kw').send_keys('selenium')
self.driver.find_element_by_id('su').click()
time.sleep(3)

@classmethod
def tearDownClass(cls):
cls.driver.quit()


if __name__ == '__main__':
unittest.main()

截图如下:

selenium - 用例执行失败后自动截图(装饰器)_ide

 



举报

相关推荐

0 条评论