2013-11-28 3 views
3

Я новичок в python, а также в py.test. Я ищу способ запуска нескольких тестов для нескольких элементов и не могу их найти. Я уверен, что это довольно просто, когда вы знаете, как это сделать.Как выполнить несколько тестов для нескольких элементов с помощью 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?

, чем вы, ребята (и девочки)

Андре

ответ

1

Забудьте о предыдущем ответе. Учитывая, что вам нужны тесты, которые нужно сгруппировать по значению, вы можете использовать scenarios. Я только адаптировали пример из документации:

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 

Я думаю, что это ближайший вы можете получить.

+0

Извините, но, как я уже сказал, falsetru, я хочу, чтобы результат был сгруппирован по itemNo. –

+0

Проверьте новый код, чтобы узнать, подходит ли он вам ... –

+0

Это больше похоже на то, что я хочу ... Теперь мне просто нужен способ генерации списка сценариев динамически из результата моей функции getItemNo() ... –

2

Использование fixture:

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" 

ПРИМЕЧАНИЕ: Название функции арматуре (itemNo) и имя параметра функций тестирования должны быть одинаковыми.

См. Demo run.


UPDATE

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

+0

Извините, но это не тот результат, который я хочу. Результат должен показывать отказ (или успех) каждой функции для itemNo. В вашем примере это показывает отказ каждого элемента ItemNo для функции. –

+0

@ AndréGodin, я обновил ответ. Это даст вам то, что вы хотите. (Используйте опцию '-v --tb = no') – falsetru

+0

спасибо за это, но опять же, ваш результат не сгруппирован по itemNo. Возможно ли, чтобы он был сгруппирован таким образом, что он будет показывать результат каждого метода тестирования для элемента ItemNo, а затем продолжить со вторым itemNo и так далее?пожалуйста, обратитесь к моему примеру, я хочу –

Смежные вопросы