allow to specify parametrize inputs as a comma-separated string
add Wouter to changelog and to authors
This commit is contained in:
parent
bc5a5a63f2
commit
c294a417bd
1
AUTHORS
1
AUTHORS
|
@ -7,6 +7,7 @@ Ronny Pfannschmidt
|
||||||
Benjamin Peterson
|
Benjamin Peterson
|
||||||
Floris Bruynooghe
|
Floris Bruynooghe
|
||||||
Jason R. Coombs
|
Jason R. Coombs
|
||||||
|
Wouter van Ackooy
|
||||||
Samuele Pedroni
|
Samuele Pedroni
|
||||||
Brianna Laugher
|
Brianna Laugher
|
||||||
Carl Friedrich Bolz
|
Carl Friedrich Bolz
|
||||||
|
|
|
@ -4,6 +4,13 @@ Changes between 2.3.5 and 2.4.DEV
|
||||||
- fix issue 308 - allow to mark/xfail/skip individual parameter sets
|
- fix issue 308 - allow to mark/xfail/skip individual parameter sets
|
||||||
when parametrizing. Thanks Brianna Laugher.
|
when parametrizing. Thanks Brianna Laugher.
|
||||||
|
|
||||||
|
- simplify parametrize() signature: allow to pass a CSV-separated string
|
||||||
|
to specify argnames. For example: ``pytest.mark.parametrize("input,expected", [(1,2), (2,3)])`` is possible now in addition to the prior
|
||||||
|
``pytest.mark.parametrize(("input", "expected"), ...)``.
|
||||||
|
|
||||||
|
- fix issue 306 - cleanup of -k/-m options to only match markers/test
|
||||||
|
names/keywords respectively. Thanks Wouter van Ackooy.
|
||||||
|
|
||||||
- (experimental) allow fixture functions to be
|
- (experimental) allow fixture functions to be
|
||||||
implemented as context managers. Thanks Andreas Pelme,
|
implemented as context managers. Thanks Andreas Pelme,
|
||||||
Vladimir Keleshev.
|
Vladimir Keleshev.
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#
|
#
|
||||||
__version__ = '2.4.0.dev2'
|
__version__ = '2.4.0.dev3'
|
||||||
|
|
|
@ -649,7 +649,8 @@ class Metafunc(FuncargnamesCompatAttr):
|
||||||
during the collection phase. If you need to setup expensive resources
|
during the collection phase. If you need to setup expensive resources
|
||||||
see about setting indirect=True to do it rather at test setup time.
|
see about setting indirect=True to do it rather at test setup time.
|
||||||
|
|
||||||
:arg argnames: an argument name or a list of argument names
|
:arg argnames: a comma-separated string denoting one or more argument
|
||||||
|
names, or a list/tuple of argument strings.
|
||||||
|
|
||||||
:arg argvalues: The list of argvalues determines how often a
|
:arg argvalues: The list of argvalues determines how often a
|
||||||
test is invoked with different argument values. If only one
|
test is invoked with different argument values. If only one
|
||||||
|
@ -688,7 +689,8 @@ class Metafunc(FuncargnamesCompatAttr):
|
||||||
argvalues = unwrapped_argvalues
|
argvalues = unwrapped_argvalues
|
||||||
|
|
||||||
if not isinstance(argnames, (tuple, list)):
|
if not isinstance(argnames, (tuple, list)):
|
||||||
argnames = (argnames,)
|
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
|
||||||
|
if len(argnames) == 1:
|
||||||
argvalues = [(val,) for val in argvalues]
|
argvalues = [(val,) for val in argvalues]
|
||||||
if not argvalues:
|
if not argvalues:
|
||||||
argvalues = [(_notexists,) * len(argnames)]
|
argvalues = [(_notexists,) * len(argnames)]
|
||||||
|
|
|
@ -30,7 +30,7 @@ pytest supports test parametrization in several well-integrated ways:
|
||||||
|
|
||||||
.. regendoc: wipe
|
.. regendoc: wipe
|
||||||
|
|
||||||
.. versionadded:: 2.2
|
.. versionadded:: 2.2, improved in 2.4
|
||||||
|
|
||||||
The builtin ``pytest.mark.parametrize`` decorator enables
|
The builtin ``pytest.mark.parametrize`` decorator enables
|
||||||
parametrization of arguments for a test function. Here is a typical example
|
parametrization of arguments for a test function. Here is a typical example
|
||||||
|
@ -39,7 +39,7 @@ to an expected output::
|
||||||
|
|
||||||
# content of test_expectation.py
|
# content of test_expectation.py
|
||||||
import pytest
|
import pytest
|
||||||
@pytest.mark.parametrize(("input", "expected"), [
|
@pytest.mark.parametrize("input,expected", [
|
||||||
("3+5", 8),
|
("3+5", 8),
|
||||||
("2+4", 6),
|
("2+4", 6),
|
||||||
("6*9", 42),
|
("6*9", 42),
|
||||||
|
@ -47,23 +47,24 @@ to an expected output::
|
||||||
def test_eval(input, expected):
|
def test_eval(input, expected):
|
||||||
assert eval(input) == expected
|
assert eval(input) == expected
|
||||||
|
|
||||||
Here, the ``@parametrize`` decorator defines three different argument
|
Here, the ``@parametrize`` decorator defines three different ``(input,output)``
|
||||||
sets for the two ``(input, output)`` arguments of the ``test_eval`` function
|
tuples so that that the ``test_eval`` function will run three times using
|
||||||
which will thus run three times::
|
them in turn::
|
||||||
|
|
||||||
$ py.test
|
$ py.test
|
||||||
=========================== test session starts ============================
|
============================= test session starts ==============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev3
|
||||||
|
plugins: xdist, cache, cli, pep8, xprocess, cov, capturelog, bdd-splinter, rerunfailures, instafail, localserver
|
||||||
collected 3 items
|
collected 3 items
|
||||||
|
|
||||||
test_expectation.py ..F
|
test_expectation.py ..F
|
||||||
|
|
||||||
================================= FAILURES =================================
|
=================================== FAILURES ===================================
|
||||||
____________________________ test_eval[6*9-42] _____________________________
|
______________________________ test_eval[6*9-42] _______________________________
|
||||||
|
|
||||||
input = '6*9', expected = 42
|
input = '6*9', expected = 42
|
||||||
|
|
||||||
@pytest.mark.parametrize(("input", "expected"), [
|
@pytest.mark.parametrize("input,expected", [
|
||||||
("3+5", 8),
|
("3+5", 8),
|
||||||
("2+4", 6),
|
("2+4", 6),
|
||||||
("6*9", 42),
|
("6*9", 42),
|
||||||
|
@ -74,19 +75,21 @@ which will thus run three times::
|
||||||
E + where 54 = eval('6*9')
|
E + where 54 = eval('6*9')
|
||||||
|
|
||||||
test_expectation.py:8: AssertionError
|
test_expectation.py:8: AssertionError
|
||||||
==================== 1 failed, 2 passed in 0.01 seconds ====================
|
====================== 1 failed, 2 passed in 0.02 seconds ======================
|
||||||
|
|
||||||
As expected only one pair of input/output values fails the simple test function.
|
As designed in this example, only one pair of input/output values fails
|
||||||
And as usual with test function arguments, you can see the ``input`` and ``output`` values in the traceback.
|
the simple test function. And as usual with test function arguments,
|
||||||
|
you can see the ``input`` and ``output`` values in the traceback.
|
||||||
|
|
||||||
Note that there ways how you can mark a class or a module,
|
Note that you could also use the parametrize marker on a class or a module
|
||||||
see :ref:`mark`.
|
(see :ref:`mark`) which would invoke several functions with the argument sets.
|
||||||
|
|
||||||
It is also possible to mark individual test instances within parametrize::
|
It is also possible to mark individual test instances within parametrize,
|
||||||
|
for example with the builtin ``mark.xfail``::
|
||||||
|
|
||||||
# content of test_expectation.py
|
# content of test_expectation.py
|
||||||
import pytest
|
import pytest
|
||||||
@pytest.mark.parametrize(("input", "expected"), [
|
@pytest.mark.parametrize("input,expected", [
|
||||||
("3+5", 8),
|
("3+5", 8),
|
||||||
("2+4", 6),
|
("2+4", 6),
|
||||||
pytest.mark.xfail(("6*9", 42)),
|
pytest.mark.xfail(("6*9", 42)),
|
||||||
|
@ -94,6 +97,27 @@ It is also possible to mark individual test instances within parametrize::
|
||||||
def test_eval(input, expected):
|
def test_eval(input, expected):
|
||||||
assert eval(input) == expected
|
assert eval(input) == expected
|
||||||
|
|
||||||
|
Let's run this::
|
||||||
|
|
||||||
|
$ py.test
|
||||||
|
============================= test session starts ==============================
|
||||||
|
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev3
|
||||||
|
plugins: xdist, cache, cli, pep8, xprocess, cov, capturelog, bdd-splinter, rerunfailures, instafail, localserver
|
||||||
|
collected 3 items
|
||||||
|
|
||||||
|
test_expectation.py ..x
|
||||||
|
|
||||||
|
===================== 2 passed, 1 xfailed in 0.02 seconds ======================
|
||||||
|
|
||||||
|
The one parameter set which caused a failure previously now
|
||||||
|
shows up as an "xfailed (expected to fail)" test.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
In versions prior to 2.4 one needed to specify the argument
|
||||||
|
names as a tuple. This remains valid but the simpler ``"name1,name2,..."``
|
||||||
|
comma-separated-string syntax is now advertised fist because
|
||||||
|
it's easier to write, produces less line noise.
|
||||||
|
|
||||||
.. _`pytest_generate_tests`:
|
.. _`pytest_generate_tests`:
|
||||||
|
|
||||||
|
@ -140,15 +164,15 @@ Let's also run with a stringinput that will lead to a failing test::
|
||||||
|
|
||||||
$ py.test -q --stringinput="!" test_strings.py
|
$ py.test -q --stringinput="!" test_strings.py
|
||||||
F
|
F
|
||||||
================================= FAILURES =================================
|
=================================== FAILURES ===================================
|
||||||
___________________________ test_valid_string[!] ___________________________
|
_____________________________ test_valid_string[!] _____________________________
|
||||||
|
|
||||||
stringinput = '!'
|
stringinput = '!'
|
||||||
|
|
||||||
def test_valid_string(stringinput):
|
def test_valid_string(stringinput):
|
||||||
> assert stringinput.isalpha()
|
> assert stringinput.isalpha()
|
||||||
E assert <built-in method isalpha of str object at 0x2ba729dab300>()
|
E assert <built-in method isalpha of str object at 0x7fd657390fd0>()
|
||||||
E + where <built-in method isalpha of str object at 0x2ba729dab300> = '!'.isalpha
|
E + where <built-in method isalpha of str object at 0x7fd657390fd0> = '!'.isalpha
|
||||||
|
|
||||||
test_strings.py:3: AssertionError
|
test_strings.py:3: AssertionError
|
||||||
|
|
||||||
|
@ -160,8 +184,8 @@ listlist::
|
||||||
|
|
||||||
$ py.test -q -rs test_strings.py
|
$ py.test -q -rs test_strings.py
|
||||||
s
|
s
|
||||||
========================= short test summary info ==========================
|
=========================== short test summary info ============================
|
||||||
SKIP [1] /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:974: got empty parameter set, function test_valid_string at /tmp/doc-exec-240/test_strings.py:1
|
SKIP [1] /home/hpk/p/pytest/_pytest/python.py:999: got empty parameter set, function test_valid_string at /tmp/doc-exec-2/test_strings.py:1
|
||||||
|
|
||||||
For further examples, you might want to look at :ref:`more
|
For further examples, you might want to look at :ref:`more
|
||||||
parametrization examples <paramexamples>`.
|
parametrization examples <paramexamples>`.
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -12,7 +12,7 @@ def main():
|
||||||
name='pytest',
|
name='pytest',
|
||||||
description='py.test: simple powerful testing with Python',
|
description='py.test: simple powerful testing with Python',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version='2.4.0.dev2',
|
version='2.4.0.dev3',
|
||||||
url='http://pytest.org',
|
url='http://pytest.org',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
|
|
|
@ -221,6 +221,16 @@ class TestMetafunc:
|
||||||
"*6 fail*",
|
"*6 fail*",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_parametrize_CSV(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
@pytest.mark.parametrize("x, y,", [(1,2), (2,3)])
|
||||||
|
def test_func(x, y):
|
||||||
|
assert x+1 == y
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
reprec.assertoutcome(passed=2)
|
||||||
|
|
||||||
def test_parametrize_class_scenarios(self, testdir):
|
def test_parametrize_class_scenarios(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
# same as doc/en/example/parametrize scenario example
|
# same as doc/en/example/parametrize scenario example
|
||||||
|
|
Loading…
Reference in New Issue