基於Python的接口自動化-unittest測試框架和ddt數據驅動

引言

     在編寫接口自動化用例時,我們一般針對一個接口建立一個.py文件,一條接口測試用例封裝爲一個函數(方法),但是在批量執行的過程中,如果其中一條出錯,後面的用例就無法執行,還有在運行大量的接口測試用例時測試數據如何管理和加載。針對測試用例加載以及執行控制,python語言提供了unittest單元測試框架,將測試用例編寫在unittest框架下,使用該框架可以單個或者批量加載互不影響的用例執行及更靈活的執行控制,對於更好的進行測試數據的管理和加載,這裏我們引入數據驅動的模塊:ddt,測試數據和測試腳本的分離,通過ddt數據驅動來加載測試數據到測試用例腳本中,通常在接口自動化測試中會將unittest和ddt結合起來使用,從而實現測試用例腳本和測試數據的載入來完成測試的執行。下面來看看unittest框架和ddt這兩個模塊具體的應用。

一、unittest測試框架

unittest單元測試框架是python語言的一套標準模塊,封裝提供了諸多操作測試用例和用例加載、測試前置和場景恢復以及測試結果輸出等一系列類和方法。

1.unittest框架中最核心四個組件概念:

(1)TestCase:測試用例類,編寫測試用例腳本時需要繼承該類,從而具有該類的屬性和方法,一個TestCase實例就是一個測試用例,其中測試用例方法都以test開頭。

(2)TestSuite:測試集,也就是測試用例的集合,用來組織用例。

(3)testrunner:用來執行測試用例,並返回測試用例的執行結果,可以用圖形或者文本將測試結果形象地展現出來,HTMLTestRunner用來生成圖形化的報告,TextTestRunner用來生成簡單的文本測試結果。

(4)testfixure:測試夾件,主要用於測試用例的前置初始化和執行後的銷燬。

 2.testcase----測試用例

  • 新建一個的.py測試用例文件必須是test開頭,如test_login.py,主要後續用於識別測試用例文件
  • 編寫測試用例的類,必須繼承unittest.TestCase,做爲測試類
  • 測試類中用例的方法名稱必須以test開頭,用於識別測試用例數
  • 測試類中的用例執行順序,按照以test開頭的方法後的Ascill碼順序執行(0~9,A~Z,a~z)

3.testfixure----測試夾件

  • 也叫測試夾具,主要是用例前置的初始化以及執行後的銷燬
  • 測試夾件提供兩種方法,一種是類級別的:setup()和teardown(),一種是方法級別的:setUpClass()和tearDownClass()
  • 類級別的測試夾件,每一條測試用例執行之前與之後都要運行一次setup()和teardown();方法級別的測試夾件,所有測試用例執行之前到執行完成只運行一次setUpClass()和tearDownClass()

下面通過簡單的代碼示例看看TestCase與TestFixure的使用

(1)使用setup()和teardown(),創建test_666.py文件編輯如下代碼:

import unittest

class test_unittest(unittest.TestCase):
    def setUp(self):
        print("測試環境初始化,開始執行setup")

    def tearDown(self):
        print("測試執行完成,運行teardown")
        print("------------------------------")
    def test_a(self):
        print("開始執行test_a用例")

    def test_A(self):
        print("開始執行test_A用例")

    def test_1(self):
        print("開始執行test_1用例")

    def notest_1(self):
        print("不執行notest_1用例")

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

執行後,輸出如下:

 在代碼中我們編寫了4個def用例方法,只執行了3個def,因爲最後一個def不是test開頭。可以看到每執行一個def用例,setup()和teardown()都會執行一次,其中按照執行順序:test_1最先執行,test_A其後,test_a最後執行

(2)使用setUpClass()和tearDownClass()

對於setUpClass()和tearDownClass()我們只需將上面代碼,稍微修改即可

import unittest

class test_unittest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("測試環境初始化,開始執行setup")
    @classmethod
    def tearDownClass(cls):
        print("測試執行完成,運行teardown")
        print("------------------------------")
    def test_a(self):
        print("開始執行test_a用例")

    def test_A(self):
        print("開始執行test_A用例")

    def test_1(self):
        print("開始執行test_1用例")

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

 運行效果如下:

可以看到所有用例都執行完後,setUpClass()和tearDownClass()只運行了一次。因此在編寫一個測試腳本時,裏面寫了多個測試用例,

這時我們希望的是所有用例執行完成後再銷燬環境,這時使用setUpClass()tearDownClass()就比較好了。

3.TestSuite----測試集

unittest框架下提供了unittest.TestSuite()和unittest.TestLoader()類,這兩個類下封裝了加載用例的方法,用於加載測試用例到測試集中

(1)unittest.TestSuite()提供單個用例加載方法

addTest():單個用例加載,當然也可以將多個用例的方法名放入列表中添加到addTest()中,加載多條測試用例

(2)unittest.TestLoader()提供批量加載或發現用例的方法

loadTestsFromTestCase(測試類名):添加一個測試類
loadTestsFromModule(模塊名):添加一個模塊
discover(測試用例的所在目錄):指定目錄去加載,會自動尋找這個目錄下所有符合命名規則的測試用例

4.testrunner----測試運行

     testrunner就是用來執行測試用例的,並且可以生成相應的測試報告。測試報告有兩種展示形式,一種是text文本,一種是html格式。
