[Pytest-commit] commit/pytest: bubenkoff: document fixture override techniques

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Sun Mar 1 18:54:34 CET 2015


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.


More information about the pytest-commit mailing list