欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Pytest 自動化測試框架的使用

 更新時間:2023年03月16日 09:25:24   作者:測試大圣  
本文主要介紹了Pytest 自動化測試框架的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

Pytest和Unittest測試框架的區(qū)別?

如何區(qū)分這兩者,很簡單unittest作為官方的測試框架,在測試方面更加基礎,并且可以再次基礎上進行二次開發(fā),同時在用法上格式會更加復雜;而pytest框架作為第三方框架,方便的地方就在于使用更加靈活,并且能夠對原有unittest風格的測試用例有很好的兼容性,同時在擴展上更加豐富,可通過擴展的插件增加使用的場景,比如一些并發(fā)測試等;

Pytest 安裝

pip安裝:

pip install pytest

測試安裝成功:

pytest --help

py.test --help

檢查安裝版本:

pytest --version

Pytest 示例

Pytest編寫規(guī)則:

  • 測試文件以test_開頭(以_test為結尾)
  • 測試的類以Test開頭;
  • 測試的方法以test_開頭
  • 斷言使用基本的assert

test_example.py

def count_num(a: list) -> int:
? ? return len(a)
?
?
def test_count():
? ? assert count_num([1, 2, 3]) != 3

執(zhí)行測試:

pytest test_example.py

執(zhí)行結果:

C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest>pytest test_example.py -v
================================================================= test session starts =================================================================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- d:\coding\python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collected 1 item                                                                                                                                       
 
test_example.py::test_count FAILED                                                                                                               [100%]
 
====================================================================== FAILURES =======================================================================
_____________________________________________________________________ test_count ______________________________________________________________________
 
    def test_count():
>       assert count_num([1, 2, 3]) != 3
E       assert 3 != 3
E        +  where 3 = count_num([1, 2, 3])
 
test_example.py:11: AssertionError
=============================================================== short test summary info ===============================================================
FAILED test_example.py::test_count - assert 3 != 3
================================================================== 1 failed in 0.16s ==================================================================

備注:

  • .代表測試通過,F代表測試失敗;
  • -v顯示詳細的測試信息, -h顯示pytest命令詳細的幫助信息;

標記

默認情況下,pytest會在當前目錄下尋找以test_為開頭(以_test結尾)的測試文件,并且執(zhí)行文件內所有以test_為開頭(以_test為結尾)的所有函數和方法;

指定運行測試用例,可以通過::顯示標記(文件名::類名::方法名)(文件名::函數名)

pytest test_example3.py::test_odd

指定一些測試用例測試運行,可以使用-k模糊匹配

pytest -k example

通過pytest.mark.skip()或者pytest.makr.skipif()條件表達式,跳過指定的測試用例

import pytest
 
test_flag = False
 
@pytest.mark.skip()
def test_odd():
    num = random.randint(0, 100)
    assert num % 2 == 1
 
 
@pytest.mark.skipif(test_flag is False, reason="test_flag is False")
def test_even():
    num = random.randint(0, 1000)
    assert num % 2 == 0

通過pytest.raises()捕獲測試用例可能拋出的異常

def test_zero():
    num = 0
    with pytest.raises(ZeroDivisionError) as e:
        num = 1/0
    exc_msg = e.value.args[0]
    print(exc_msg)
    assert num == 0

預先知道測試用例會失敗,但是不想跳過,需要顯示提示信息,使用pytest.mark.xfail()

@pytest.mark.xfail()
def test_sum():
    random_list = [random.randint(0, 100)  for x in range(10)]
    num = sum(random_list)
    assert num < 20

對測試用例進行多組數據測試,每組參數都能夠獨立執(zhí)行一次(可以避免測試用例內部執(zhí)行單組數據測試不通過后停止測試)

@pytest.mark.parametrize('num,num2', [(1,2),(3,4)])
def test_many_odd(num: int, num2: int):
    assert num % 2 == 1
    assert num2 % 2 == 0

固件(Fixture)

固件就是一些預處理的函數,pytest會在執(zhí)行測試函數前(或者執(zhí)行后)加載運行這些固件,常見的應用場景就有數據庫的連接和關閉(設備連接和關閉)

簡單使用

import pytest
 
@pytest.fixture()
def postcode():
    return "hello"

def test_count(postcode):
    assert postcode == "hello"

按照官方的解釋就是當運行測試函數,會首先檢測運行函數的參數,搜索與參數同名的fixture,一旦pytest找到,就會運行這些固件,獲取這些固件的返回值(如果有),并將這些返回值作為參數傳遞給測試函數;

預處理和后處理

接下來進一步驗證關于官方的說法:

import pytest
 
@pytest.fixture()
def connect_db():
    print("Connect Database in .......")
    yield
    print("Close Database out .......")
 
def read_database(key: str):
    p_info = {
        "name": "zhangsan",
        "address": "China Guangzhou",
        "age": 99
    }
    return p_info[key]
 
def test_count(connect_db):
    assert read_database("name") == "zhangsan"

執(zhí)行測試函數結果:

============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 1 item
 
test_example.py::test_count Connect Database in .......
PASSED                                       [100%]Close Database out .......
 
 
============================== 1 passed in 0.07s ==============================

