pytest fixture-參數(shù)化fixture

2022-03-18 14:18 更新

??fixture??函數(shù)可以被參數(shù)化,在這種情況下,它們將被多次調(diào)用,每次執(zhí)行一組依賴于該??fixture??的測(cè)試。測(cè)試函數(shù)通常不需要知道它們的重新運(yùn)行。夾具參數(shù)化有助于為組件編寫(xiě)詳盡的功能測(cè)試,這些組件本身可以以多種方式配置。

擴(kuò)展前面的示例,我們可以標(biāo)記??fixture??來(lái)創(chuàng)建兩個(gè)??smtp_connection fixture??實(shí)例,這將導(dǎo)致使用該??fixture??的所有測(cè)試運(yùn)行兩次。??fixture??函數(shù)通過(guò)特殊的??request??對(duì)象訪問(wèn)每個(gè)參數(shù):

# content of conftest.py
import pytest
import smtplib


@pytest.fixture(scope="module", params=["smtp.gmail.com", "mail.python.org"])
def smtp_connection(request):
    smtp_connection = smtplib.SMTP(request.param, 587, timeout=5)
    yield smtp_connection
    print("finalizing {}".format(smtp_connection))
    smtp_connection.close()

主要的變化是用??@pytest??聲明??params??。??Fixture??,一個(gè)值列表,??Fixture??函數(shù)將執(zhí)行其中的每個(gè)值,并可以通過(guò)??request.param??訪問(wèn)一個(gè)值。不需要更改測(cè)試函數(shù)代碼。我們?cè)龠\(yùn)行一次

$ pytest -q test_module.py
FFFF                                                                 [100%]
================================= FAILURES =================================
________________________ test_ehlo[smtp.gmail.com] _________________________

smtp_connection = <smtplib.SMTP object at 0xdeadbeef0004>

    def test_ehlo(smtp_connection):
        response, msg = smtp_connection.ehlo()
        assert response == 250
        assert b"smtp.gmail.com" in msg
>       assert 0  # for demo purposes
E       assert 0

test_module.py:7: AssertionError
________________________ test_noop[smtp.gmail.com] _________________________

smtp_connection = <smtplib.SMTP object at 0xdeadbeef0004>

    def test_noop(smtp_connection):
        response, msg = smtp_connection.noop()
        assert response == 250
>       assert 0  # for demo purposes
E       assert 0

test_module.py:13: AssertionError
________________________ test_ehlo[mail.python.org] ________________________

smtp_connection = <smtplib.SMTP object at 0xdeadbeef0005>

    def test_ehlo(smtp_connection):
        response, msg = smtp_connection.ehlo()
        assert response == 250
>       assert b"smtp.gmail.com" in msg
E       AssertionError: assert b'smtp.gmail.com' in b'mail.python.org\nPIPELINING\nSIZE 51200000\nETRN\nSTARTTLS\nAUTH DIGEST-MD5 NTLM CRAM-MD5\nENHANCEDSTATUSCODES\n8BITMIME\nDSN\nSMTPUTF8\nCHUNKING'

test_module.py:6: AssertionError
-------------------------- Captured stdout setup ---------------------------
finalizing <smtplib.SMTP object at 0xdeadbeef0004>
________________________ test_noop[mail.python.org] ________________________

smtp_connection = <smtplib.SMTP object at 0xdeadbeef0005>

    def test_noop(smtp_connection):
        response, msg = smtp_connection.noop()
        assert response == 250
>       assert 0  # for demo purposes
E       assert 0

test_module.py:13: AssertionError
------------------------- Captured stdout teardown -------------------------
finalizing <smtplib.SMTP object at 0xdeadbeef0005>
========================= short test summary info ==========================
FAILED test_module.py::test_ehlo[smtp.gmail.com] - assert 0
FAILED test_module.py::test_noop[smtp.gmail.com] - assert 0
FAILED test_module.py::test_ehlo[mail.python.org] - AssertionError: asser...
FAILED test_module.py::test_noop[mail.python.org] - assert 0
4 failed in 0.12s

我們看到,我們的兩個(gè)測(cè)試函數(shù)針對(duì)不同的??smtp_connection??實(shí)例運(yùn)行了兩次。還要注意,對(duì)于??mail.python.org??連接,第二個(gè)測(cè)試在??test_ehlo??中失敗,因?yàn)轭A(yù)期的服務(wù)器字符串與到達(dá)的服務(wù)器字符串不同。

pytest將構(gòu)建一個(gè)字符串,它是參數(shù)化??fixture??中每個(gè)??fixture??值的測(cè)試ID,例如上面示例中的??test_ehlo[smtp.gmail.com]??和??test_ehlo[mail.python.org]??。這些ids可以與??-k??一起使用,以選擇要運(yùn)行的特定案例,并且它們還將在某個(gè)案例失敗時(shí)標(biāo)識(shí)特定案例。使用??——collect-only??運(yùn)行pytest將顯示生成的id。

數(shù)字、字符串、布爾值和None將在測(cè)試ID中使用它們通常的字符串表示。對(duì)于其他對(duì)象,pytest將根據(jù)參數(shù)名生成一個(gè)字符串。通過(guò)使用?ids?關(guān)鍵字參數(shù),可以定制測(cè)試ID中用于特定??fixture??值的字符串:

# content of test_ids.py
import pytest


@pytest.fixture(params=[0, 1], ids=["spam", "ham"])
def a(request):
    return request.param


def test_a(a):
    pass


def idfn(fixture_value):
    if fixture_value == 0:
        return "eggs"
    else:
        return None


@pytest.fixture(params=[0, 1], ids=idfn)
def b(request):
    return request.param


def test_b(b):
    pass

上面展示了如何將ids作為一個(gè)字符串列表來(lái)使用,或者作為一個(gè)函數(shù)來(lái)調(diào)用??fixture??值,然后返回一個(gè)字符串來(lái)使用。在后一種情況下,如果函數(shù)返回?None?,那么將使用pytest自動(dòng)生成的ID。

運(yùn)行上述測(cè)試會(huì)在以下正在使用的測(cè)試ids中產(chǎn)生結(jié)果:

$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 11 items

<Module test_anothersmtp.py>
  <Function test_showhelo[smtp.gmail.com]>
  <Function test_showhelo[mail.python.org]>
<Module test_emaillib.py>
  <Function test_email_received>
<Module test_ids.py>
  <Function test_a[spam]>
  <Function test_a[ham]>
  <Function test_b[eggs]>
  <Function test_b[1]>
<Module test_module.py>
  <Function test_ehlo[smtp.gmail.com]>
  <Function test_noop[smtp.gmail.com]>
  <Function test_ehlo[mail.python.org]>
  <Function test_noop[mail.python.org]>

======================= 11 tests collected in 0.12s ========================


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)