數(shù)據(jù)驅(qū)動---ddt

一、背景

一般進(jìn)行接口測試時,每個接口的傳參都不止一種情況,一般會考慮正向、逆向等多種組合,所以在測試一個接口時,通常會編寫多條case,而這些除了傳參不同外,并沒有什么區(qū)別。這個時候就可以利用ddt來管理測試數(shù)據(jù),提高代碼復(fù)用率。

二、ddt安裝

ddt是python的第三方庫,安裝非常簡單:

pip install ddt

ddt官方文檔地址:https://pypi.org/project/ddt/

三、ddt模塊組成

1、ddt模塊包含類的裝飾器ddt和兩個方法裝飾器data

  • ddt.ddt:裝飾類,也就是繼承TestCase的類。

  • ddt.data:裝飾測試方法,參數(shù)是一系列的值。

  • ddt.file_data:裝飾測試方法,參數(shù)是文件名。文件可以是json或者yaml類型。

    注意,如果文件是以“.yml”或者".yaml"結(jié)尾,ddt會作為yaml類型處理,其他文件都會作為json文件處理。

    如果文件是列表,列表的值會作為測試用例參數(shù),同時,會作為測試用例方法名后綴顯示。

    如果文件是字典,字典的key會作為測試用例方法的后綴顯示,字典的value會作為測試用例參數(shù)。

  • ddt.unpack:傳遞的是復(fù)雜的數(shù)據(jù)結(jié)構(gòu)時使用,比如使用列表或者元組,添加unpack后,ddt會自動把元組或者列表對應(yīng)到多個參數(shù)上。

2、測試用例方法名生成規(guī)則

使用ddt后,會產(chǎn)生一個新的測試用例方法名,即定義的測試用例方法名,比如:def test_one(),這里就是test_one。

data:如果傳遞過來的數(shù)據(jù)存在__ name__ 屬性,則這里就是該數(shù)據(jù)的__ name__ 值。如果未定義__ name__ 屬性,ddt會盡量將傳遞過來的值轉(zhuǎn)化為python標(biāo)識符,作為data顯示。比如:(1,3)就轉(zhuǎn)為1_3。需要注意的是,如果數(shù)據(jù)是字典,則這里就是字典的key。

四、示例

1、使用data傳參數(shù)給測試用例

from ddt import ddt,data,file_data,unpack
import unittest

@ddt
class MyTestDdt(unittest.TestCase):
    def setUp(self):
        print('start')

    @data(2,4)#使用data傳參數(shù)給測試用例
    def test_one(self,value):
        print(f'the @data number is :{value}')

    def tearDown(self):
        print('end')

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

結(jié)果:

start
test_one_1_2 (__main__.MyTestDdt) ... ok
the @data number is :2
end
start
the @data number is :4
test_one_2_4 (__main__.MyTestDdt) ... ok
end

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

可以看出data分別傳參數(shù)2和4給測試用例,然后測試用例執(zhí)行了兩遍。另外,注意此時打印出的測試用例名稱已經(jīng)不同,比如:test_one_1_2和test_one_2_4,最后的2和4,分別是傳遞進(jìn)去的參數(shù)。

2、使用unpack分解list或者tuple

from ddt import ddt,data,file_data,unpack
import unittest

@ddt
class MyTestDdt(unittest.TestCase):
    def setUp(self):
        print('start')

    @data((1,2),(4,5)) #元組
    @unpack #分解
    def test_one(self,value1,value2):
        print(f'the @data number is :{value1,value2}')

    def tearDown(self):
        print('end')

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

結(jié)果:

start
the @data number is :(1, 2)
end
test_one_1__1__2_ (__main__.MyTestDdt) ... ok
start
the @data number is :(4, 5)
test_one_2__4__5_ (__main__.MyTestDdt) ... ok

end
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK

可以看出data分別傳元組參數(shù)(1,2)和(4,5)給測試用例,然后測試用例執(zhí)行了兩遍。另外,注意此時打印出的測試用例名稱已經(jīng)不同,比如:test_one_1__ 1__ 2_和test_one_2__ 4__5_ ,最后的1,2和4,5,分別是傳遞進(jìn)去的參數(shù)。

3、用unpack分解字典

from ddt import ddt,data,file_data,unpack
import unittest

@ddt
class MyTestDdt(unittest.TestCase):
    def setUp(self):
        print('start')

    @data({'value1':1,'value2':2},{'value1':3,'value2':4}) #字典
    @unpack
    def test_one(self,value1,value2):
        print(f'the @data number is :{value1,value2}')

    def tearDown(self):
        print('end')

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

結(jié)果:

test_one_1 (__main__.MyTestDdt) ... ok
start
test_one_2 (__main__.MyTestDdt) ... ok

the @data number is :(1, 2)
----------------------------------------------------------------------
end
Ran 2 tests in 0.000s
start

the @data number is :(3, 4)
OK
end

4、自動化測試實(shí)戰(zhàn)

這里我們登錄新浪郵箱,并利用數(shù)據(jù)驅(qū)動的方式帶參進(jìn)行測試

import unittest
from ddt import ddt,data,unpack
from selenium import webdriver

def testdata():
    '''測試數(shù)據(jù)'''
    return [('', '', '請輸入郵箱名'), ('', '123456', '請輸入郵箱名'),
            ('123456', '', '您輸入的郵箱名格式不正確')]

@ddt
class MyMailLogin(unittest.TestCase):
    def setUp(self):
        self.url = 'https://mail.sina.com.cn/'
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get(self.url)
        self.driver.implicitly_wait(30)

    @data(*testdata()) #這里加*后會將返回數(shù)據(jù)分為一個個的元組
    @unpack
    def test_login(self,username,password,result):
        '''測試郵箱登錄'''
        self.driver.find_element_by_id('freename').clear()
        self.driver.find_element_by_id('freename').send_keys(username)
        self.driver.find_element_by_id('freepassword').clear()
        self.driver.find_element_by_id('freepassword').send_keys(password)
        self.driver.find_element_by_link_text('登錄').click()
        freeError = self.driver.find_element_by_xpath('//div[@class="freeError"]//span').text
        self.assertEqual(freeError,result)

    def tearDown(self):
        self.driver.quit()

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

結(jié)果:

test_login_1___________請輸入郵箱名__ (__main__.MyMailLogin)
測試郵箱登錄 ... ok
test_login_2_______123456____請輸入郵箱名__ (__main__.MyMailLogin)
測試郵箱登錄 ... ok
test_login_3___123456________您輸入的郵箱名格式不正確__ (__main__.MyMailLogin)
測試郵箱登錄 ... ok

需要注意@data( * testdata()) 這里加*后會將返回數(shù)據(jù)分為一個個的元組,否則unpack無法分解數(shù)據(jù),就會報錯。比如:

def testdata():
    return (('', '', '請輸入郵箱名'), ('', '123456', '請輸入郵箱名'),
            ('123456', '', '您輸入的郵箱名格式不正確'))

print(*testdata()) #三個元組
print(testdata()) #一個元組

結(jié)果:

('', '', '請輸入郵箱名') ('', '123456', '請輸入郵箱名') ('123456', '', '您輸入的郵箱名格式不正確')
(('', '', '請輸入郵箱名'), ('', '123456', '請輸入郵箱名'), ('123456', '', '您輸入的郵箱名格式不正確'))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容