динамический параметризованный тест - PullRequest
0 голосов
/ 12 июня 2018

Я создал «динамический» список параметров, которые я передаю параметризации.

OPTIONS = ['a', 'b', 'c']

def get_unique_pairs():
    unique_list = []
    for first in OPTIONS:
        for second OPTIONS:
            if first == second:
                continue
            unique_list.append({'first':first, 'second':second))
    return unique_list

def some_func()
    unique_pairs = get_unique_pairs()
    result = []
    for pair in unique_pair:
        if test(pair):
           continue
        else:
           result.append(pair)
    return pair

@pytest.mark.parametrize('param', some_fnc())
def test_fnc(param):
    first = param['first']
    second = param['second']

Ввод, который я хочу передать test_fnc, это [('a','b'),('a','c')...('c','b')], где первый и второй элементы никогда не совпадают.Есть некоторая дополнительная логика, которую я использую для дальнейшего удаления определенных пар.

Когда я запускаю тест, я получаю вывод:

::test_fnc[param0] PASSED
::test_fnc[param1] PASSED
::test_fnc[param2] PASSED

У меня есть две проблемы:

  1. Я не совсем уверен, как описать, что я делаю, чтобы найти дополнительную документацию / помощь.
  2. Я хотел бы получить более описательный вывод (т. Е. Не param0), и я хотел бы продолжить использование словарей для передачи данных в тест.

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Я бы написал так:

import pytest
import itertools


OPTIONS = ['a', 'b', 'c']

@pytest.mark.parametrize(
    'param',
    itertools.permutations(OPTIONS, 2),
    ids=lambda pair: "first={}, second={}".format(*pair)
)
def test_fn(param):
    first, second = param
    assert first != second

Результат:

> pytest --verbose 
================================ test session starts =================================
platform linux2 -- Python 2.7.12, pytest-3.6.1, py-1.5.3, pluggy-0.6.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /home/paulos/work/lixo/tests, inifile:
collected 6 items

test_foo.py::test_fn[first=a, second=b] PASSED                                     [ 16%]
test_foo.py::test_fn[first=a, second=c] PASSED                                     [ 33%]
test_foo.py::test_fn[first=b, second=a] PASSED                                     [ 50%]
test_foo.py::test_fn[first=b, second=c] PASSED                                     [ 66%]
test_foo.py::test_fn[first=c, second=a] PASSED                                     [ 83%]
test_foo.py::test_fn[first=c, second=b] PASSED                                     [100%]

================================ 6 passed in 0.03 seconds ================================

[обновление]

Я думаю, что этот ответ - решение, которое ябуду использовать.Каждый день - школьный день!(Из любопытства есть способ, которым я мог бы быть «param» в нечто вроде «first, second», чтобы test_foo (param) был test_foo (first, second). Я не уверен, что на самом деле что-то помогает ...но мне любопытно - Ф. Эллиот

Если вы не против test_fn[a-b] вместо test_fn[a, b]:

@pytest.mark.parametrize(
    'first,second',
    itertools.permutations(OPTIONS, 2),
)
def test_fn(first, second):
    assert first != second

На практике мы на самом деле не бежимтесты с --verbose в любом случае, поэтому большую часть времени результат будет просто точкой для каждого теста.

0 голосов
/ 12 июня 2018
  1. Как Пауло Скардина , упомянутый в комментарии, не изобретать велосипед, используйте itertools.combinations.
  2. Вы ищете аргумент idsв parametrize крюк .Это либо список имен для каждого аргумента, либо функция, которая принимает аргумент и возвращает строку - repr - это простое решение для встроенных типов.

Комбинированный пример:

import itertools
import pytest


opts = ['a', 'b', 'c']


@pytest.mark.parametrize('param', itertools.combinations(opts, 2), ids=repr)
def test_fn(param):
    first = param[0]
    second = param[1]
    assert first != second
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...