Merged in parametrized-fixture-override (pull request #257)

allow to override parametrized fixtures with non-parametrized ones and vice versa
This commit is contained in:
Bruno Oliveira 2015-03-12 09:40:56 -03:00
commit eead0365b5
10 changed files with 413 additions and 82 deletions

View File

@ -1,10 +1,10 @@
2.7.0.dev (compared to 2.6.4) 2.7.0.dev (compared to 2.6.4)
----------------------------- -----------------------------
- fix issue616: conftest.py files and their contained fixutres are now - fix issue616: conftest.py files and their contained fixutres are now
properly considered for visibility, independently from the exact properly considered for visibility, independently from the exact
current working directory and test arguments that are used. current working directory and test arguments that are used.
Many thanks to Eric Siegerman and his PR235 which contains Many thanks to Eric Siegerman and his PR235 which contains
systematic tests for conftest visibility and now passes. systematic tests for conftest visibility and now passes.
This change also introduces the concept of a ``rootdir`` which This change also introduces the concept of a ``rootdir`` which
is printed as a new pytest header and documented in the pytest is printed as a new pytest header and documented in the pytest
@ -12,7 +12,7 @@
- change reporting of "diverted" tests, i.e. tests that are collected - change reporting of "diverted" tests, i.e. tests that are collected
in one file but actually come from another (e.g. when tests in a test class in one file but actually come from another (e.g. when tests in a test class
come from a base class in a different file). We now show the nodeid come from a base class in a different file). We now show the nodeid
and indicate via a postfix the other file. and indicate via a postfix the other file.
- add ability to set command line options by environment variable PYTEST_ADDOPTS. - add ability to set command line options by environment variable PYTEST_ADDOPTS.
@ -24,7 +24,7 @@
- fix issue650: new option ``--docttest-ignore-import-errors`` which - fix issue650: new option ``--docttest-ignore-import-errors`` which
will turn import errors in doctests into skips. Thanks Charles Cloud will turn import errors in doctests into skips. Thanks Charles Cloud
for the complete PR. for the complete PR.
- fix issue655: work around different ways that cause python2/3 - fix issue655: work around different ways that cause python2/3
to leak sys.exc_info into fixtures/tests causing failures in 3rd party code to leak sys.exc_info into fixtures/tests causing failures in 3rd party code
@ -55,6 +55,7 @@
- "python_classes" and "python_functions" options now support glob-patterns - "python_classes" and "python_functions" options now support glob-patterns
for test discovery, as discussed in issue600. Thanks Ldiary Translations. for test discovery, as discussed in issue600. Thanks Ldiary Translations.
- allow to override parametrized fixtures with non-parametrized ones and vice versa (bubenkoff).
2.6.4 2.6.4
---------- ----------

View File

@ -30,8 +30,8 @@ You can submit your plugin by subscribing to the `pytest-dev mail list
mail pointing to your existing pytest plugin repository which must have mail pointing to your existing pytest plugin repository which must have
the following: the following:
- PyPI presence with a ``setup.py`` that contains a license, ``pytest-`` - PyPI presence with a ``setup.py`` that contains a license, ``pytest-``
prefixed, version number, authors, short and long description. prefixed, version number, authors, short and long description.
- a ``tox.ini`` for running tests using `tox <http://tox.testrun.org>`_. - a ``tox.ini`` for running tests using `tox <http://tox.testrun.org>`_.
@ -43,7 +43,7 @@ the following:
If no contributor strongly objects and two agree, the repo will be If no contributor strongly objects and two agree, the repo will be
transferred to the ``pytest-dev`` organisation and you'll become a transferred to the ``pytest-dev`` organisation and you'll become a
member of the ``pytest-dev`` team, with commit rights to all projects. member of the ``pytest-dev`` team, with commit rights to all projects.
We recommend that each plugin has at least three people who have the We recommend that each plugin has at least three people who have the
right to release to pypi. right to release to pypi.
@ -128,22 +128,18 @@ Preparing Pull Requests on Bitbucket
The primary development platform for pytest is BitBucket. You can find all The primary development platform for pytest is BitBucket. You can find all
the issues there and submit your pull requests. the issues there and submit your pull requests.
1. Fork the #. Fork the
`pytest BitBucket repository <https://bitbucket.org/pytest-dev/pytest>`__. It's `pytest BitBucket repository <https://bitbucket.org/pytest-dev/pytest>`__. It's
fine to use ``pytest`` as your fork repository name because it will live fine to use ``pytest`` as your fork repository name because it will live
under your user. under your user.
.. _virtualenvactivate: #. Create a development environment
(will implicitly use http://www.virtualenv.org/en/latest/)::
2. Create and activate a fork-specific virtualenv $ make develop
(http://www.virtualenv.org/en/latest/):: $ source .env/bin/activate
$ virtualenv pytest-venv #. Clone your fork locally using `Mercurial <http://mercurial.selenic.com/>`_
$ source pytest-venv/bin/activate
.. _checkout:
3. Clone your fork locally using `Mercurial <http://mercurial.selenic.com/>`_
(``hg``) and create a branch:: (``hg``) and create a branch::
$ hg clone ssh://hg@bitbucket.org/YOUR_BITBUCKET_USERNAME/pytest $ hg clone ssh://hg@bitbucket.org/YOUR_BITBUCKET_USERNAME/pytest
@ -153,45 +149,46 @@ the issues there and submit your pull requests.
If you need some help with Mercurial, follow this quick start If you need some help with Mercurial, follow this quick start
guide: http://mercurial.selenic.com/wiki/QuickStart guide: http://mercurial.selenic.com/wiki/QuickStart
.. _testing-pytest: #. Create a development environment
(will implicitly use http://www.virtualenv.org/en/latest/)::
4. You can now edit your local working copy. To test you need to $ make develop
install the "tox" tool into your virtualenv:: $ source .env/bin/activate
$ pip install tox #. You can now edit your local working copy.
You need to have Python 2.7 and 3.3 available in your system. Now You need to have Python 2.7 and 3.4 available in your system. Now
running tests is as simple as issuing this command:: running tests is as simple as issuing this command::
$ python runtox.py -e py27,py33,flakes $ python runtox.py -e py27,py34,flakes
This command will run tests via the "tox" tool against Python 2.7 and 3.3 This command will run tests via the "tox" tool against Python 2.7 and 3.4
and also perform "flakes" coding-style checks. ``runtox.py`` is and also perform "flakes" coding-style checks. ``runtox.py`` is
a thin wrapper around ``tox`` which installs from a development package a thin wrapper around ``tox`` which installs from a development package
index where newer (not yet released to pypi) versions of dependencies index where newer (not yet released to pypi) versions of dependencies
(especially ``py``) might be present. (especially ``py``) might be present.
To run tests on py27 and pass options (e.g. enter pdb on failure) To run tests on py27 and pass options (e.g. enter pdb on failure)
to pytest you can do:: to pytest you can do::
$ python runtox.py -e py27 -- --pdb $ python runtox.py -e py27 -- --pdb
or to only run tests in a particular test module on py33:: or to only run tests in a particular test module on py34::
$ python runtox.py -e py33 -- testing/test_config.py $ python runtox.py -e py34 -- testing/test_config.py
5. Commit and push once your tests pass and you are happy with your change(s):: #. Commit and push once your tests pass and you are happy with your change(s)::
$ hg commit -m"<commit message>" $ hg commit -m"<commit message>"
$ hg push -b . $ hg push -b .
6. Finally, submit a pull request through the BitBucket website: #. Finally, submit a pull request through the BitBucket website:
.. image:: img/pullrequest.png .. image:: img/pullrequest.png
:width: 700px :width: 700px
:align: center :align: center
:: ::
source: YOUR_BITBUCKET_USERNAME/pytest source: YOUR_BITBUCKET_USERNAME/pytest
branch: your-branch-name branch: your-branch-name
@ -214,5 +211,3 @@ original repository. If you insist on using git with bitbucket/hg you
may try `gitifyhg <https://github.com/buchuki/gitifyhg>`_ but are on your may try `gitifyhg <https://github.com/buchuki/gitifyhg>`_ but are on your
own and need to submit pull requests through the respective platform, own and need to submit pull requests through the respective platform,
nevertheless. nevertheless.

25
Makefile Normal file
View File

@ -0,0 +1,25 @@
# Set of targets useful for development/release process
PYTHON = python2.7
PATH := $(PWD)/.env/bin:$(PATH)
# prepare virtual python environment
.env:
virtualenv .env -p $(PYTHON)
# install all needed for development
develop: .env
pip install -e . tox -r requirements-docs.txt
# clean the development envrironment
clean:
-rm -rf .env
# generate documentation
docs: develop
find doc/en -name '*.txt' -not -path 'doc/en/_build/*' | xargs .env/bin/regendoc
cd doc/en; make html
# upload documentation
upload-docs: develop
find doc/en -name '*.txt' -not -path 'doc/en/_build/*' | xargs .env/bin/regendoc --update
cd doc/en; make install

View File

@ -1712,13 +1712,17 @@ class FixtureManager:
def pytest_generate_tests(self, metafunc): def pytest_generate_tests(self, metafunc):
for argname in metafunc.fixturenames: for argname in metafunc.fixturenames:
faclist = metafunc._arg2fixturedefs.get(argname) faclist = metafunc._arg2fixturedefs.get(argname)
if faclist is None: if faclist:
continue # will raise FixtureLookupError at setup time fixturedef = faclist[-1]
for fixturedef in faclist:
if fixturedef.params is not None: if fixturedef.params is not None:
metafunc.parametrize(argname, fixturedef.params, func_params = getattr(getattr(metafunc.function, 'parametrize', None), 'args', [[None]])
indirect=True, scope=fixturedef.scope, # skip directly parametrized arguments
ids=fixturedef.ids) if argname not in func_params and argname not in func_params[0]:
metafunc.parametrize(argname, fixturedef.params,
indirect=True, scope=fixturedef.scope,
ids=fixturedef.ids)
else:
continue # will raise FixtureLookupError at setup time
def pytest_collection_modifyitems(self, items): def pytest_collection_modifyitems(self, items):
# separate parametrized setups # separate parametrized setups

View File

@ -78,20 +78,20 @@ marked ``smtp`` fixture function. Running the test looks like this::
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4
collected 1 items collected 1 items
test_smtpsimple.py F test_smtpsimple.py F
================================= FAILURES ================================= ================================= FAILURES =================================
________________________________ test_ehlo _________________________________ ________________________________ test_ehlo _________________________________
smtp = <smtplib.SMTP object at 0x2b88f2d1b0b8> smtp = <smtplib.SMTP object at 0x2b88f2d1b0b8>
def test_ehlo(smtp): def test_ehlo(smtp):
response, msg = smtp.ehlo() response, msg = smtp.ehlo()
assert response == 250 assert response == 250
> assert "merlinux" in msg > assert "merlinux" in msg
E TypeError: Type str doesn't support the buffer API E TypeError: Type str doesn't support the buffer API
test_smtpsimple.py:11: TypeError test_smtpsimple.py:11: TypeError
========================= 1 failed in 0.28 seconds ========================= ========================= 1 failed in 0.28 seconds =========================
@ -195,31 +195,31 @@ inspect what is going on and can now run the tests::
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4
collected 2 items collected 2 items
test_module.py FF test_module.py FF
================================= FAILURES ================================= ================================= FAILURES =================================
________________________________ test_ehlo _________________________________ ________________________________ test_ehlo _________________________________
smtp = <smtplib.SMTP object at 0x2b29b71bd8d0> smtp = <smtplib.SMTP object at 0x2b29b71bd8d0>
def test_ehlo(smtp): def test_ehlo(smtp):
response = smtp.ehlo() response = smtp.ehlo()
assert response[0] == 250 assert response[0] == 250
> assert "merlinux" in response[1] > assert "merlinux" in response[1]
E TypeError: Type str doesn't support the buffer API E TypeError: Type str doesn't support the buffer API
test_module.py:5: TypeError test_module.py:5: TypeError
________________________________ test_noop _________________________________ ________________________________ test_noop _________________________________
smtp = <smtplib.SMTP object at 0x2b29b71bd8d0> smtp = <smtplib.SMTP object at 0x2b29b71bd8d0>
def test_noop(smtp): def test_noop(smtp):
response = smtp.noop() response = smtp.noop()
assert response[0] == 250 assert response[0] == 250
> assert 0 # for demo purposes > assert 0 # for demo purposes
E assert 0 E assert 0
test_module.py:11: AssertionError test_module.py:11: AssertionError
========================= 2 failed in 0.28 seconds ========================= ========================= 2 failed in 0.28 seconds =========================
@ -268,7 +268,7 @@ Let's execute it::
$ py.test -s -q --tb=no $ py.test -s -q --tb=no
FFteardown smtp FFteardown smtp
2 failed in 0.21 seconds 2 failed in 0.21 seconds
We see that the ``smtp`` instance is finalized after the two We see that the ``smtp`` instance is finalized after the two
@ -377,50 +377,50 @@ So let's just do another run::
FFFF FFFF
================================= FAILURES ================================= ================================= FAILURES =================================
__________________________ test_ehlo[merlinux.eu] __________________________ __________________________ test_ehlo[merlinux.eu] __________________________
smtp = <smtplib.SMTP object at 0x2b6b796568d0> smtp = <smtplib.SMTP object at 0x2b6b796568d0>
def test_ehlo(smtp): def test_ehlo(smtp):
response = smtp.ehlo() response = smtp.ehlo()
assert response[0] == 250 assert response[0] == 250
> assert "merlinux" in response[1] > assert "merlinux" in response[1]
E TypeError: Type str doesn't support the buffer API E TypeError: Type str doesn't support the buffer API
test_module.py:5: TypeError test_module.py:5: TypeError
__________________________ test_noop[merlinux.eu] __________________________ __________________________ test_noop[merlinux.eu] __________________________
smtp = <smtplib.SMTP object at 0x2b6b796568d0> smtp = <smtplib.SMTP object at 0x2b6b796568d0>
def test_noop(smtp): def test_noop(smtp):
response = smtp.noop() response = smtp.noop()
assert response[0] == 250 assert response[0] == 250
> assert 0 # for demo purposes > assert 0 # for demo purposes
E assert 0 E assert 0
test_module.py:11: AssertionError test_module.py:11: AssertionError
________________________ test_ehlo[mail.python.org] ________________________ ________________________ test_ehlo[mail.python.org] ________________________
smtp = <smtplib.SMTP object at 0x2b6b79656780> smtp = <smtplib.SMTP object at 0x2b6b79656780>
def test_ehlo(smtp): def test_ehlo(smtp):
response = smtp.ehlo() response = smtp.ehlo()
assert response[0] == 250 assert response[0] == 250
> assert "merlinux" in response[1] > assert "merlinux" in response[1]
E TypeError: Type str doesn't support the buffer API E TypeError: Type str doesn't support the buffer API
test_module.py:5: TypeError test_module.py:5: TypeError
-------------------------- Captured stdout setup --------------------------- -------------------------- Captured stdout setup ---------------------------
finalizing <smtplib.SMTP object at 0x2b6b796568d0> finalizing <smtplib.SMTP object at 0x2b6b796568d0>
________________________ test_noop[mail.python.org] ________________________ ________________________ test_noop[mail.python.org] ________________________
smtp = <smtplib.SMTP object at 0x2b6b79656780> smtp = <smtplib.SMTP object at 0x2b6b79656780>
def test_noop(smtp): def test_noop(smtp):
response = smtp.noop() response = smtp.noop()
assert response[0] == 250 assert response[0] == 250
> assert 0 # for demo purposes > assert 0 # for demo purposes
E assert 0 E assert 0
test_module.py:11: AssertionError test_module.py:11: AssertionError
4 failed in 7.02 seconds 4 failed in 7.02 seconds
@ -519,10 +519,10 @@ Here we declare an ``app`` fixture which receives the previously defined
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4
collecting ... collected 2 items collecting ... collected 2 items
test_appsetup.py::test_smtp_exists[merlinux.eu] PASSED test_appsetup.py::test_smtp_exists[merlinux.eu] PASSED
test_appsetup.py::test_smtp_exists[mail.python.org] PASSED test_appsetup.py::test_smtp_exists[mail.python.org] PASSED
========================= 2 passed in 6.63 seconds ========================= ========================= 2 passed in 6.63 seconds =========================
Due to the parametrization of ``smtp`` the test will run twice with two Due to the parametrization of ``smtp`` the test will run twice with two
@ -583,7 +583,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4
collecting ... collected 8 items collecting ... collected 8 items
test_module.py::test_0[1] test0 1 test_module.py::test_0[1] test0 1
PASSED PASSED
test_module.py::test_0[2] test0 2 test_module.py::test_0[2] test0 2
@ -602,7 +602,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
PASSED PASSED
test_module.py::test_2[2-mod2] test2 2 mod2 test_module.py::test_2[2-mod2] test2 2 mod2
PASSED PASSED
========================= 8 passed in 0.01 seconds ========================= ========================= 8 passed in 0.01 seconds =========================
You can see that the parametrized module-scoped ``modarg`` resource caused You can see that the parametrized module-scoped ``modarg`` resource caused
@ -780,4 +780,182 @@ to a :ref:`conftest.py <conftest.py>` file or even separately installable
fixtures functions starts at test classes, then test modules, then fixtures functions starts at test classes, then test modules, then
``conftest.py`` files and finally builtin and third party plugins. ``conftest.py`` files and finally builtin and third party plugins.
Overriding fixtures on various levels
-------------------------------------
In relatively large test suite, you most likely need to ``override`` a ``global`` or ``root`` fixture with a ``locally``
defined one, keeping the test code readable and maintainable.
Override a fixture on a folder (conftest) level
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Given the tests file structure is:
::
tests/
__init__.py
conftest.py
# content of tests/conftest.py
import pytest
@pytest.fixture
def username():
return 'username'
test_something.py
# content of tests/test_something.py
def test_username(username):
assert username == 'username'
subfolder/
__init__.py
conftest.py
# content of tests/subfolder/conftest.py
import pytest
@pytest.fixture
def username(username):
return 'overridden-' + username
test_something.py
# content of tests/subfolder/test_something.py
def test_username(username):
assert username == 'overridden-username'
As you can see, a fixture with the same name can be overridden for certain test folder level.
Note that the ``base`` or ``super`` fixture can be accessed from the ``overriding``
fixture easily - used in the example above.
Override a fixture on a test module level
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Given the tests file structure is:
::
tests/
__init__.py
conftest.py
# content of tests/conftest.py
@pytest.fixture
def username():
return 'username'
test_something.py
# content of tests/test_something.py
import pytest
@pytest.fixture
def username(username):
return 'overridden-' + username
def test_username(username):
assert username == 'overridden-username'
test_something_else.py
# content of tests/test_something_else.py
import pytest
@pytest.fixture
def username(username):
return 'overridden-else-' + username
def test_username(username):
assert username == 'overridden-else-username'
In the example above, a fixture with the same name can be overridden for certain test module.
Override a fixture with direct test parametrization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Given the tests file structure is:
::
tests/
__init__.py
conftest.py
# content of tests/conftest.py
import pytest
@pytest.fixture
def username():
return 'username'
@pytest.fixture
def other_username(username):
return 'other-' + username
test_something.py
# content of tests/test_something.py
import pytest
@pytest.mark.parametrize('username', ['directly-overridden-username'])
def test_username(username):
assert username == 'directly-overridden-username'
@pytest.mark.parametrize('username', ['directly-overridden-username-other'])
def test_username_other(other_username):
assert username == 'other-directly-overridden-username-other'
In the example above, a fixture value is overridden by the test parameter value. Note that the value of the fixture
can be overridden this way even if the test doesn't use it directly (doesn't mention it in the function prototype).
Override a parametrized fixture with non-parametrized one and vice versa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Given the tests file structure is:
::
tests/
__init__.py
conftest.py
# content of tests/conftest.py
import pytest
@pytest.fixture(params=['one', 'two', 'three'])
def parametrized_username(request):
return request.param
@pytest.fixture
def non_parametrized_username(request):
return 'username'
test_something.py
# content of tests/test_something.py
import pytest
@pytest.fixture
def parametrized_username():
return 'overridden-username'
@pytest.fixture(params=['one', 'two', 'three'])
def non_parametrized_username(request):
return request.param
def test_username(parametrized_username):
assert parametrized_username == 'overridden-username'
def test_parametrized_username(non_parametrized_username):
assert non_parametrized_username in ['one', 'two', 'three']
test_something_else.py
# content of tests/test_something_else.py
def test_username(parametrized_username):
assert parametrized_username in ['one', 'two', 'three']
def test_username(non_parametrized_username):
assert non_parametrized_username == 'username'
In the example above, a parametrized fixture is overridden with a non-parametrized version, and
a non-parametrized fixture is overridden with a parametrized version for certain test module.
The same applies for the test folder level obviously.

2
requirements-docs.txt Normal file
View File

@ -0,0 +1,2 @@
sphinx==1.2.3
hg+ssh://hg@bitbucket.org/RonnyPfannschmidt/regendoc#egg=regendoc

View File

@ -13,7 +13,8 @@ classifiers = ['Development Status :: 6 - Mature',
('Programming Language :: Python :: %s' % x) for x in ('Programming Language :: Python :: %s' % x) for x in
'2 2.6 2.7 3 3.2 3.3 3.4'.split()] '2 2.6 2.7 3 3.2 3.3 3.4'.split()]
long_description = open('README.rst').read() with open('README.rst') as fd:
long_description = fd.read()
def main(): def main():

View File

@ -393,14 +393,31 @@ class TestFunction:
return 'value' return 'value'
@pytest.mark.parametrize('value', @pytest.mark.parametrize('value',
['overrided']) ['overridden'])
def test_overrided_via_param(value): def test_overridden_via_param(value):
assert value == 'overrided' assert value == 'overridden'
""") """)
rec = testdir.inline_run() rec = testdir.inline_run()
rec.assertoutcome(passed=1) rec.assertoutcome(passed=1)
def test_parametrize_overrides_parametrized_fixture(self, testdir):
"""Test parametrization when parameter overrides existing parametrized fixture with same name."""
testdir.makepyfile("""
import pytest
@pytest.fixture(params=[1, 2])
def value(request):
return request.param
@pytest.mark.parametrize('value',
['overridden'])
def test_overridden_via_param(value):
assert value == 'overridden'
""")
rec = testdir.inline_run()
rec.assertoutcome(passed=1)
def test_parametrize_with_mark(selfself, testdir): def test_parametrize_with_mark(selfself, testdir):
items = testdir.getitems(""" items = testdir.getitems("""
import pytest import pytest

View File

@ -226,6 +226,114 @@ class TestFillFixtures:
result = testdir.runpytest() result = testdir.runpytest()
assert result.ret == 0 assert result.ret == 0
def test_override_parametrized_fixture_conftest_module(self, testdir):
"""Test override of the parametrized fixture with non-parametrized one on the test module level."""
testdir.makeconftest("""
import pytest
@pytest.fixture(params=[1, 2, 3])
def spam(request):
return request.param
""")
testfile = testdir.makepyfile("""
import pytest
@pytest.fixture
def spam():
return 'spam'
def test_spam(spam):
assert spam == 'spam'
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines(["*1 passed*"])
result = testdir.runpytest(testfile)
result.stdout.fnmatch_lines(["*1 passed*"])
def test_override_parametrized_fixture_conftest_conftest(self, testdir):
"""Test override of the parametrized fixture with non-parametrized one on the conftest level."""
testdir.makeconftest("""
import pytest
@pytest.fixture(params=[1, 2, 3])
def spam(request):
return request.param
""")
subdir = testdir.mkpydir('subdir')
subdir.join("conftest.py").write(py.code.Source("""
import pytest
@pytest.fixture
def spam():
return 'spam'
"""))
testfile = subdir.join("test_spam.py")
testfile.write(py.code.Source("""
def test_spam(spam):
assert spam == "spam"
"""))
result = testdir.runpytest()
result.stdout.fnmatch_lines(["*1 passed*"])
result = testdir.runpytest(testfile)
result.stdout.fnmatch_lines(["*1 passed*"])
def test_override_non_parametrized_fixture_conftest_module(self, testdir):
"""Test override of the non-parametrized fixture with parametrized one on the test module level."""
testdir.makeconftest("""
import pytest
@pytest.fixture
def spam():
return 'spam'
""")
testfile = testdir.makepyfile("""
import pytest
@pytest.fixture(params=[1, 2, 3])
def spam(request):
return request.param
params = {'spam': 1}
def test_spam(spam):
assert spam == params['spam']
params['spam'] += 1
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines(["*3 passed*"])
result = testdir.runpytest(testfile)
result.stdout.fnmatch_lines(["*3 passed*"])
def test_override_non_parametrized_fixture_conftest_conftest(self, testdir):
"""Test override of the non-parametrized fixture with parametrized one on the conftest level."""
testdir.makeconftest("""
import pytest
@pytest.fixture
def spam():
return 'spam'
""")
subdir = testdir.mkpydir('subdir')
subdir.join("conftest.py").write(py.code.Source("""
import pytest
@pytest.fixture(params=[1, 2, 3])
def spam(request):
return request.param
"""))
testfile = subdir.join("test_spam.py")
testfile.write(py.code.Source("""
params = {'spam': 1}
def test_spam(spam):
assert spam == params['spam']
params['spam'] += 1
"""))
result = testdir.runpytest()
result.stdout.fnmatch_lines(["*3 passed*"])
result = testdir.runpytest(testfile)
result.stdout.fnmatch_lines(["*3 passed*"])
def test_autouse_fixture_plugin(self, testdir): def test_autouse_fixture_plugin(self, testdir):
# A fixture from a plugin has no baseid set, which screwed up # A fixture from a plugin has no baseid set, which screwed up
# the autouse fixture handling. # the autouse fixture handling.

View File

@ -136,7 +136,7 @@ commands=
minversion=2.0 minversion=2.0
plugins=pytester plugins=pytester
#--pyargs --doctest-modules --ignore=.tox #--pyargs --doctest-modules --ignore=.tox
addopts= -rxsX addopts= -rxsX -vl
rsyncdirs=tox.ini pytest.py _pytest testing rsyncdirs=tox.ini pytest.py _pytest testing
python_files=test_*.py *_test.py testing/*/*.py python_files=test_*.py *_test.py testing/*/*.py
python_classes=Test Acceptance python_classes=Test Acceptance