Pytest04-編寫測試函數

4.編寫測試函數

4.1 使用assert聲明

    使用pytest編寫測試時,若須要傳遞測試失敗信息,能夠直接使用Pytho自帶的assert關鍵字。pytest與其餘測試框架如unittest的區別以下所示:html

pytest unittest
assert something assertTrue(something)
assert a==b assertEqual(a,b)
assert a<=b assertLessEqual(a,b)
... ...

    pytest中assert主要有如下特色node

  • 1.assert 後面能夠添加任何表達式,若表達式的結果經過bool轉換結果爲True,則表明測試經過
  • 2.pytest 能夠重寫assert關鍵字。pytest可截斷對原生assert的調用,替換爲pytest定義的assert,從而提供更多的詳細失敗信息
import pytest

def addItemToList(item):
    tmpList=[]
    tmpList.append(item)
    return tmpList


def test_addItemToList():
    t1=addItemToList("a")
    t2=addItemToList("b")
    assert t1==t2

運行結果以下所示:python

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest .\test_01.py
=============================test session starts ====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 1 item

test_01.py F                                                                [100%]

================================== FAILURES ======================================
___________________________test_addItemToList ____________________________________

    def test_addItemToList():
        t1=addItemToList("a")
        t2=addItemToList("b")
>       assert t1==t2
E       AssertionError: assert ['a'] == ['b']
E         At index 0 diff: 'a' != 'b'
E         Use -v to get the full diff

test_01.py:12: AssertionError
=================================== short test summary info =========================
FAILED test_01.py::test_addItemToList - AssertionError: assert ['a'] == ['b']
====================================1 failed in 0.29s ==============================

    在上面的運行結果中,失敗的測試用例在行首會有一個 > 來標識。以E開頭的行是pytest提供的額外斷定信息,用於幫助瞭解異常的具體信息。數組

4.2 預期異常

    在Python後來的版本,增長了函數參數註解功能,即在定義一個參數後,後面可直接聲明參數的數據類型,方便其餘人員知道如何調用這個函數,以下所示:微信

def add(x:int,y:int)->int:
    return x+y

    爲確保像這樣的函數,在發生類型錯誤時,能夠拋出異常,可使用with pytest.raises(< expected exception >),以下所示:session

def add(x:int,y:int)->int:
    if not isinstance(x,(int,)) or not isinstance(y,(int,)):
        raise TypeError("args must be int")
    else:
        return x+y

def test_add():
    with pytest.raises(TypeError):
        add("1","2")

運行結果以下所示:app

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest .\test_01.py
==============================test session starts ================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 1 item

test_01.py .                                                              [100%]

=================================1 passed in 0.08s ===============================

    測試用例中test_add()有with pytest.raises(TypeError)聲明,則意味着不管with中的內容是什麼,都至少會產生TypeError異常。若是測試經過,則說明確實發生了預期的TypeError異常,若是拋出的是其餘類型的異常,則與預期不一致,測試失敗。框架

    在上面的測試用例中,僅檢驗了傳參數據的類型異常,也能夠檢查值異常,好比在檢驗一個參數的數據類型以後,也能夠再檢驗其內容,爲校驗異常消息是否符合預期,能夠增長as exInfo語句獲得異常消息的值,再進行校驗,示例以下所示:函數

def add(x:int,y:int,operator:str)->int:
    if not isinstance(x,(int,)) or not isinstance(y,(int,)) or not isinstance(operator,(str,)):
        raise TypeError("args must be int")
    if operator=="+":
        return x + y
    elif operator=="-":
        return x - y
    else:
        raise ValueError("operator must be '+' or '-' ")

def test_add():
    with pytest.raises(ValueError) as exInfo:
        add(1,2,"*")
    exInfo=exInfo.value.args[0]
    expectInfo="operator must be '+' or '-' "
    assert expectInfo== exInfo

運行結果以下所示:測試

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest .\test_01.py
=============================test session starts ============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 1 item

test_01.py .                                                      [100%]

============================1 passed in 0.13s ================================

4.3 測試函數標記

    pytest提供了標記機制,容許使用marker對測試函數進行標記,一個測試函數能夠有多個marker,一個marker也能夠用來標記多個測試函數

對測試函數進行標記,一般使用的場景爲冒煙測試,通常狀況下冒煙測試不須要跑所有的測試用例,只須要選擇關鍵的點進行測試,這個時候只跑被標記爲冒煙測試的測試用例,會省不少時間。

    示例以下所示:

import pytest