​html格式的就是HTMLTestRunner了,HTMLTestRunner是 Python 標準庫的 unittest 框架的一個擴展,它可以生成一個直觀清晰的 HTML 測試報告。使用的前提就是要下載 HTMLTestRunner.py,下載完後放在python的安裝目錄下的scripts目錄下即可。

通過代碼示例看看testsuite和testrunner這兩個組件的使用,上面的test_666.py用例文件我們已經寫好了3條用例了,現在我們來加載這些用例

新建run_case.py文件,該文件和test_666.py文件放置在同一個包文件:test下,run_case.py文件編輯如下代碼運行:

import unittest
from test.test_666 import test_unittest

# 單個用例加載
suite = unittest.TestSuite()
case1 = test_unittest('test_1')
case2 = test_unittest('test_a')
suite.addTest(case1)
suite.addTest(case2)
print(suite)
print("------------------")
# 批量用例加載
case_path = r"E:\api_test\test"
# 按文件路徑加載,注意該文件爲包文件即文件下有__init__.py
all_case = unittest.defaultTestLoader.discover(case_path,pattern="test_666*.py",top_level_dir=None)
all_case1 = unittest.defaultTestLoader.loadTestsFromTestCase(test_unittest)   # 按類名稱加載
print(all_case)
print("------------------")
print(all_case1)

 輸出結果如下:

E:\api_test\Scripts\python.exe E:/api_test/test_bak/run_case.py
<unittest.suite.TestSuite tests=[<test.test_666.test_unittest testMethod=test_1>, <test.test_666.test_unittest testMethod=test_a>]>
------------------
<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<test_666.test_unittest testMethod=test_1>, <test_666.test_unittest testMethod=test_A>, <test_666.test_unittest testMethod=test_a>]>]>]>
------------------
<unittest.suite.TestSuite tests=[<test.test_666.test_unittest testMethod=test_1>, <test.test_666.test_unittest testMethod=test_A>, <test.test_666.test_unittest testMethod=test_a>]>

Process finished with exit code 0

 通過unittest框架下提供的加載用例的諸多方法,我們就可以單個或者批量加載用例,後續可以將加載的用例集引入到HTMLTestRunner.py模塊生成可視化的測試報告

5.assert----測試斷言

無論是什麼樣的測試用例,最後都需要有用例執行後的驗證,在接口自動化測試中我們執行完接口用例也需要驗證斷言用例執行是否滿足我們的預期。unittest提供了豐富的斷言方法,常見的斷言如下表:

二、ddt數據驅動

   在進行接口測試時,參考接口文檔說明每個接口測試可以設計諸多測試case,即接口數據設計可以多種,比如正常接口數據、各種異常接口測試數據等,可以發現同一個接口用例除了傳參不同外,接口腳本並沒有什麼區別,無非就是輸入不同接口數據,輸出對應的接口測試接口。這個時候就可以利用ddt來管理測試數據,同一個接口用例傳入不同的測試數據即可,接口腳本可以根據傳入的測試數據運行多次,從而提高代碼的複用性。ddt全稱:data driver test數據驅動測試,是一個第三方模塊,一般和unittest框架結合起來應用,單獨安裝即可,如使用pip安裝。以下通過實例來看看ddt的常規使用:
  • @ddt:類的裝飾器,繼承的是TestCase類
  • @data():@data裝飾符可以把參數當成測試數據,參數可以是單個值、列表、元祖、字典這些類型,用於輸入測試數據
  • @unpack:分解數據標誌,主要是把元祖和列表解析成多個參數
  • @file_data():輸入文件,如json或者yaml類型文件
(1)輸入簡單的參數:單個值、列表、元祖、字典
import unittest
from ddt import data,unpack,ddt

@ddt
class myddt(unittest.TestCase):

    @data("123")              # 單個值
    def test1(self,testdata1):
        print(testdata1)
        print("------------------")

    @data([1,2,3],[4,5,6])    # 列表
    def test2(self,testdata2):
        print(testdata2)
        print("------------------")
"""
    @data((1, 2, 3))          # 元組
    def test2(self, testdata3):
        print(testdata3)
        print("------------------")

    @data({'zhangshan':1,'wangwu':2,'lisi':3})   # 字典
    def test2(self, testdata4):
        print(testdata4)
        print("------------------")
"""
if __name__ == '__main__':
     unittest.main()

 (2)使用@unpack對複雜數據結構,如元組、列表數據進行分解

代碼示例:

import unittest
from ddt import data,unpack,ddt

@ddt
class myddt(unittest.TestCase):

    @data([1,2],[3,4])  # 列表
    @unpack
    def test2(self, testdata1,testdata2):
        print("拆解的第一個參數:",testdata1)
        print("拆解的第二個參數:", testdata2)
        print("------------------")

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

 運行後輸出如下:

 (3)使用@file_data()輸入文件格式測試數據

編輯一個data.json的文件,代碼示例:

import unittest
from ddt import file_data,ddt

@ddt
class myddt(unittest.TestCase):

    @file_data(r"E:\api_test\test\data.json")
    def test1(self, *value):
        print(value)

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

 通過ddt和unittest框架的結合就可以實現測試用例腳本編寫、測試執行控制以及測試數據的批量加載,從而完成不同接口測試用例的批量執行和覆蓋測試不同測試場景。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章