備注:

  • 首先從結果上看驗證了官方的解釋,pytest執(zhí)行測試函數前會尋找同名的固件加載運行;
  • connect_db固件中有yield,這里pytest默認會判斷yield關鍵詞之前的代碼屬于預處理,會在測試前執(zhí)行,yield之后的代碼則是屬于后處理,將在測試后執(zhí)行;

作用域

從前面大致了解了固件的作用,抽離出一些重復的工作方便復用,同時pytest框架中為了更加精細化控制固件,會使用作用域來進行指定固件的使用范圍,(比如在這一模塊中的測試函數執(zhí)行一次即可,不需要模塊中的函數重復執(zhí)行)更加具體的例子就是數據庫的連接,這一連接的操作可能是耗時的,我只需要在這一模塊的測試函數運行一次即可,不需要每次都運行。

而定義固件是,一般通過scop參數來聲明作用,常用的有:

  • function: 函數級,每個測試函數都會執(zhí)行一次固件;
  • class: 類級別,每個測試類執(zhí)行一次,所有方法都可以使用;
  • module: 模塊級,每個模塊執(zhí)行一次,模塊內函數和方法都可使用;
  • session: 會話級,一次測試只執(zhí)行一次,所有被找到的函數和方法都可用。
import pytest
??
@pytest.fixture(scope="function")
def func_scope():
? ? print("func_scope")
??
@pytest.fixture(scope="module")
def mod_scope():
? ? print("mod_scope")
?
@pytest.fixture(scope="session")
def sess_scope():
? ? print("session_scope")?
?
def test_scope(sess_scope, mod_scope, func_scope):
? ? pass
?
def test_scope2(sess_scope, mod_scope, func_scope):
? ? pass

執(zhí)行結果:

============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
 
test_example2.py::test_scope session_scope
mod_scope
func_scope
PASSED                                      [ 50%]
test_example2.py::test_scope2 func_scope
PASSED                                     [100%]
 
============================== 2 passed in 0.07s ==============================

從這里可以看出module,session作用域的固件只執(zhí)行了一次,可以驗證官方的使用介紹

自動執(zhí)行

有人可能會說,這樣子怎么那么麻煩,unittest框架中直接定義setUp就能自動執(zhí)行預處理,同樣的pytest框架也有類似的自動執(zhí)行; pytest框架中固件一般通過參數autouse控制自動運行。

import pytest
 
@pytest.fixture(scope='session', autouse=True)
def connect_db():
   print("Connect Database in .......")
   yield
   print("Close Database out .......")
 
 
def test1():
   print("test1")
 
 
def test2():
   print("test")

執(zhí)行結果:

============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
 
test_example.py::test1 Connect Database in .......
PASSED                                            [ 50%]test1
 
test_example.py::test2 PASSED                                            [100%]test
Close Database out .......
 
 
============================== 2 passed in 0.07s ==============================

從結果看到,測試函數運行前后自動執(zhí)行了connect_db固件;

參數化

前面簡單的提到過了@pytest.mark.parametrize通過參數化測試,而關于固件傳入參數時則需要通過pytest框架中內置的固件request,并且通過request.param獲取參數

import pytest
 
@pytest.fixture(params=[
    ('redis', '6379'),
    ('elasticsearch', '9200')
])
def param(request):
    return request.param
 
 
@pytest.fixture(autouse=True)
def db(param):
    print('\nSucceed to connect %s:%s' % param)
 
    yield
 
    print('\nSucceed to close %s:%s' % param)
 
def test_api():
    assert 1 == 1

執(zhí)行結果:

============================= test session starts =============================
platform win32 -- Python 3.6.8, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- D:\Coding\Python3.6\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\libuliduobuqiuqiu\Desktop\GitProjects\PythonDemo\pytest
plugins: Faker-8.11.0
collecting ... collected 2 items
 
test_example.py::test_api[param0] 
Succeed to connect redis:6379
PASSED                                 [ 50%]
Succeed to close redis:6379
 
test_example.py::test_api[param1] 
Succeed to connect elasticsearch:9200
PASSED                                 [100%]
Succeed to close elasticsearch:9200
 
 
============================== 2 passed in 0.07s ==============================

這里模擬連接redis和elasticsearch,加載固件自動執(zhí)行連接然后執(zhí)行測試函數再斷開連接。

總結

對于開發(fā)來說為什么也要學習自動化測試這一塊,很重要的一點就是通過自動化測試節(jié)省一些重復工作的時間,同時對于優(yōu)化代碼結構,提高代碼覆蓋率,以及后續(xù)項目重構都是有著很重要的意義,同時理解pytest和unittest在基礎上有何區(qū)別有助于不同的業(yè)務場景中選擇適合自己的測試工具。

這篇文章只是簡單的介紹了pytest的基本使用,有興趣的可以去看看官方文檔,官方文檔中還提到了如內置固件的使用,常用測試的場景等等。

到此這篇關于Pytest 自動化測試框架的使用的文章就介紹到這了,更多相關Pytest 自動化測試框架內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論