def add(x:int,y:int,operator:str)->int:
    if not isinstance(x,(int,)) or not isinstance(y,(int,)) or not isinstance(operator,(str,)):
        raise TypeError("args must be int")
    if operator=="+":
        return x + y
    elif operator=="-":
        return x - y
    else:
        raise ValueError("operator must be '+' or '-' ")

@pytest.mark.testValueError
@pytest.mark.smoke
def test_addValueError():
    with pytest.raises(ValueError) as exInfo:
        add(1,2,"*")
    exInfo=exInfo.value.args[0]
    expectInfo="operator must be '+' or '-' "
    assert expectInfo== exInfo

@pytest.mark.testTypeErrorTest
@pytest.mark.smoke
def test_addTypeError():
    with pytest.raises(TypeError):
        add("1","2","+")

    如今只須要在命令中指定-m markerName,就能夠運行指定的測試用例,以下所示:

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest -m smoke .\test_02.py
=========================test session starts ===============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items

test_02.py ..                                                                       [100%]
============================ 2 passed, 4 warnings in 0.12s ====================================

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest -m testValueError .\test_02.py
==============================test session starts ==============================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items / 1 deselected / 1 selected

test_02.py .                                                                        [100%]
========================= 1 passed, 1 deselected, 4 warnings in 0.04s ===========================

    針對上面示例,能夠得出如下結論

1.pytest.mark.markName:markName由用戶自行定義,並不是pytest內置
2.-m:後面也可使用表達式,能夠在標記之間添加and、or、not等關鍵字,以下所示:

pytest -m "testValueError and testTypeError" .\test_02.py
pytest -m "testValueError and not testTypeError" .\test_02.py

4.4 跳過測試

    pytest內置了一些標記,如skip、skipif、xfail。其中skip、skipif容許跳過不但願運行的測試。示例以下所示:

1.要直接跳過某一個測試函數,可使用pytest.mark.skip()裝飾器便可

import pytest

def add(x:int,y:int,operator:str)->int:
    if not isinstance(x,(int,)) or not isinstance(y,(int,)) or not isinstance(operator,(str,)):
        raise TypeError("args must be int")
    if operator=="+":
        return x + y
    elif operator=="-":
        return x - y
    else:
        raise ValueError("operator must be '+' or '-' ")

@pytest.mark.testValueError
@pytest.mark.smoke
def test_addValueError():
    with pytest.raises(ValueError) as exInfo:
        add(1,2,"*")
    exInfo=exInfo.value.args[0]
    expectInfo="operator must be '+' or '-' "
    assert expectInfo== exInfo

@pytest.mark.skip(reason="skip this case")
def test_addTypeError():
    with pytest.raises(TypeError):
        add("1","2","+")

運行結果以下所示:

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest -v .\test_02.py
==========================test session starts =================================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items

test_02.py::test_addValueError PASSED                                                      [ 50%]
test_02.py::test_addTypeError SKIPPED                                                      [100%]

2.添加跳過的緣由和條件,可使用pytest.mark.skipif()裝飾器便可

    若是有一些測試,只有在知足特定條件的狀況下,才被跳過,這時候則可使用pytest.mark.skipif(),示例以下所示:

import pytest

def add(x:int,y:int,operator:str)->int:
    """this is sample case"""
    if not isinstance(x,(int,)) or not isinstance(y,(int,)) or not isinstance(operator,(str,)):
        raise TypeError("args must be int")
    if operator=="+":
        return x + y
    elif operator=="-":
        return x - y
    else:
        raise ValueError("operator must be '+' or '-' ")

@pytest.mark.testValueError
@pytest.mark.smoke
def test_addValueError():
    with pytest.raises(ValueError) as exInfo:
        add(1,2,"*")
    exInfo=exInfo.value.args[0]
    expectInfo="operator must be '+' or '-' "
    assert expectInfo== exInfo

@pytest.mark.skipif(add.__doc__=="this is sample case",reason="skip this case")
def test_addTypeError():
    with pytest.raises(TypeError):
        add("1","2","+")

運行結果以下所示:

platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items

test_02.py::test_addValueError PASSED                                                                      [ 50%]
test_02.py::test_addTypeError SKIPPED                                                                      [100%]

儘管跳過的緣由不是必須寫,但仍是建議在實際項目儘量的寫上,方便知道跳過的緣由,若是想知道跳過的詳細緣由,可以使用參數 -rs

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest -rs -v .\test_02.py
======================test session starts ====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items

test_02.py::test_addValueError PASSED                                                       [ 50%]
test_02.py::test_addTypeError SKIPPED                                                       [100%]
==================================short test summary info =================================
SKIPPED [1] test_02.py:23: skip this case
==========================1 passed, 1 skipped, 2 warnings in 0.04s ========================

4.5 標記預期失敗的測試

    使用skip和skipif,在知足條件的下,會直接跳過,而不會執行。使用xfail標記,則是預期運行失敗,以下所示:

import pytest

def add(x:int,y:int,operator:str)->int:
    """this is sample case"""
    if not isinstance(x,(int,)) or not isinstance(y,(int,)) or not isinstance(operator,(str,)):
        raise TypeError("args must be int")
    if operator=="+":
        return x + y
    elif operator=="-":
        return x - y
    else:
        raise ValueError("operator must be '+' or '-' ")

@pytest.mark.xfail
def test_addValueError():
    with pytest.raises(ValueError) as exInfo:
        add(1,2,"*")
    exInfo=exInfo.value.args[0]
    expectInfo="operator must be '+' or '-' "
    assert expectInfo!= exInfo

@pytest.mark.xfail(add.__doc__=="this is sample case",reason="skip this case")
def test_addTypeError():
    with pytest.raises(TypeError):
        add("1","2","+")

運行結果以下所示:

PS C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02> pytest  .\test_02.py
============================test session starts ===================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items

test_02.py xX                                                                        [100%]

======================= 1 xfailed, 1 xpassed in 0.19s ===============================
  • x表明XFAIL,意味着expect to fail(預期失敗,實際上也失敗)
  • X表明XPASS,意味着expect to fail but passed(預期失敗,實際上成功)

    對於標記爲xfail,但實際運行結果爲XPASS的測試,能夠在pytest配置中強制指定爲FAIL,在pytest.ini文件按以下修改便可:

[pytest]
xfail_strict=true

4.6 運行測試子集

    前面主要介紹對測試函數進行標記及如何運行。而運行測試子集能夠按目錄文件類中的測試,還能夠選擇運行某一個測試用例(可能在文件中,也能夠在類中)**。

4.6.1 單個目錄

    運行單個目錄下的全部測試,以目錄作爲參數便可,以下所示:

pytest --tb=no .\PytestStudy\

4.6.2 單個測試文件/模塊

    運行單個測試文件/模塊,以路徑名加文件名作爲參數便可,以下所示:

pytest --tb=no .\PytestStudy\Lesson02\test_01.py

4.6.3 單個測試函數

    運行單個測試函數,只須要在文件名後面添加::符號和函數名便可,以下所示:

pytest .\test_02.py::test_addTypeError

4.6.4 單個測試類

    測試類用於將某些類似的測試函數組合在一塊兒,來看看如下示例:

import pytest

class Person:
    _age=28
    _name="Surpass"
    
    def __init__(self,age,name):
        self._name=name
        self._age=age
        
    @classmethod
    def getAge(cls):
        if not isinstance(cls._age,(int,)):
            raise TypeError("age must be integer")
        else:
            return cls._age
    
    @classmethod
    def getName(cls):
        if not isinstance(cls._name,(str,)):
            raise TypeError("name must be string")
        else:
            return cls._name

class TestPerson:
    
    def test_getAge(self):
        with pytest.raises(TypeError):
            Person.getAge("28")
            
    def test_getName(self):
        with pytest.raises(TypeError):
            Person.getName(123)

    以上測試類中的方法都是測試Person中的方法,所以能夠放在一個測試類中,要運行該類,能夠在文件名後面添加::符號和類名便可,與運行單個測試函數相似,以下所示:

pytest .\test_03.py::TestPerson -v
========================== test session starts ===========================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 2 items

test_03.py::TestPerson::test_getAge PASSED                                          [ 50%]
test_03.py::TestPerson::test_getName PASSED                                         [100%]

============================= 2 passed in 0.04s ============================================

4.6.5 單個測試類中的測試方法

    若是不但願運行測試類中的全部測試方法,能夠指定運行的測試方法名即,能夠在文件名後面添加::類名::類中方法名便可,以下所示:

>>> pytest -v .\test_03.py::TestPerson::test_getName
=========================== test session starts ==================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 1 item

test_03.py::TestPerson::test_getName PASSED                                          [100%]

============================= 1 passed in 0.04s ===============================

4.6.6 用測試名劃分測試集合

    -k選項容許用一個表達式指定須要運行的測試,表達式能夠匹配測試名或其子串,表達式中也能夠包含and、or、not等。

    例如想運行目錄中,全部文件中測試函數名包含_add的測試函數,可按以下方式進行操做:

