Python 自動化測試框架unittest與pytest的區別


  引言

  前面一篇文章Python單元測試框架介紹已經介紹了python單元測試框架,大家平時經常使用的是unittest,因為它比較基礎,並且可以進行二次開發,如果你的開發水平很高,集成開發自動化測試平台也是可以的。而這篇文章主要講unittest與pytest的區別,pytest相對unittest而言,代碼簡潔,使用便捷靈活,並且插件很豐富。

  Unittest vs Pytest

  主要從用例編寫規則、用例的前置和后置、參數化、斷言、用例執行、失敗重運行和報告這幾個方面比較unittest和pytest的區別:

  用例編寫規則

 

 

 

 

 

  用例前置與后置條件

 

 

 

  斷言

 

 

   測試報告

 

 

 

   失敗重跑機制

 

 

 

   參數化

 

 

 

  用例分類執行

 

 

 如果不好看,可以看下面表格:

  總體來說,unittest用例格式復雜,兼容性無,插件少,二次開發方便。pytest更加方便快捷,用例格式簡單,可以執行unittest風格的測試用例,無須修改unittest用例的任何代碼,有較好的兼容性。pytest插件豐富,比如flask插件,可用於用例出錯重跑,還有xdist插件,可用於設備並行執行,效率更高。

  實例演示

  講了七大區別,總要演示一下具體實例,用事實說話。

  前后置區別

  這里抽用例前置與后置的區別來講,先看unittest的前后置使用:

import unittest



class TestFixtures01(unittest.TestCase):
    # 所有用例執行前執行
    def setUp(self) -> None:
        print("setUp開始")
    def tearDown(self) -> None:
        print("tearDown結束")

    # 每條用例執行前執行
    @classmethod
    def setUpClass(cls) -> None:
        print("setUpClass開始")

    @classmethod
    def tearDownClass(cls) -> None:
        print("tearDownClass結束")

    # 測試用例
    def test_001(self):
        print("測試用例001")

class TestFixtures02(unittest.TestCase):
    def test_002(self):
        print("測試類2")

# 每個模塊執行前執行
def setUpModule():
    """
    在所有測試類在調用之前會被執行一次,函數名是固定寫法,會被unittest框架自動識別
    """
    print('集成測試 >>>>>>>>>>>>>>開始')
def tearDownModule():
    print("集成測試 >>>>>>>>>>>>>>結束")



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

  運行結果:

從結果上得知, 三個方法的邏輯優先級: setUp()&tearDown() < setUpClass()&tearDownClass() < setUpModule()&tearDownModule()

 

接下來看pytest的前后置:

1、我們都知道在自動化測試中都會用到前后置,pytest 相比 unittest 無論是前后置還是插件等都靈活了許多,還能自己用 fixture 來定義。

首先了解一下,用例運行前后置級別如下:

  1.模塊級:全局的,整個模塊開只運行一次,優先於測試用例。

  2.類級別:定義在類里面,只針對此類生效。類似unittest的cls裝飾器

  3.函數級:只對函數生效,類下面的函數不生效。

  4.方法級:定義在類里面,每個用例都執行一次

def setup_module():
    print('\n整個模塊 前 只運行一次')

def teardown_module():
    print('\n整個模塊 后 只運行一次')

def setup_function():
    print('\n不在類中的函數,每個用例 前 只運行一次')

def teardown_function():
    print('\n不在類中的函數,每個用例 后 只運行一次')

def test_ab():
    b = 2
    assert b < 3

def test_aba():
    b = 2
    assert b < 3


class Test_api():

    def setup_class(self):
        print('\n此類用例 前 只執行一次')
    def teardown_class(self):
        print('\n此類用例 后 只執行一次')

    def setup_method(self):
        print('\n此類每個用例 前 只執行一次')

    def teardown_method(self):
        print('\n此類每個用例 后 執行一次')

    def test_aa(self):
        a = 1
        print('\n我是用例:a')       # pytest -s 顯示打印內容
        assert a > 0

    def test_b(self):
        b = 2
        assert b < 3

 

運行結果:

 

2、這是原始用法,下面看使用Fixture,Fixture 其實就是自定義 pytest 執行用例前置和后置操作,首先創建 conftest.py 文件 (規定此命名),導入 pytest 模塊,運用 pytest.fixture 裝飾器,默認級別為:函數級:

 其它用例文件調用即可,如下定義一個函數,繼承 conftest.py 文件里的 login 函數即可調用:

# conftest.py配置需要注意以下點:
# conftest.py配置腳本名稱是固定的,不能改名稱
# conftest.py與運行的用例要在同一個pakage下,並且有__init__.py文件
# 不需要import導入 conftest.py,pytest用例會自動查找

import pytest

def test_one(login):
	print("登陸后,操作111")

# def test_two():
# 	print("操作222")
#
# def test_three(login):
# 	print("登陸后,操作333")

 

運行結果:

 

3、擴展用法,多個自定義函數和全局級別展示:(全局的比如用於登錄獲取到token其他用例模塊就不需要再登錄了)

import pytest

def test_one(login):
	print("登陸后,操作111")

def test_two(login,open_page):
	print("測試用例2")

def test_three(open_page):
	print("測試用例3")

  

運行結果:

 

細心的人應該可以知道,測試用例2並沒有調用login函數,因為前置設置的是共享模式,類似全局函數。

 

  參數化區別

參數化應用場景,一個場景的用例會用到多條數據來進行驗證,比如登錄功能會用到正確的用戶名、密碼登錄,錯誤的用戶名、正確的密碼,正確的用戶名、錯誤的密碼等等來進行測試,這時就可以用到框架中的參數化,來便捷的完成測試。

參數化 就是數據驅動思想,即可以在一個測試用例中進行多組的數據測試,而且每一組數據都是分開的、獨立的。

unittest參數化其實是:ddt,叫數據驅動。

pytest數據驅動,就是參數化,使用@pytest.mark.parametrize

 

1.先看unittest如何進行參數化:

test_data = [1,2,3]

@ddt.ddt
class Testddt(unittest.TestCase):
    @ddt.data(*test_data)
    def test_001(self,get_data):
        print(get_data)
if __name__ == '__main__':
    unittest.main()

  

運行結果:

 

2.pytest中參數化的用法

在測試用例的前面加上:
@pytest.mark.parametrize("參數名",列表數據)
參數名:用來接收每一項數據,並作為測試用例的參數。
列表數據:一組測試數據。

@pytest.mark.parametrize("參數1,參數2",[(數據1,數據2),(數據1,數據2)])
示例:
@pytest.mark.parametrize("a,b,c",[(1,3,4),(10,35,45),(22.22,22.22,44.44)])
def test_add(a,b,c):
res = a + b
assert res == c

實例:

@pytest.mark.parametrize('data',[1,2,3])
class Testddt(object):

    def test_001(self,data):
        print(data)
if __name__ == '__main__':
    pytest.main(['-sv'])

 

運行結果:

 

 

  總結

  以上就是unittest與pytest測試框架的區別,七大主要區別,這里已講了兩個區別的實例,其他五個有時間再補充,如對python自動化測試感興趣的朋友,可以加入左下方學習交流群,討論交流一下心得。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM