簡體   English   中英

如何使用 py.test 對多個項目執行多個測試

[英]how to execute multiple tests on multiple items with py.test

我是 python 和 py.test 的新手。 我正在尋找一種對多個項目運行多個測試的方法,但找不到它。 我相信當你知道如何去做時,這很簡單。

我已經簡化了我想要做的事情,使其易於理解。

如果我有一個 Test 類定義了一系列這樣的測試:

class SeriesOfTests:
    def test_greater_than_30(self, itemNo):
        assert (itemNo > 30), "not greather than 30"
    def test_lesser_than_30(self, itemNo):
        assert (itemNo < 30), "not lesser thant 30"
    def test_modulo_2(self, itemNo):
        assert (itemNo % 2) == 0, "not divisible by 2"

我想對從以下函數獲得的每個項目執行此 SeriesOfTest:

def getItemNo():
    return [0,11,33]

我試圖獲得的結果是這樣的:

RESULT : 
Test "itemNo = 0"
  - test_greater_than_30 = failed
  - test_lesser_than_30 = success
  - test_modulo_2 = success

Test "itemNo = 11"
  - test_greater_than_30 = failed
  - test_lesser_than_30 = success
  - test_modulo_2 = failed

Test "itemNo = 33"
  - test_greater_than_30 = success
  - test_lesser_than_30 = failed
  - test_modulo_2 = failed

我怎樣才能用 py.test 做到這一點?

比你們(還有女孩)

安德烈

使用夾具

import pytest

@pytest.fixture(params=[0, 11, 33])
def itemNo(request):
    return request.param

def test_greater_than_30(itemNo):
    assert (itemNo > 30), "not greather than 30"
def test_lesser_than_30(itemNo):
    assert (itemNo < 30), "not lesser thant 30"
def test_modulo_2(itemNo):
    assert (itemNo % 2) == 0, "not divisible by 2"

注意:fixture 函數的名稱( itemNo )和測試函數的參數名稱應該相同。

請參閱演示運行


更新

import pytest

class FunctionWrapper(str):
    def __init__(self, f):
        self.f = f
    def __call__(self, *args, **kwargs):
        return self.f(*args, **kwargs)
    def __str__(self):
        return self.f.__name__

def greater_than_30(itemNo):
    assert (itemNo > 30), "not greater than 30"
def lesser_than_30(itemNo):
    assert (itemNo < 30), "not lesser thant 30"
def modulo_2(itemNo):
    assert (itemNo % 2) == 0, "not divisible by 2"

@pytest.fixture(params=[0, 11, 33])
def itemNo(request):
    return request.param

@pytest.fixture(params=map(FunctionWrapper, [
    greater_than_30, lesser_than_30, modulo_2
]))
def assertion_func(request):
    return request.param

def test_item_no(itemNo, assertion_func):
    assertion_func(itemNo)

使用-v --tb=no選項。

例如:

============================= test session starts ==============================
platform linux2 -- Python 2.7.5 -- pytest-2.3.5 -- /usr/bin/python
collected 9 items

test_sample.py:26: test_item_no[0-greater_than_30] FAILED
test_sample.py:26: test_item_no[0-lesser_than_30] PASSED
test_sample.py:26: test_item_no[0-modulo_2] PASSED
test_sample.py:26: test_item_no[11-greater_than_30] FAILED
test_sample.py:26: test_item_no[11-lesser_than_30] PASSED
test_sample.py:26: test_item_no[11-modulo_2] FAILED
test_sample.py:26: test_item_no[33-greater_than_30] PASSED
test_sample.py:26: test_item_no[33-lesser_than_30] FAILED
test_sample.py:26: test_item_no[33-modulo_2] FAILED

====================== 5 failed, 4 passed in 0.03 seconds ======================

http://asciinema.org/a/6562

忘記之前的答案。 鑒於您需要按值對測試進行分組,您可以使用場景 我剛剛改編了文檔中的示例:

import pytest

def pytest_generate_tests(metafunc):
    idlist = []
    argvalues = []
    for scenario in metafunc.cls.scenarios:
        idlist.append(scenario[0])
        items = scenario[1].items()
        argnames = [x[0] for x in items]
        argvalues.append(([x[1] for x in items]))
    metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class")

scenario1 = ('itemNo = 0', {'itemNo': 0})
scenario2 = ('itemNo = 11', {'itemNo': 11})
scenario3 = ('itemNo = 33', {'itemNo': 33})

class TestSeries:
    scenarios = [scenario1, scenario2, scenario3]
    
    def test_greater_than_30(self, itemNo):
        assert (itemNo > 30), "not greather than 30"
    def test_lesser_than_30(self, itemNo):
        assert (itemNo < 30), "not lesser thant 30"
    def test_modulo_2(self, itemNo):
        assert (itemNo % 2) == 0, "not divisible by 2"

輸出是:

$ py.test -v
============ test session starts ==============================================
platform linux2 -- Python 2.7.4 -- pytest-2.4.2 -- /home/jose/.virtualenvs/pytest1/bin/python
collected 9 items 

test_first.py:23: TestSeries.test_greater_than_30[itemNo = 0] FAILED
test_first.py:25: TestSeries.test_lesser_than_30[itemNo = 0] PASSED
test_first.py:27: TestSeries.test_modulo_2[itemNo = 0] PASSED
test_first.py:23: TestSeries.test_greater_than_30[itemNo = 11] FAILED
test_first.py:25: TestSeries.test_lesser_than_30[itemNo = 11] PASSED
test_first.py:27: TestSeries.test_modulo_2[itemNo = 11] FAILED
test_first.py:23: TestSeries.test_greater_than_30[itemNo = 33] PASSED
test_first.py:25: TestSeries.test_lesser_than_30[itemNo = 33] FAILED
test_first.py:27: TestSeries.test_modulo_2[itemNo = 33] FAILED

我認為這是你能得到的最接近的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM