2016-12-20 12 views
5

Интересно, как выбрать подмножество моих тестов с использованием pytest пользовательских маркеровКак выбрать подмножество тестов в pytest с помощью пользовательских маркеров на Params

Простой тест работает, как ожидалось:

код с одним заметное параметр

import pytest 

@pytest.mark.parametrize('a', [pytest.mark.my_custom_marker(0), 1]) 
@pytest.mark.parametrize('b', [0, 1]) 
def test_increment(a, b): 
    pass 

Если я только хочу, чтобы запустить тест, помеченные 'my_custom_marker'

Выход

$ pytest test_machin.py -m my_custom_marker --collect-only 
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.32, pluggy-0.4.0 
rootdir: /home/mvelay/workspace/sandbox, inifile: 
plugins: hypothesis-3.6.0, html-1.12.0, xdist-1.15.0, timeout-1.0.0 
collected 4 items 
<Module 'test_machin.py'> 
    <Function 'test_increment[0-0]'> 
    <Function 'test_increment[0-1]'> 

Но как только я пытаюсь проверить мульти отмеченных параметров, я столкнулся вопрос

кода с двумя маркированными параметрами при

import pytest 

@pytest.mark.parametrize('a', [pytest.mark.my_custom_marker(0), 1]) 
@pytest.mark.parametrize('b', [pytest.mark.my_custom_marker(0), 1]) 
def test_increment(a, b): 
    pass 

Выходных

$ pytest -m my_custom_marker test_machin.py --collect-only 
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.32, pluggy-0.4.0 
rootdir: /home/mvelay/workspace/sandbox, inifile: 
plugins: hypothesis-3.6.0, html-1.12.0, xdist-1.15.0, timeout-1.0.0 
collected 4 items 
<Module 'test_machin.py'> 
    <Function 'test_increment[0-0]'> 
    <Function 'test_increment[0-1]'> 
    <Function 'test_increment[1-0]'> 

Ожидалось, что только комбинация [0-0] бежит.

Есть ли способ сделать это элегантным способом?

ответ

1

Вы можете использовать два различных маркеров следующим образом:

import pytest 

@pytest.mark.parametrize('a', [pytest.mark.marker_a(0), 1]) 
@pytest.mark.parametrize('b', [pytest.mark.marker_b(0), 1]) 
def test_increment(a, b): 
    pass 

и указать выражение метки:

$ pytest test_machin.py -m "marker_a and marker_b" --collect-only 
============= test session starts =============================== 
platform darwin -- Python 2.7.10, pytest-3.0.5, py-1.4.32, pluggy-0.4.0 
rootdir: /Users/yangchao/Code, inifile: 
collected 4 items 
<Module 'test_machin.py'> 
    <Function 'test_increment[0-0]'> 
============= 3 tests deselected ================================= 
============= 3 deselected in 0.00 seconds ======================= 
0

Ответ здесь вы злоупотребляете Marks. Test Runners обычно построены для проверки всего пространства перестановок. Вы обнаружите, что все в pytest предназначено для создания декартова продукта. Это происходит потому, что люди обычно хотят как можно больше протестировать при написании наименьшего количества кода. При рассмотрении этого вы окажетесь аномалиями, и это должно быть XY problem

Это не означает, что ответа нет. Итак, что вы действительно хотите здесь сделать? Вот то, что вы просите ...

Интересно, как выбрать подмножество моих тестов с использованием pytest пользовательских маркеров

Но мне интересно, если то, что вы говорите ...

Я хочу выполнить свой тест с различными наборами параметров по требованию с использованием меток.

Это намного проще. Здесь в своей простейшей форме ...

import pytest 

@pytest.mark.A 
def test_add(): 

    a = 2 
    b = 1 
    result = add(a,b) 
    assert result == 3 

@pytest.mark.B 
def test_add_with_failure(): 

    a = 1 
    b = 2  
    add(a,b) 
    #expect it to fail 

def add(a, b): 
    assert a>b 
    return a+b 

Теперь каждый из этих тестовых наборов может быть вызван из командной строки с метками.

py.test -m A tests.py py.test -m B tests.py

Это то, что было оригинальное задание на Марка. Чтобы найти конкретный тест или группу тестов и выполнить его (их). Если вы пытаетесь сделать что-то помимо поиска конкретного теста для выполнения, вы будете бороться с каркасом.

Если вы хотите что-то немного более каноническое pytest, вы можете взять часть шаблона и закрепить его. Это позволяет добавить много перестановок. Как и ...

@pytest.fixture(params=[(2,1,3)]) 
def always_pass(request): 
    return request.param 

@pytest.mark.A 
def test_add(always_pass): 

    a, b, expected = always_pass 
    result = add(a,b) 
    assert result == expected 

Или вы можете пойти на полный и построить все тесты в один большой, наборный арматуре ...

@pytest.fixture(params=[ 
    (2, 1, 3), 
    (1, 2, 'fail') 
    ]) 
def all_the_things(request): 
    return request.param 

@pytest.mark.A 
def test_add(all_the_things): 

    a, b, expected = all_the_things 

    if expected == 'fail' 
    with pytest.raises(AssertionError): 
     result = add(a,b) 
    else: 
    assert result == expected 

Дело в том, что структура говорит вам что-то, когда оно складывает все вместе. Его высказывание «есть лучший способ». Не сражайтесь с каркасом, обнимайте его! Если вы посмотрите ближе на parameterize, рассматривая принципы, описанные выше, вы увидите его действительно особенность, позволяющую вам более тонкую, зернистую композицию. Таким образом, вы можете построить декартово произведение отдельных параметров, используя укладку декораторов и метки.

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

  • Нет связанных вопросов^_^