1 new commit in pytest: https://bitbucket.org/pytest-dev/pytest/commits/03d41bd86f9f/ Changeset: 03d41bd86f9f Branch: parametrized-fixture-override User: bubenkoff Date: 2015-03-01 17:54:24+00:00 Summary: document fixture override techniques Affected #: 1 file
diff -r 36e8f6d683da6908f9c5fe76c02c013302903808 -r 03d41bd86f9fc0de41b349866d3f947c52ae6bd5 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -78,20 +78,20 @@ =========================== test session starts ============================ platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 collected 1 items - + test_smtpsimple.py F - + ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - + smtp = <smtplib.SMTP object at 0x2b88f2d1b0b8> - + def test_ehlo(smtp): response, msg = smtp.ehlo() assert response == 250 > assert "merlinux" in msg E TypeError: Type str doesn't support the buffer API - + test_smtpsimple.py:11: TypeError ========================= 1 failed in 0.28 seconds ========================= @@ -195,31 +195,31 @@ =========================== test session starts ============================ platform linux -- Python 3.4.0 -- py-1.4.26 -- pytest-2.6.4 collected 2 items - + test_module.py FF - + ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - + smtp = <smtplib.SMTP object at 0x2b29b71bd8d0> - + def test_ehlo(smtp): response = smtp.ehlo() assert response[0] == 250 > assert "merlinux" in response[1] E TypeError: Type str doesn't support the buffer API - + test_module.py:5: TypeError ________________________________ test_noop _________________________________ - + smtp = <smtplib.SMTP object at 0x2b29b71bd8d0> - + def test_noop(smtp): response = smtp.noop() assert response[0] == 250 > assert 0 # for demo purposes E assert 0 - + test_module.py:11: AssertionError ========================= 2 failed in 0.28 seconds ========================= @@ -268,7 +268,7 @@ $ py.test -s -q --tb=no FFteardown smtp - + 2 failed in 0.21 seconds We see that the ``smtp`` instance is finalized after the two @@ -377,50 +377,50 @@ FFFF ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - + smtp = <smtplib.SMTP object at 0x2b6b796568d0> - + def test_ehlo(smtp): response = smtp.ehlo() assert response[0] == 250 > assert "merlinux" in response[1] E TypeError: Type str doesn't support the buffer API - + test_module.py:5: TypeError __________________________ test_noop[merlinux.eu] __________________________ - + smtp = <smtplib.SMTP object at 0x2b6b796568d0> - + def test_noop(smtp): response = smtp.noop() assert response[0] == 250 > assert 0 # for demo purposes E assert 0 - + test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - + smtp = <smtplib.SMTP object at 0x2b6b79656780> - + def test_ehlo(smtp): response = smtp.ehlo() assert response[0] == 250 > assert "merlinux" in response[1] E TypeError: Type str doesn't support the buffer API - + test_module.py:5: TypeError -------------------------- Captured stdout setup --------------------------- finalizing <smtplib.SMTP object at 0x2b6b796568d0> ________________________ test_noop[mail.python.org] ________________________ - + smtp = <smtplib.SMTP object at 0x2b6b79656780> - + def test_noop(smtp): response = smtp.noop() assert response[0] == 250 > assert 0 # for demo purposes E assert 0 - + test_module.py:11: AssertionError 4 failed in 7.02 seconds @@ -519,10 +519,10 @@ =========================== 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 collecting ... collected 2 items - + test_appsetup.py::test_smtp_exists[merlinux.eu] PASSED test_appsetup.py::test_smtp_exists[mail.python.org] PASSED - + ========================= 2 passed in 6.63 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two @@ -583,7 +583,7 @@ =========================== 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 collecting ... collected 8 items - + test_module.py::test_0[1] test0 1 PASSED test_module.py::test_0[2] test0 2 @@ -602,7 +602,7 @@ PASSED test_module.py::test_2[2-mod2] test2 2 mod2 PASSED - + ========================= 8 passed in 0.01 seconds ========================= You can see that the parametrized module-scoped ``modarg`` resource caused @@ -780,4 +780,182 @@ fixtures functions starts at test classes, then test modules, then ``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. Repository URL: https://bitbucket.org/pytest-dev/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. _______________________________________________ pytest-commit mailing list pytest-commit@python.org https://mail.python.org/mailman/listinfo/pytest-commit