1. 程式人生 > >python+selenium自動化軟件測試:裝飾器之用例失敗後截圖

python+selenium自動化軟件測試:裝飾器之用例失敗後截圖

功能 get war keys case 全局參數 ase when code

對於用例失敗截圖,很多小夥伴都希望用例執行失敗的時候能自動截圖,想法是很好的,實現起來並不是那麽容易,這裏小編分享下最近研究裝飾器,打算用裝飾器來實現自動截圖。

一、函數作為形參
1.函數的參數也可以是另外一個函數,也就是說傳的參數不僅可以是常見的字符串、數字等,也可以是一個函數。
2.定義aaa為一個加法函數,bbb為減法函數。
3.calculate這個函數傳三個參數,第一個參數是一個函數,另外兩個參數是函數的兩個參數。

技術分享

二、萬能裝飾器
1.由於不知道我們被調用的函數到底有幾個參數,這時候就可以寫一個萬能的裝飾器,傳可變參數。
2.這個裝飾器實現一個簡單功能:運行一個函數,運行不拋異常,就打印pass;運行函數拋異常就打印fail。

技術分享

三、實現百度搜索功能。

#實現百度搜索功能
# coding:utf-8
from selenium import webdriver
driver = webdriver.Firefox()
# 截圖功能
def get_screen():
    ‘‘‘截圖‘‘‘
    import time
    nowTime = time.strftime("%Y_%m_%d_%H_%M_%S")
    driver.get_screenshot_as_file(%s.jpg % nowTime)
# 自動截圖裝飾器
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("https://www.baidu.com") driver.find_element_by_id("kw11").send_keys("
python") # 此行運行失敗的 driver.find_element_by_id("su").click() search(driver) # 執行search

這裏介紹的是簡單的裝飾器函數,下面我來介紹復雜一點的帶參數的裝飾器。

裝飾器其實就是一個以函數作為參數並返回一個替換函數的可執行函數。
上面講到用裝飾器解決異常後自動截圖,不過並沒有與unittest結合,這篇把截圖的裝飾器改良了下,可以實現用例執行失敗自動截圖。

一、不帶變量的裝飾器
1.參考資料:http://www.artima.com/weblogs/viewpost.jsp?thread=240845,這裏這篇講的很好,可以看下原文。
2.這個是不帶變量的裝飾器__init__裏是初始化參數,__call__裏面是原函數參數。

Decorators without Arguments
If we create a decorator without arguments, the function to be decorated 
is passed to the constructor, and the __call__() method is called 
whenever the decorated function is invoked:
class decoratorWithoutArguments(object):
    def __init__(self, f):
        """
        If there are no decorator arguments, the function
        to be decorated is passed to the constructor.
        """
        print "Inside __init__()"
        self.f = f
    def __call__(self, *args):
        """
        The __call__ method is not called until the
        decorated function is called.
        """
        print "Inside __call__()"
        self.f(*args)
        print "After self.f(*args)"
@decoratorWithoutArguments
def sayHello(a1, a2, a3, a4):
    print sayHello arguments:, a1, a2, a3, a4

二、帶變量的裝飾器。
1.這個是帶變量的參數,參數寫到__init__裏。

Decorators with Arguments

Now lets modify the above example to see what happens when we add arguments to the decorator:
class decoratorWithArguments(object):
    def __init__(self, arg1, arg2, arg3):
        """
        If there are decorator arguments, the function
        to be decorated is not passed to the constructor!
        """
        print "Inside __init__()"
        self.arg1 = arg1
        self.arg2 = arg2
        self.arg3 = arg3
    def __call__(self, f):

   """
        If there are decorator arguments, __call__() is only called
        once, as part of the decoration process! You can only give
        it a single argument, which is the function object.
        """
        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 sayHello(a1, a2, a3, a4):
    print sayHello arguments:, a1, a2, a3, a4

三、截圖裝飾器
有了上面的參考文檔,依著葫蘆畫瓢就行,最大的麻煩就是driver參數處理,這裏放到__init__裏就可以了。

技術分享

四、參考案例

# coding:utf-8
from selenium import webdriver
class Screen(object):
    u‘‘‘這個應該截圖功能的裝飾器‘‘‘
    def __init__(self, driver):
        self.driver = driver
    def __call__(self, f):
        def inner(*args):
            try:
                return f(*args)
            except:
                import time
                nowTime = time.strftime("%Y_%m_%d_%H_%M_%S")
                self.driver.get_screenshot_as_file(%s.jpg % nowTime)
                raise
        return inner
# 以下是裝飾器與unittest結合的案例
import unittest
class Test(unittest.TestCase):
    driver = webdriver.Firefox()  # 全局參數driver
    def setUp(self):
        self.driver.get("https://www.baidu.com")
    @Screen(driver)
    def test01(self):
        u‘‘‘這個是失敗的案例‘‘‘
        self.driver.find_element_by_id("11kw").send_keys("python")
        self.driver.find_element_by_id("su").click()
    @Screen(driver)
    def test_02(self):
        u‘‘‘這個是通過的案例‘‘‘
        self.driver.find_element_by_id("kw").send_keys("yoyo")
        self.driver.find_element_by_id("su").click()
    def tearDown(self):
        self.driver.quit()
if __name__ == "__main__":
    unittest.main()

python+selenium自動化軟件測試:裝飾器之用例失敗後截圖