>>> pytest -v -k _add
======================== test session starts ===============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 5 items / 2 deselected / 3 selected

test_01.py::test_add PASSED                                                         [ 33%]
test_02.py::test_addValueError XFAIL                                                [ 66%]
test_02.py::test_addTypeError XPASS                                                 [100%]

==================== 1 passed, 2 deselected, 1 xfailed, 1 xpassed in 0.14s ====================

4.7 參數化測試

4.7.1 參數化方式

    向函數傳值並校驗其輸出是軟件測試的經常使用手段,但大部分狀況下,僅使用一組數據是沒法充分測試函數功能。參數化測試容許傳遞多組數據,一旦發現測試失敗,pytest會及時拋出信息。
    要使用參數化測試,須要使用裝飾器pytest.mark.parametrize(args,argsvaules)來傳遞批量的參數。示例以下所示:

1.方式一

import pytest

def add(x:int,y:int)->int:
    return x+y

@pytest.mark.parametrize("paras",[(1,2),(3,5),(7,8),(10,-98)])
def test_add(paras):
    res=add(paras[0],paras[1])
    expect=paras[0]+paras[1]
    assert res==expect

運行結果以下所示:

>>> pytest -v .\test_04.py
================================================= test session starts =================================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 4 items

test_04.py::test_add[paras0] PASSED                               [ 25%]
test_04.py::test_add[paras1] PASSED                               [ 50%]
test_04.py::test_add[paras2] PASSED                               [ 75%]
test_04.py::test_add[paras3] PASSED                               [100%]

=====================4 passed in 0.10s ====================================

    在parametrize()中第一個參數字符串列表(paras),第二個參數是一個值列表,pytest會輪流對每一個paras作測試,並分別報告每一個測試用例的結果。

    parametrize()函數工做正常,那若是把paras替換爲鍵值對形式了,可否達到一樣的效果,以下所示:

2.方式二

import pytest

def add(x:int,y:int)->int:
    return x+y

@pytest.mark.parametrize(("x","y"),[(1,2),(3,5),(7,8),(10,-98)])
def test_add(x,y):
    res=add(x,y)
    expect=x+y
    assert res==expect

運行結果以下所示:

>>> pytest -v .\test_04.py
====================test session starts =================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 4 items

test_04.py::test_add[1-2] PASSED                                            [ 25%]
test_04.py::test_add[3-5] PASSED                                            [ 50%]
test_04.py::test_add[7-8] PASSED                                            [ 75%]
test_04.py::test_add[10--98] PASSED                                         [100%]

======================4 passed in 0.16s =============================

    若是傳入的參數具備標識性,則在輸出結果中也一樣具有可標識性,加強可讀性。也可使用完整的測試標識(pytest術語爲node),若是標識符中包含空格,則須要使用引號。從新運行指定的測試以下所示:

>>> pytest -v test_04.py::test_add[1-2]
================================ test session starts =======================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 1 item

test_04.py::test_add[1-2] PASSED                                      [100%]

========================== 1 passed in 0.04s ===================================

3.方式三

    除了以上兩種方式以外,還可使用以下方式進行參數化,以下所示:

import pytest

def add(x:int,y:int)->int:
    return x+y

paras=((1,2),(3,5),(7,8),(10,-98))
@pytest.mark.parametrize("p",paras)
def test_add(p):
    res=add(p[0],p[1])
    expect=p[0]+p[1]
    assert res==expect

運行結果以下所示

>>> pytest -v test_04.py
================================ test session starts ======================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 4 items

test_04.py::test_add[p0] PASSED                                          [ 25%]
test_04.py::test_add[p1] PASSED                                          [ 50%]
test_04.py::test_add[p2] PASSED                                          [ 75%]
test_04.py::test_add[p3] PASSED                                          [100%]

==============================4 passed in 0.14s ======================================

4.7.2 添加額外參數ids

1.方式一

    以上幾種雖然能夠達到參數化的目的,但可讀性不太友好,爲改善可讀性,能夠爲parametrize()引入一個額外的參數ids,使列表中每一個元素都被標識。ids是一個字符串列表和數據對象列表和長度一致。以下所示:

import pytest

def add(x:int,y:int)->int:
    return x+y

paras=((1,2),(3,5),(7,8),(10,-98))

parasIds=[f"{x},{y}" for x,y in paras]

@pytest.mark.parametrize("p",paras,ids=parasIds)
def test_add(p):
    res=add(p[0],p[1])
    expect=p[0]+p[1]
    assert res==expect

運行結果以下所示

>>> pytest -v test_04.py
========================= test session starts ===================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 4 items

test_04.py::test_add[1,2] PASSED                                       [ 25%]
test_04.py::test_add[3,5] PASSED                                       [ 50%]
test_04.py::test_add[7,8] PASSED                                       [ 75%]
test_04.py::test_add[10,-98] PASSED                                    100%]

=================================== 4 passed in 0.11s ============================

    parametrize()不只適於通常的測試函數,也能夠適用類,在用於類中,則數據集會被傳遞給該類的全部方法,以下所示:

import pytest

paras=((1,2),(3,5),(7,8),(10,-98))
parasIds=[f"{x},{y}" for x,y in paras]

class Oper:
    _x=0
    _y=0

    def __int__(self,x,y):
        self._x=x
        self._y=y

    @classmethod
    def add(cls,x,y):
        return x+y

    @classmethod
    def sub(cls,x,y):
        return x-y

@pytest.mark.parametrize("p",paras,ids=parasIds)
class TestOper:
    def test_add(self,p):
        res=Oper.add(p[0],p[1])
        expect=p[0]+p[1]
        assert res==expect

    def test_sub(self,p):
        res = Oper.sub(p[0], p[1])
        expect = p[0] - p[1]
        assert res == expect

運行結果以下所示

>>> pytest -v test_04.py
============================= test session starts =============================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 8 items

test_04.py::TestOper::test_add[1,2] PASSED                                  [ 12%]
test_04.py::TestOper::test_add[3,5] PASSED                                  [ 25%]
test_04.py::TestOper::test_add[7,8] PASSED                                  [ 37%]
test_04.py::TestOper::test_add[10,-98] PASSED                               [ 50%]
test_04.py::TestOper::test_sub[1,2] PASSED                                  [ 62%]
test_04.py::TestOper::test_sub[3,5] PASSED                                  [ 75%]
test_04.py::TestOper::test_sub[7,8] PASSED                                  [ 87%]
test_04.py::TestOper::test_sub[10,-98] PASSED                               [100%]

============================ 8 passed in 0.13s ================================

2.方式二

    在給@pytest.mark.parametrize()裝飾器傳入參數列表時,還能夠在參數值中定義一個id作爲標識,其語法格式以下所示:

@pytest.mark.parametrize(<value>,id="id")

    示例以下所示:

import pytest

class Oper:
    _x=0
    _y=0

    def __int__(self,x,y):
        self._x=x
        self._y=y

    @classmethod
    def add(cls,x,y):
        return x+y

    @classmethod
    def sub(cls,x,y):
        return x-y

@pytest.mark.parametrize("p",[pytest.param((1,2),id="id-1"),pytest.param((3,5),id="id-2"),
                              pytest.param((7,8),id="id-3"),pytest.param((10,-98),id="id-4")])
class TestOper:
    def test_add(self,p):
        res=Oper.add(p[0],p[1])
        expect=p[0]+p[1]
        assert res==expect

    def test_sub(self,p):
        res = Oper.sub(p[0], p[1])
        expect = p[0] - p[1]
        assert res == expect

運行結果以下所示

>>> pytest -v test_04.py
==============test session starts ====================================
platform win32 -- Python 3.7.6, pytest-5.4.2, py-1.8.1, pluggy-0.13.1 -- d:\program files\python\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\Surpass\Documents\PycharmProjects\PytestStudy\Lesson02
collected 8 items

test_04.py::TestOper::test_add[id-1] PASSED                             [ 12%]
test_04.py::TestOper::test_add[id-2] PASSED                             [ 25%]
test_04.py::TestOper::test_add[id-3] PASSED                             [ 37%]
test_04.py::TestOper::test_add[id-4] PASSED                             [ 50%]
test_04.py::TestOper::test_sub[id-1] PASSED                             [ 62%]
test_04.py::TestOper::test_sub[id-2] PASSED                             [ 75%]
test_04.py::TestOper::test_sub[id-3] PASSED                             [ 87%]
test_04.py::TestOper::test_sub[id-4] PASSED                             [100%]

=============================== 8 passed in 0.19s =============================

    在id不能被參數批量生成,須要自定義時,這個方法很是適用。

原文地址:http://www.javashuo.com/article/p-qreunrvh-nn.html

本文同步在微信訂閱號上發佈,如各位小夥伴們喜歡個人文章,也能夠關注個人微信訂閱號:woaitest,或掃描下面的二維碼添加關注:
MyQRCode.jpg

相關文章
相關標籤/搜索