1.. _fixture: 2.. _fixtures: 3.. _`fixture functions`: 4 5pytest fixtures: explicit, modular, scalable 6======================================================== 7 8.. currentmodule:: _pytest.python 9 10 11 12.. _`xUnit`: https://en.wikipedia.org/wiki/XUnit 13.. _`Software test fixtures`: https://en.wikipedia.org/wiki/Test_fixture#Software 14.. _`Dependency injection`: https://en.wikipedia.org/wiki/Dependency_injection 15 16`Software test fixtures`_ initialize test functions. They provide a 17fixed baseline so that tests execute reliably and produce consistent, 18repeatable, results. Initialization may setup services, state, or 19other operating environments. These are accessed by test functions 20through arguments; for each fixture used by a test function there is 21typically a parameter (named after the fixture) in the test function's 22definition. 23 24pytest fixtures offer dramatic improvements over the classic xUnit 25style of setup/teardown functions: 26 27* fixtures have explicit names and are activated by declaring their use 28 from test functions, modules, classes or whole projects. 29 30* fixtures are implemented in a modular manner, as each fixture name 31 triggers a *fixture function* which can itself use other fixtures. 32 33* fixture management scales from simple unit to complex 34 functional testing, allowing to parametrize fixtures and tests according 35 to configuration and component options, or to re-use fixtures 36 across function, class, module or whole test session scopes. 37 38In addition, pytest continues to support :ref:`xunitsetup`. You can mix 39both styles, moving incrementally from classic to new style, as you 40prefer. You can also start out from existing :ref:`unittest.TestCase 41style <unittest.TestCase>` or :ref:`nose based <nosestyle>` projects. 42 43:ref:`Fixtures <fixtures-api>` are defined using the 44:ref:`@pytest.fixture <pytest.fixture-api>` decorator, :ref:`described 45below <funcargs>`. Pytest has useful built-in fixtures, listed here 46for reference: 47 48 :fixture:`capfd` 49 Capture, as text, output to file descriptors ``1`` and ``2``. 50 51 :fixture:`capfdbinary` 52 Capture, as bytes, output to file descriptors ``1`` and ``2``. 53 54 :fixture:`caplog` 55 Control logging and access log entries. 56 57 :fixture:`capsys` 58 Capture, as text, output to ``sys.stdout`` and ``sys.stderr``. 59 60 :fixture:`capsysbinary` 61 Capture, as bytes, output to ``sys.stdout`` and ``sys.stderr``. 62 63 :fixture:`cache` 64 Store and retrieve values across pytest runs. 65 66 :fixture:`doctest_namespace` 67 Provide a dict injected into the docstests namespace. 68 69 :fixture:`monkeypatch` 70 Temporarily modify classes, functions, dictionaries, 71 ``os.environ``, and other objects. 72 73 :fixture:`pytestconfig` 74 Access to configuration values, pluginmanager and plugin hooks. 75 76 :fixture:`record_property` 77 Add extra properties to the test. 78 79 :fixture:`record_testsuite_property` 80 Add extra properties to the test suite. 81 82 :fixture:`recwarn` 83 Record warnings emitted by test functions. 84 85 :fixture:`request` 86 Provide information on the executing test function. 87 88 :fixture:`testdir` 89 Provide a temporary test directory to aid in running, and 90 testing, pytest plugins. 91 92 :fixture:`tmp_path` 93 Provide a :class:`pathlib.Path` object to a temporary directory 94 which is unique to each test function. 95 96 :fixture:`tmp_path_factory` 97 Make session-scoped temporary directories and return 98 :class:`pathlib.Path` objects. 99 100 :fixture:`tmpdir` 101 Provide a :class:`py.path.local` object to a temporary 102 directory which is unique to each test function; 103 replaced by :fixture:`tmp_path`. 104 105 .. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html 106 107 :fixture:`tmpdir_factory` 108 Make session-scoped temporary directories and return 109 :class:`py.path.local` objects; 110 replaced by :fixture:`tmp_path_factory`. 111 112.. _`funcargs`: 113.. _`funcarg mechanism`: 114.. _`fixture function`: 115.. _`@pytest.fixture`: 116.. _`pytest.fixture`: 117 118Fixtures as Function arguments 119----------------------------------------- 120 121Test functions can receive fixture objects by naming them as an input 122argument. For each argument name, a fixture function with that name provides 123the fixture object. Fixture functions are registered by marking them with 124:py:func:`@pytest.fixture <pytest.fixture>`. Let's look at a simple 125self-contained test module containing a fixture and a test function 126using it: 127 128.. code-block:: python 129 130 # content of ./test_smtpsimple.py 131 import pytest 132 133 134 @pytest.fixture 135 def smtp_connection(): 136 import smtplib 137 138 return smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 139 140 141 def test_ehlo(smtp_connection): 142 response, msg = smtp_connection.ehlo() 143 assert response == 250 144 assert 0 # for demo purposes 145 146Here, the ``test_ehlo`` needs the ``smtp_connection`` fixture value. pytest 147will discover and call the :py:func:`@pytest.fixture <pytest.fixture>` 148marked ``smtp_connection`` fixture function. Running the test looks like this: 149 150.. code-block:: pytest 151 152 $ pytest test_smtpsimple.py 153 =========================== test session starts ============================ 154 platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y 155 cachedir: $PYTHON_PREFIX/.pytest_cache 156 rootdir: $REGENDOC_TMPDIR 157 collected 1 item 158 159 test_smtpsimple.py F [100%] 160 161 ================================= FAILURES ================================= 162 ________________________________ test_ehlo _________________________________ 163 164 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 165 166 def test_ehlo(smtp_connection): 167 response, msg = smtp_connection.ehlo() 168 assert response == 250 169 > assert 0 # for demo purposes 170 E assert 0 171 172 test_smtpsimple.py:14: AssertionError 173 ========================= short test summary info ========================== 174 FAILED test_smtpsimple.py::test_ehlo - assert 0 175 ============================ 1 failed in 0.12s ============================= 176 177In the failure traceback we see that the test function was called with a 178``smtp_connection`` argument, the ``smtplib.SMTP()`` instance created by the fixture 179function. The test function fails on our deliberate ``assert 0``. Here is 180the exact protocol used by ``pytest`` to call the test function this way: 181 1821. pytest :ref:`finds <test discovery>` the test ``test_ehlo`` because 183 of the ``test_`` prefix. The test function needs a function argument 184 named ``smtp_connection``. A matching fixture function is discovered by 185 looking for a fixture-marked function named ``smtp_connection``. 186 1872. ``smtp_connection()`` is called to create an instance. 188 1893. ``test_ehlo(<smtp_connection instance>)`` is called and fails in the last 190 line of the test function. 191 192Note that if you misspell a function argument or want 193to use one that isn't available, you'll see an error 194with a list of available function arguments. 195 196.. note:: 197 198 You can always issue: 199 200 .. code-block:: bash 201 202 pytest --fixtures test_simplefactory.py 203 204 to see available fixtures (fixtures with leading ``_`` are only shown if you add the ``-v`` option). 205 206Fixtures: a prime example of dependency injection 207--------------------------------------------------- 208 209Fixtures allow test functions to easily receive and work 210against specific pre-initialized application objects without having 211to care about import/setup/cleanup details. 212It's a prime example of `dependency injection`_ where fixture 213functions take the role of the *injector* and test functions are the 214*consumers* of fixture objects. 215 216.. _`conftest.py`: 217.. _`conftest`: 218 219``conftest.py``: sharing fixture functions 220------------------------------------------ 221 222If during implementing your tests you realize that you 223want to use a fixture function from multiple test files you can move it 224to a ``conftest.py`` file. 225You don't need to import the fixture you want to use in a test, it 226automatically gets discovered by pytest. The discovery of 227fixture functions starts at test classes, then test modules, then 228``conftest.py`` files and finally builtin and third party plugins. 229 230You can also use the ``conftest.py`` file to implement 231:ref:`local per-directory plugins <conftest.py plugins>`. 232 233Sharing test data 234----------------- 235 236If you want to make test data from files available to your tests, a good way 237to do this is by loading these data in a fixture for use by your tests. 238This makes use of the automatic caching mechanisms of pytest. 239 240Another good approach is by adding the data files in the ``tests`` folder. 241There are also community plugins available to help managing this aspect of 242testing, e.g. `pytest-datadir <https://pypi.org/project/pytest-datadir/>`__ 243and `pytest-datafiles <https://pypi.org/project/pytest-datafiles/>`__. 244 245.. _smtpshared: 246 247Scope: sharing fixtures across classes, modules, packages or session 248-------------------------------------------------------------------- 249 250.. regendoc:wipe 251 252Fixtures requiring network access depend on connectivity and are 253usually time-expensive to create. Extending the previous example, we 254can add a ``scope="module"`` parameter to the 255:py:func:`@pytest.fixture <pytest.fixture>` invocation 256to cause the decorated ``smtp_connection`` fixture function to only be invoked 257once per test *module* (the default is to invoke once per test *function*). 258Multiple test functions in a test module will thus 259each receive the same ``smtp_connection`` fixture instance, thus saving time. 260Possible values for ``scope`` are: ``function``, ``class``, ``module``, ``package`` or ``session``. 261 262The next example puts the fixture function into a separate ``conftest.py`` file 263so that tests from multiple test modules in the directory can 264access the fixture function: 265 266.. code-block:: python 267 268 # content of conftest.py 269 import pytest 270 import smtplib 271 272 273 @pytest.fixture(scope="module") 274 def smtp_connection(): 275 return smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 276 277The name of the fixture again is ``smtp_connection`` and you can access its 278result by listing the name ``smtp_connection`` as an input parameter in any 279test or fixture function (in or below the directory where ``conftest.py`` is 280located): 281 282.. code-block:: python 283 284 # content of test_module.py 285 286 287 def test_ehlo(smtp_connection): 288 response, msg = smtp_connection.ehlo() 289 assert response == 250 290 assert b"smtp.gmail.com" in msg 291 assert 0 # for demo purposes 292 293 294 def test_noop(smtp_connection): 295 response, msg = smtp_connection.noop() 296 assert response == 250 297 assert 0 # for demo purposes 298 299We deliberately insert failing ``assert 0`` statements in order to 300inspect what is going on and can now run the tests: 301 302.. code-block:: pytest 303 304 $ pytest test_module.py 305 =========================== test session starts ============================ 306 platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y 307 cachedir: $PYTHON_PREFIX/.pytest_cache 308 rootdir: $REGENDOC_TMPDIR 309 collected 2 items 310 311 test_module.py FF [100%] 312 313 ================================= FAILURES ================================= 314 ________________________________ test_ehlo _________________________________ 315 316 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 317 318 def test_ehlo(smtp_connection): 319 response, msg = smtp_connection.ehlo() 320 assert response == 250 321 assert b"smtp.gmail.com" in msg 322 > assert 0 # for demo purposes 323 E assert 0 324 325 test_module.py:7: AssertionError 326 ________________________________ test_noop _________________________________ 327 328 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 329 330 def test_noop(smtp_connection): 331 response, msg = smtp_connection.noop() 332 assert response == 250 333 > assert 0 # for demo purposes 334 E assert 0 335 336 test_module.py:13: AssertionError 337 ========================= short test summary info ========================== 338 FAILED test_module.py::test_ehlo - assert 0 339 FAILED test_module.py::test_noop - assert 0 340 ============================ 2 failed in 0.12s ============================= 341 342You see the two ``assert 0`` failing and more importantly you can also see 343that the same (module-scoped) ``smtp_connection`` object was passed into the 344two test functions because pytest shows the incoming argument values in the 345traceback. As a result, the two test functions using ``smtp_connection`` run 346as quick as a single one because they reuse the same instance. 347 348If you decide that you rather want to have a session-scoped ``smtp_connection`` 349instance, you can simply declare it: 350 351.. code-block:: python 352 353 @pytest.fixture(scope="session") 354 def smtp_connection(): 355 # the returned fixture value will be shared for 356 # all tests needing it 357 ... 358 359 360Fixture scopes 361^^^^^^^^^^^^^^ 362 363Fixtures are created when first requested by a test, and are destroyed based on their ``scope``: 364 365* ``function``: the default scope, the fixture is destroyed at the end of the test. 366* ``class``: the fixture is destroyed during teardown of the last test in the class. 367* ``module``: the fixture is destroyed during teardown of the last test in the module. 368* ``package``: the fixture is destroyed during teardown of the last test in the package. 369* ``session``: the fixture is destroyed at the end of the test session. 370 371.. note:: 372 373 Pytest only caches one instance of a fixture at a time, which 374 means that when using a parametrized fixture, pytest may invoke a fixture more than once in 375 the given scope. 376 377.. _dynamic scope: 378 379Dynamic scope 380^^^^^^^^^^^^^ 381 382.. versionadded:: 5.2 383 384In some cases, you might want to change the scope of the fixture without changing the code. 385To do that, pass a callable to ``scope``. The callable must return a string with a valid scope 386and will be executed only once - during the fixture definition. It will be called with two 387keyword arguments - ``fixture_name`` as a string and ``config`` with a configuration object. 388 389This can be especially useful when dealing with fixtures that need time for setup, like spawning 390a docker container. You can use the command-line argument to control the scope of the spawned 391containers for different environments. See the example below. 392 393.. code-block:: python 394 395 def determine_scope(fixture_name, config): 396 if config.getoption("--keep-containers", None): 397 return "session" 398 return "function" 399 400 401 @pytest.fixture(scope=determine_scope) 402 def docker_container(): 403 yield spawn_container() 404 405 406 407Order: Higher-scoped fixtures are instantiated first 408---------------------------------------------------- 409 410 411 412Within a function request for fixtures, those of higher-scopes (such as ``session``) are instantiated before 413lower-scoped fixtures (such as ``function`` or ``class``). The relative order of fixtures of same scope follows 414the declared order in the test function and honours dependencies between fixtures. Autouse fixtures will be 415instantiated before explicitly used fixtures. 416 417Consider the code below: 418 419.. literalinclude:: example/fixtures/test_fixtures_order.py 420 421The fixtures requested by ``test_order`` will be instantiated in the following order: 422 4231. ``s1``: is the highest-scoped fixture (``session``). 4242. ``m1``: is the second highest-scoped fixture (``module``). 4253. ``a1``: is a ``function``-scoped ``autouse`` fixture: it will be instantiated before other fixtures 426 within the same scope. 4274. ``f3``: is a ``function``-scoped fixture, required by ``f1``: it needs to be instantiated at this point 4285. ``f1``: is the first ``function``-scoped fixture in ``test_order`` parameter list. 4296. ``f2``: is the last ``function``-scoped fixture in ``test_order`` parameter list. 430 431 432.. _`finalization`: 433 434Fixture finalization / executing teardown code 435------------------------------------------------------------- 436 437pytest supports execution of fixture specific finalization code 438when the fixture goes out of scope. By using a ``yield`` statement instead of ``return``, all 439the code after the *yield* statement serves as the teardown code: 440 441.. code-block:: python 442 443 # content of conftest.py 444 445 import smtplib 446 import pytest 447 448 449 @pytest.fixture(scope="module") 450 def smtp_connection(): 451 smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 452 yield smtp_connection # provide the fixture value 453 print("teardown smtp") 454 smtp_connection.close() 455 456The ``print`` and ``smtp.close()`` statements will execute when the last test in 457the module has finished execution, regardless of the exception status of the 458tests. 459 460Let's execute it: 461 462.. code-block:: pytest 463 464 $ pytest -s -q --tb=no 465 FFteardown smtp 466 467 ========================= short test summary info ========================== 468 FAILED test_module.py::test_ehlo - assert 0 469 FAILED test_module.py::test_noop - assert 0 470 2 failed in 0.12s 471 472We see that the ``smtp_connection`` instance is finalized after the two 473tests finished execution. Note that if we decorated our fixture 474function with ``scope='function'`` then fixture setup and cleanup would 475occur around each single test. In either case the test 476module itself does not need to change or know about these details 477of fixture setup. 478 479Note that we can also seamlessly use the ``yield`` syntax with ``with`` statements: 480 481.. code-block:: python 482 483 # content of test_yield2.py 484 485 import smtplib 486 import pytest 487 488 489 @pytest.fixture(scope="module") 490 def smtp_connection(): 491 with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection: 492 yield smtp_connection # provide the fixture value 493 494 495The ``smtp_connection`` connection will be closed after the test finished 496execution because the ``smtp_connection`` object automatically closes when 497the ``with`` statement ends. 498 499Using the contextlib.ExitStack context manager finalizers will always be called 500regardless if the fixture *setup* code raises an exception. This is handy to properly 501close all resources created by a fixture even if one of them fails to be created/acquired: 502 503.. code-block:: python 504 505 # content of test_yield3.py 506 507 import contextlib 508 509 import pytest 510 511 512 @contextlib.contextmanager 513 def connect(port): 514 ... # create connection 515 yield 516 ... # close connection 517 518 519 @pytest.fixture 520 def equipments(): 521 with contextlib.ExitStack() as stack: 522 yield [stack.enter_context(connect(port)) for port in ("C1", "C3", "C28")] 523 524In the example above, if ``"C28"`` fails with an exception, ``"C1"`` and ``"C3"`` will still 525be properly closed. 526 527Note that if an exception happens during the *setup* code (before the ``yield`` keyword), the 528*teardown* code (after the ``yield``) will not be called. 529 530An alternative option for executing *teardown* code is to 531make use of the ``addfinalizer`` method of the `request-context`_ object to register 532finalization functions. 533 534Here's the ``smtp_connection`` fixture changed to use ``addfinalizer`` for cleanup: 535 536.. code-block:: python 537 538 # content of conftest.py 539 import smtplib 540 import pytest 541 542 543 @pytest.fixture(scope="module") 544 def smtp_connection(request): 545 smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 546 547 def fin(): 548 print("teardown smtp_connection") 549 smtp_connection.close() 550 551 request.addfinalizer(fin) 552 return smtp_connection # provide the fixture value 553 554 555Here's the ``equipments`` fixture changed to use ``addfinalizer`` for cleanup: 556 557.. code-block:: python 558 559 # content of test_yield3.py 560 561 import contextlib 562 import functools 563 564 import pytest 565 566 567 @contextlib.contextmanager 568 def connect(port): 569 ... # create connection 570 yield 571 ... # close connection 572 573 574 @pytest.fixture 575 def equipments(request): 576 r = [] 577 for port in ("C1", "C3", "C28"): 578 cm = connect(port) 579 equip = cm.__enter__() 580 request.addfinalizer(functools.partial(cm.__exit__, None, None, None)) 581 r.append(equip) 582 return r 583 584 585Both ``yield`` and ``addfinalizer`` methods work similarly by calling their code after the test 586ends. Of course, if an exception happens before the finalize function is registered then it 587will not be executed. 588 589 590.. _`request-context`: 591 592Fixtures can introspect the requesting test context 593------------------------------------------------------------- 594 595Fixture functions can accept the :py:class:`request <_pytest.fixtures.FixtureRequest>` object 596to introspect the "requesting" test function, class or module context. 597Further extending the previous ``smtp_connection`` fixture example, let's 598read an optional server URL from the test module which uses our fixture: 599 600.. code-block:: python 601 602 # content of conftest.py 603 import pytest 604 import smtplib 605 606 607 @pytest.fixture(scope="module") 608 def smtp_connection(request): 609 server = getattr(request.module, "smtpserver", "smtp.gmail.com") 610 smtp_connection = smtplib.SMTP(server, 587, timeout=5) 611 yield smtp_connection 612 print("finalizing {} ({})".format(smtp_connection, server)) 613 smtp_connection.close() 614 615We use the ``request.module`` attribute to optionally obtain an 616``smtpserver`` attribute from the test module. If we just execute 617again, nothing much has changed: 618 619.. code-block:: pytest 620 621 $ pytest -s -q --tb=no 622 FFfinalizing <smtplib.SMTP object at 0xdeadbeef> (smtp.gmail.com) 623 624 ========================= short test summary info ========================== 625 FAILED test_module.py::test_ehlo - assert 0 626 FAILED test_module.py::test_noop - assert 0 627 2 failed in 0.12s 628 629Let's quickly create another test module that actually sets the 630server URL in its module namespace: 631 632.. code-block:: python 633 634 # content of test_anothersmtp.py 635 636 smtpserver = "mail.python.org" # will be read by smtp fixture 637 638 639 def test_showhelo(smtp_connection): 640 assert 0, smtp_connection.helo() 641 642Running it: 643 644.. code-block:: pytest 645 646 $ pytest -qq --tb=short test_anothersmtp.py 647 F [100%] 648 ================================= FAILURES ================================= 649 ______________________________ test_showhelo _______________________________ 650 test_anothersmtp.py:6: in test_showhelo 651 assert 0, smtp_connection.helo() 652 E AssertionError: (250, b'mail.python.org') 653 E assert 0 654 ------------------------- Captured stdout teardown ------------------------- 655 finalizing <smtplib.SMTP object at 0xdeadbeef> (mail.python.org) 656 ========================= short test summary info ========================== 657 FAILED test_anothersmtp.py::test_showhelo - AssertionError: (250, b'mail.... 658 659voila! The ``smtp_connection`` fixture function picked up our mail server name 660from the module namespace. 661 662.. _`using-markers`: 663 664Using markers to pass data to fixtures 665------------------------------------------------------------- 666 667Using the :py:class:`request <_pytest.fixtures.FixtureRequest>` object, a fixture can also access 668markers which are applied to a test function. This can be useful to pass data 669into a fixture from a test: 670 671.. code-block:: python 672 673 import pytest 674 675 676 @pytest.fixture 677 def fixt(request): 678 marker = request.node.get_closest_marker("fixt_data") 679 if marker is None: 680 # Handle missing marker in some way... 681 data = None 682 else: 683 data = marker.args[0] 684 685 # Do something with the data 686 return data 687 688 689 @pytest.mark.fixt_data(42) 690 def test_fixt(fixt): 691 assert fixt == 42 692 693.. _`fixture-factory`: 694 695Factories as fixtures 696------------------------------------------------------------- 697 698The "factory as fixture" pattern can help in situations where the result 699of a fixture is needed multiple times in a single test. Instead of returning 700data directly, the fixture instead returns a function which generates the data. 701This function can then be called multiple times in the test. 702 703Factories can have parameters as needed: 704 705.. code-block:: python 706 707 @pytest.fixture 708 def make_customer_record(): 709 def _make_customer_record(name): 710 return {"name": name, "orders": []} 711 712 return _make_customer_record 713 714 715 def test_customer_records(make_customer_record): 716 customer_1 = make_customer_record("Lisa") 717 customer_2 = make_customer_record("Mike") 718 customer_3 = make_customer_record("Meredith") 719 720If the data created by the factory requires managing, the fixture can take care of that: 721 722.. code-block:: python 723 724 @pytest.fixture 725 def make_customer_record(): 726 727 created_records = [] 728 729 def _make_customer_record(name): 730 record = models.Customer(name=name, orders=[]) 731 created_records.append(record) 732 return record 733 734 yield _make_customer_record 735 736 for record in created_records: 737 record.destroy() 738 739 740 def test_customer_records(make_customer_record): 741 customer_1 = make_customer_record("Lisa") 742 customer_2 = make_customer_record("Mike") 743 customer_3 = make_customer_record("Meredith") 744 745 746.. _`fixture-parametrize`: 747 748Parametrizing fixtures 749----------------------------------------------------------------- 750 751Fixture functions can be parametrized in which case they will be called 752multiple times, each time executing the set of dependent tests, i. e. the 753tests that depend on this fixture. Test functions usually do not need 754to be aware of their re-running. Fixture parametrization helps to 755write exhaustive functional tests for components which themselves can be 756configured in multiple ways. 757 758Extending the previous example, we can flag the fixture to create two 759``smtp_connection`` fixture instances which will cause all tests using the fixture 760to run twice. The fixture function gets access to each parameter 761through the special :py:class:`request <FixtureRequest>` object: 762 763.. code-block:: python 764 765 # content of conftest.py 766 import pytest 767 import smtplib 768 769 770 @pytest.fixture(scope="module", params=["smtp.gmail.com", "mail.python.org"]) 771 def smtp_connection(request): 772 smtp_connection = smtplib.SMTP(request.param, 587, timeout=5) 773 yield smtp_connection 774 print("finalizing {}".format(smtp_connection)) 775 smtp_connection.close() 776 777The main change is the declaration of ``params`` with 778:py:func:`@pytest.fixture <pytest.fixture>`, a list of values 779for each of which the fixture function will execute and can access 780a value via ``request.param``. No test function code needs to change. 781So let's just do another run: 782 783.. code-block:: pytest 784 785 $ pytest -q test_module.py 786 FFFF [100%] 787 ================================= FAILURES ================================= 788 ________________________ test_ehlo[smtp.gmail.com] _________________________ 789 790 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 791 792 def test_ehlo(smtp_connection): 793 response, msg = smtp_connection.ehlo() 794 assert response == 250 795 assert b"smtp.gmail.com" in msg 796 > assert 0 # for demo purposes 797 E assert 0 798 799 test_module.py:7: AssertionError 800 ________________________ test_noop[smtp.gmail.com] _________________________ 801 802 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 803 804 def test_noop(smtp_connection): 805 response, msg = smtp_connection.noop() 806 assert response == 250 807 > assert 0 # for demo purposes 808 E assert 0 809 810 test_module.py:13: AssertionError 811 ________________________ test_ehlo[mail.python.org] ________________________ 812 813 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 814 815 def test_ehlo(smtp_connection): 816 response, msg = smtp_connection.ehlo() 817 assert response == 250 818 > assert b"smtp.gmail.com" in msg 819 E AssertionError: assert b'smtp.gmail.com' in b'mail.python.org\nPIPELINING\nSIZE 51200000\nETRN\nSTARTTLS\nAUTH DIGEST-MD5 NTLM CRAM-MD5\nENHANCEDSTATUSCODES\n8BITMIME\nDSN\nSMTPUTF8\nCHUNKING' 820 821 test_module.py:6: AssertionError 822 -------------------------- Captured stdout setup --------------------------- 823 finalizing <smtplib.SMTP object at 0xdeadbeef> 824 ________________________ test_noop[mail.python.org] ________________________ 825 826 smtp_connection = <smtplib.SMTP object at 0xdeadbeef> 827 828 def test_noop(smtp_connection): 829 response, msg = smtp_connection.noop() 830 assert response == 250 831 > assert 0 # for demo purposes 832 E assert 0 833 834 test_module.py:13: AssertionError 835 ------------------------- Captured stdout teardown ------------------------- 836 finalizing <smtplib.SMTP object at 0xdeadbeef> 837 ========================= short test summary info ========================== 838 FAILED test_module.py::test_ehlo[smtp.gmail.com] - assert 0 839 FAILED test_module.py::test_noop[smtp.gmail.com] - assert 0 840 FAILED test_module.py::test_ehlo[mail.python.org] - AssertionError: asser... 841 FAILED test_module.py::test_noop[mail.python.org] - assert 0 842 4 failed in 0.12s 843 844We see that our two test functions each ran twice, against the different 845``smtp_connection`` instances. Note also, that with the ``mail.python.org`` 846connection the second test fails in ``test_ehlo`` because a 847different server string is expected than what arrived. 848 849pytest will build a string that is the test ID for each fixture value 850in a parametrized fixture, e.g. ``test_ehlo[smtp.gmail.com]`` and 851``test_ehlo[mail.python.org]`` in the above examples. These IDs can 852be used with ``-k`` to select specific cases to run, and they will 853also identify the specific case when one is failing. Running pytest 854with ``--collect-only`` will show the generated IDs. 855 856Numbers, strings, booleans and ``None`` will have their usual string 857representation used in the test ID. For other objects, pytest will 858make a string based on the argument name. It is possible to customise 859the string used in a test ID for a certain fixture value by using the 860``ids`` keyword argument: 861 862.. code-block:: python 863 864 # content of test_ids.py 865 import pytest 866 867 868 @pytest.fixture(params=[0, 1], ids=["spam", "ham"]) 869 def a(request): 870 return request.param 871 872 873 def test_a(a): 874 pass 875 876 877 def idfn(fixture_value): 878 if fixture_value == 0: 879 return "eggs" 880 else: 881 return None 882 883 884 @pytest.fixture(params=[0, 1], ids=idfn) 885 def b(request): 886 return request.param 887 888 889 def test_b(b): 890 pass 891 892The above shows how ``ids`` can be either a list of strings to use or 893a function which will be called with the fixture value and then 894has to return a string to use. In the latter case if the function 895returns ``None`` then pytest's auto-generated ID will be used. 896 897Running the above tests results in the following test IDs being used: 898 899.. code-block:: pytest 900 901 $ pytest --collect-only 902 =========================== test session starts ============================ 903 platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y 904 cachedir: $PYTHON_PREFIX/.pytest_cache 905 rootdir: $REGENDOC_TMPDIR 906 collected 10 items 907 908 <Module test_anothersmtp.py> 909 <Function test_showhelo[smtp.gmail.com]> 910 <Function test_showhelo[mail.python.org]> 911 <Module test_ids.py> 912 <Function test_a[spam]> 913 <Function test_a[ham]> 914 <Function test_b[eggs]> 915 <Function test_b[1]> 916 <Module test_module.py> 917 <Function test_ehlo[smtp.gmail.com]> 918 <Function test_noop[smtp.gmail.com]> 919 <Function test_ehlo[mail.python.org]> 920 <Function test_noop[mail.python.org]> 921 922 ========================== no tests ran in 0.12s =========================== 923 924.. _`fixture-parametrize-marks`: 925 926Using marks with parametrized fixtures 927-------------------------------------- 928 929:func:`pytest.param` can be used to apply marks in values sets of parametrized fixtures in the same way 930that they can be used with :ref:`@pytest.mark.parametrize <@pytest.mark.parametrize>`. 931 932Example: 933 934.. code-block:: python 935 936 # content of test_fixture_marks.py 937 import pytest 938 939 940 @pytest.fixture(params=[0, 1, pytest.param(2, marks=pytest.mark.skip)]) 941 def data_set(request): 942 return request.param 943 944 945 def test_data(data_set): 946 pass 947 948Running this test will *skip* the invocation of ``data_set`` with value ``2``: 949 950.. code-block:: pytest 951 952 $ pytest test_fixture_marks.py -v 953 =========================== test session starts ============================ 954 platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python 955 cachedir: $PYTHON_PREFIX/.pytest_cache 956 rootdir: $REGENDOC_TMPDIR 957 collecting ... collected 3 items 958 959 test_fixture_marks.py::test_data[0] PASSED [ 33%] 960 test_fixture_marks.py::test_data[1] PASSED [ 66%] 961 test_fixture_marks.py::test_data[2] SKIPPED [100%] 962 963 ======================= 2 passed, 1 skipped in 0.12s ======================= 964 965.. _`interdependent fixtures`: 966 967Modularity: using fixtures from a fixture function 968---------------------------------------------------------- 969 970In addition to using fixtures in test functions, fixture functions 971can use other fixtures themselves. This contributes to a modular design 972of your fixtures and allows re-use of framework-specific fixtures across 973many projects. As a simple example, we can extend the previous example 974and instantiate an object ``app`` where we stick the already defined 975``smtp_connection`` resource into it: 976 977.. code-block:: python 978 979 # content of test_appsetup.py 980 981 import pytest 982 983 984 class App: 985 def __init__(self, smtp_connection): 986 self.smtp_connection = smtp_connection 987 988 989 @pytest.fixture(scope="module") 990 def app(smtp_connection): 991 return App(smtp_connection) 992 993 994 def test_smtp_connection_exists(app): 995 assert app.smtp_connection 996 997Here we declare an ``app`` fixture which receives the previously defined 998``smtp_connection`` fixture and instantiates an ``App`` object with it. Let's run it: 999 1000.. code-block:: pytest 1001 1002 $ pytest -v test_appsetup.py 1003 =========================== test session starts ============================ 1004 platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python 1005 cachedir: $PYTHON_PREFIX/.pytest_cache 1006 rootdir: $REGENDOC_TMPDIR 1007 collecting ... collected 2 items 1008 1009 test_appsetup.py::test_smtp_connection_exists[smtp.gmail.com] PASSED [ 50%] 1010 test_appsetup.py::test_smtp_connection_exists[mail.python.org] PASSED [100%] 1011 1012 ============================ 2 passed in 0.12s ============================= 1013 1014Due to the parametrization of ``smtp_connection``, the test will run twice with two 1015different ``App`` instances and respective smtp servers. There is no 1016need for the ``app`` fixture to be aware of the ``smtp_connection`` 1017parametrization because pytest will fully analyse the fixture dependency graph. 1018 1019Note that the ``app`` fixture has a scope of ``module`` and uses a 1020module-scoped ``smtp_connection`` fixture. The example would still work if 1021``smtp_connection`` was cached on a ``session`` scope: it is fine for fixtures to use 1022"broader" scoped fixtures but not the other way round: 1023A session-scoped fixture could not use a module-scoped one in a 1024meaningful way. 1025 1026 1027.. _`automatic per-resource grouping`: 1028 1029Automatic grouping of tests by fixture instances 1030---------------------------------------------------------- 1031 1032.. regendoc: wipe 1033 1034pytest minimizes the number of active fixtures during test runs. 1035If you have a parametrized fixture, then all the tests using it will 1036first execute with one instance and then finalizers are called 1037before the next fixture instance is created. Among other things, 1038this eases testing of applications which create and use global state. 1039 1040The following example uses two parametrized fixtures, one of which is 1041scoped on a per-module basis, and all the functions perform ``print`` calls 1042to show the setup/teardown flow: 1043 1044.. code-block:: python 1045 1046 # content of test_module.py 1047 import pytest 1048 1049 1050 @pytest.fixture(scope="module", params=["mod1", "mod2"]) 1051 def modarg(request): 1052 param = request.param 1053 print(" SETUP modarg", param) 1054 yield param 1055 print(" TEARDOWN modarg", param) 1056 1057 1058 @pytest.fixture(scope="function", params=[1, 2]) 1059 def otherarg(request): 1060 param = request.param 1061 print(" SETUP otherarg", param) 1062 yield param 1063 print(" TEARDOWN otherarg", param) 1064 1065 1066 def test_0(otherarg): 1067 print(" RUN test0 with otherarg", otherarg) 1068 1069 1070 def test_1(modarg): 1071 print(" RUN test1 with modarg", modarg) 1072 1073 1074 def test_2(otherarg, modarg): 1075 print(" RUN test2 with otherarg {} and modarg {}".format(otherarg, modarg)) 1076 1077 1078Let's run the tests in verbose mode and with looking at the print-output: 1079 1080.. code-block:: pytest 1081 1082 $ pytest -v -s test_module.py 1083 =========================== test session starts ============================ 1084 platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python 1085 cachedir: $PYTHON_PREFIX/.pytest_cache 1086 rootdir: $REGENDOC_TMPDIR 1087 collecting ... collected 8 items 1088 1089 test_module.py::test_0[1] SETUP otherarg 1 1090 RUN test0 with otherarg 1 1091 PASSED TEARDOWN otherarg 1 1092 1093 test_module.py::test_0[2] SETUP otherarg 2 1094 RUN test0 with otherarg 2 1095 PASSED TEARDOWN otherarg 2 1096 1097 test_module.py::test_1[mod1] SETUP modarg mod1 1098 RUN test1 with modarg mod1 1099 PASSED 1100 test_module.py::test_2[mod1-1] SETUP otherarg 1 1101 RUN test2 with otherarg 1 and modarg mod1 1102 PASSED TEARDOWN otherarg 1 1103 1104 test_module.py::test_2[mod1-2] SETUP otherarg 2 1105 RUN test2 with otherarg 2 and modarg mod1 1106 PASSED TEARDOWN otherarg 2 1107 1108 test_module.py::test_1[mod2] TEARDOWN modarg mod1 1109 SETUP modarg mod2 1110 RUN test1 with modarg mod2 1111 PASSED 1112 test_module.py::test_2[mod2-1] SETUP otherarg 1 1113 RUN test2 with otherarg 1 and modarg mod2 1114 PASSED TEARDOWN otherarg 1 1115 1116 test_module.py::test_2[mod2-2] SETUP otherarg 2 1117 RUN test2 with otherarg 2 and modarg mod2 1118 PASSED TEARDOWN otherarg 2 1119 TEARDOWN modarg mod2 1120 1121 1122 ============================ 8 passed in 0.12s ============================= 1123 1124You can see that the parametrized module-scoped ``modarg`` resource caused an 1125ordering of test execution that lead to the fewest possible "active" resources. 1126The finalizer for the ``mod1`` parametrized resource was executed before the 1127``mod2`` resource was setup. 1128 1129In particular notice that test_0 is completely independent and finishes first. 1130Then test_1 is executed with ``mod1``, then test_2 with ``mod1``, then test_1 1131with ``mod2`` and finally test_2 with ``mod2``. 1132 1133The ``otherarg`` parametrized resource (having function scope) was set up before 1134and teared down after every test that used it. 1135 1136 1137.. _`usefixtures`: 1138 1139Use fixtures in classes and modules with ``usefixtures`` 1140-------------------------------------------------------- 1141 1142.. regendoc:wipe 1143 1144Sometimes test functions do not directly need access to a fixture object. 1145For example, tests may require to operate with an empty directory as the 1146current working directory but otherwise do not care for the concrete 1147directory. Here is how you can use the standard `tempfile 1148<http://docs.python.org/library/tempfile.html>`_ and pytest fixtures to 1149achieve it. We separate the creation of the fixture into a conftest.py 1150file: 1151 1152.. code-block:: python 1153 1154 # content of conftest.py 1155 1156 import os 1157 import shutil 1158 import tempfile 1159 1160 import pytest 1161 1162 1163 @pytest.fixture 1164 def cleandir(): 1165 old_cwd = os.getcwd() 1166 newpath = tempfile.mkdtemp() 1167 os.chdir(newpath) 1168 yield 1169 os.chdir(old_cwd) 1170 shutil.rmtree(newpath) 1171 1172and declare its use in a test module via a ``usefixtures`` marker: 1173 1174.. code-block:: python 1175 1176 # content of test_setenv.py 1177 import os 1178 import pytest 1179 1180 1181 @pytest.mark.usefixtures("cleandir") 1182 class TestDirectoryInit: 1183 def test_cwd_starts_empty(self): 1184 assert os.listdir(os.getcwd()) == [] 1185 with open("myfile", "w") as f: 1186 f.write("hello") 1187 1188 def test_cwd_again_starts_empty(self): 1189 assert os.listdir(os.getcwd()) == [] 1190 1191Due to the ``usefixtures`` marker, the ``cleandir`` fixture 1192will be required for the execution of each test method, just as if 1193you specified a "cleandir" function argument to each of them. Let's run it 1194to verify our fixture is activated and the tests pass: 1195 1196.. code-block:: pytest 1197 1198 $ pytest -q 1199 .. [100%] 1200 2 passed in 0.12s 1201 1202You can specify multiple fixtures like this: 1203 1204.. code-block:: python 1205 1206 @pytest.mark.usefixtures("cleandir", "anotherfixture") 1207 def test(): 1208 ... 1209 1210and you may specify fixture usage at the test module level using :globalvar:`pytestmark`: 1211 1212.. code-block:: python 1213 1214 pytestmark = pytest.mark.usefixtures("cleandir") 1215 1216 1217It is also possible to put fixtures required by all tests in your project 1218into an ini-file: 1219 1220.. code-block:: ini 1221 1222 # content of pytest.ini 1223 [pytest] 1224 usefixtures = cleandir 1225 1226 1227.. warning:: 1228 1229 Note this mark has no effect in **fixture functions**. For example, 1230 this **will not work as expected**: 1231 1232 .. code-block:: python 1233 1234 @pytest.mark.usefixtures("my_other_fixture") 1235 @pytest.fixture 1236 def my_fixture_that_sadly_wont_use_my_other_fixture(): 1237 ... 1238 1239 Currently this will not generate any error or warning, but this is intended 1240 to be handled by `#3664 <https://github.com/pytest-dev/pytest/issues/3664>`_. 1241 1242 1243.. _`autouse`: 1244.. _`autouse fixtures`: 1245 1246Autouse fixtures (xUnit setup on steroids) 1247---------------------------------------------------------------------- 1248 1249.. regendoc:wipe 1250 1251Occasionally, you may want to have fixtures get invoked automatically 1252without declaring a function argument explicitly or a `usefixtures`_ decorator. 1253As a practical example, suppose we have a database fixture which has a 1254begin/rollback/commit architecture and we want to automatically surround 1255each test method by a transaction and a rollback. Here is a dummy 1256self-contained implementation of this idea: 1257 1258.. code-block:: python 1259 1260 # content of test_db_transact.py 1261 1262 import pytest 1263 1264 1265 class DB: 1266 def __init__(self): 1267 self.intransaction = [] 1268 1269 def begin(self, name): 1270 self.intransaction.append(name) 1271 1272 def rollback(self): 1273 self.intransaction.pop() 1274 1275 1276 @pytest.fixture(scope="module") 1277 def db(): 1278 return DB() 1279 1280 1281 class TestClass: 1282 @pytest.fixture(autouse=True) 1283 def transact(self, request, db): 1284 db.begin(request.function.__name__) 1285 yield 1286 db.rollback() 1287 1288 def test_method1(self, db): 1289 assert db.intransaction == ["test_method1"] 1290 1291 def test_method2(self, db): 1292 assert db.intransaction == ["test_method2"] 1293 1294The class-level ``transact`` fixture is marked with *autouse=true* 1295which implies that all test methods in the class will use this fixture 1296without a need to state it in the test function signature or with a 1297class-level ``usefixtures`` decorator. 1298 1299If we run it, we get two passing tests: 1300 1301.. code-block:: pytest 1302 1303 $ pytest -q 1304 .. [100%] 1305 2 passed in 0.12s 1306 1307Here is how autouse fixtures work in other scopes: 1308 1309- autouse fixtures obey the ``scope=`` keyword-argument: if an autouse fixture 1310 has ``scope='session'`` it will only be run once, no matter where it is 1311 defined. ``scope='class'`` means it will be run once per class, etc. 1312 1313- if an autouse fixture is defined in a test module, all its test 1314 functions automatically use it. 1315 1316- if an autouse fixture is defined in a conftest.py file then all tests in 1317 all test modules below its directory will invoke the fixture. 1318 1319- lastly, and **please use that with care**: if you define an autouse 1320 fixture in a plugin, it will be invoked for all tests in all projects 1321 where the plugin is installed. This can be useful if a fixture only 1322 anyway works in the presence of certain settings e. g. in the ini-file. Such 1323 a global fixture should always quickly determine if it should do 1324 any work and avoid otherwise expensive imports or computation. 1325 1326Note that the above ``transact`` fixture may very well be a fixture that 1327you want to make available in your project without having it generally 1328active. The canonical way to do that is to put the transact definition 1329into a conftest.py file **without** using ``autouse``: 1330 1331.. code-block:: python 1332 1333 # content of conftest.py 1334 @pytest.fixture 1335 def transact(request, db): 1336 db.begin() 1337 yield 1338 db.rollback() 1339 1340and then e.g. have a TestClass using it by declaring the need: 1341 1342.. code-block:: python 1343 1344 @pytest.mark.usefixtures("transact") 1345 class TestClass: 1346 def test_method1(self): 1347 ... 1348 1349All test methods in this TestClass will use the transaction fixture while 1350other test classes or functions in the module will not use it unless 1351they also add a ``transact`` reference. 1352 1353Overriding fixtures on various levels 1354------------------------------------- 1355 1356In relatively large test suite, you most likely need to ``override`` a ``global`` or ``root`` fixture with a ``locally`` 1357defined one, keeping the test code readable and maintainable. 1358 1359Override a fixture on a folder (conftest) level 1360^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1361 1362Given the tests file structure is: 1363 1364:: 1365 1366 tests/ 1367 __init__.py 1368 1369 conftest.py 1370 # content of tests/conftest.py 1371 import pytest 1372 1373 @pytest.fixture 1374 def username(): 1375 return 'username' 1376 1377 test_something.py 1378 # content of tests/test_something.py 1379 def test_username(username): 1380 assert username == 'username' 1381 1382 subfolder/ 1383 __init__.py 1384 1385 conftest.py 1386 # content of tests/subfolder/conftest.py 1387 import pytest 1388 1389 @pytest.fixture 1390 def username(username): 1391 return 'overridden-' + username 1392 1393 test_something.py 1394 # content of tests/subfolder/test_something.py 1395 def test_username(username): 1396 assert username == 'overridden-username' 1397 1398As you can see, a fixture with the same name can be overridden for certain test folder level. 1399Note that the ``base`` or ``super`` fixture can be accessed from the ``overriding`` 1400fixture easily - used in the example above. 1401 1402Override a fixture on a test module level 1403^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1404 1405Given the tests file structure is: 1406 1407:: 1408 1409 tests/ 1410 __init__.py 1411 1412 conftest.py 1413 # content of tests/conftest.py 1414 import pytest 1415 1416 @pytest.fixture 1417 def username(): 1418 return 'username' 1419 1420 test_something.py 1421 # content of tests/test_something.py 1422 import pytest 1423 1424 @pytest.fixture 1425 def username(username): 1426 return 'overridden-' + username 1427 1428 def test_username(username): 1429 assert username == 'overridden-username' 1430 1431 test_something_else.py 1432 # content of tests/test_something_else.py 1433 import pytest 1434 1435 @pytest.fixture 1436 def username(username): 1437 return 'overridden-else-' + username 1438 1439 def test_username(username): 1440 assert username == 'overridden-else-username' 1441 1442In the example above, a fixture with the same name can be overridden for certain test module. 1443 1444 1445Override a fixture with direct test parametrization 1446^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1447 1448Given the tests file structure is: 1449 1450:: 1451 1452 tests/ 1453 __init__.py 1454 1455 conftest.py 1456 # content of tests/conftest.py 1457 import pytest 1458 1459 @pytest.fixture 1460 def username(): 1461 return 'username' 1462 1463 @pytest.fixture 1464 def other_username(username): 1465 return 'other-' + username 1466 1467 test_something.py 1468 # content of tests/test_something.py 1469 import pytest 1470 1471 @pytest.mark.parametrize('username', ['directly-overridden-username']) 1472 def test_username(username): 1473 assert username == 'directly-overridden-username' 1474 1475 @pytest.mark.parametrize('username', ['directly-overridden-username-other']) 1476 def test_username_other(other_username): 1477 assert other_username == 'other-directly-overridden-username-other' 1478 1479In the example above, a fixture value is overridden by the test parameter value. Note that the value of the fixture 1480can be overridden this way even if the test doesn't use it directly (doesn't mention it in the function prototype). 1481 1482 1483Override a parametrized fixture with non-parametrized one and vice versa 1484^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1485 1486Given the tests file structure is: 1487 1488:: 1489 1490 tests/ 1491 __init__.py 1492 1493 conftest.py 1494 # content of tests/conftest.py 1495 import pytest 1496 1497 @pytest.fixture(params=['one', 'two', 'three']) 1498 def parametrized_username(request): 1499 return request.param 1500 1501 @pytest.fixture 1502 def non_parametrized_username(request): 1503 return 'username' 1504 1505 test_something.py 1506 # content of tests/test_something.py 1507 import pytest 1508 1509 @pytest.fixture 1510 def parametrized_username(): 1511 return 'overridden-username' 1512 1513 @pytest.fixture(params=['one', 'two', 'three']) 1514 def non_parametrized_username(request): 1515 return request.param 1516 1517 def test_username(parametrized_username): 1518 assert parametrized_username == 'overridden-username' 1519 1520 def test_parametrized_username(non_parametrized_username): 1521 assert non_parametrized_username in ['one', 'two', 'three'] 1522 1523 test_something_else.py 1524 # content of tests/test_something_else.py 1525 def test_username(parametrized_username): 1526 assert parametrized_username in ['one', 'two', 'three'] 1527 1528 def test_username(non_parametrized_username): 1529 assert non_parametrized_username == 'username' 1530 1531In the example above, a parametrized fixture is overridden with a non-parametrized version, and 1532a non-parametrized fixture is overridden with a parametrized version for certain test module. 1533The same applies for the test folder level obviously. 1534 1535 1536Using fixtures from other projects 1537---------------------------------- 1538 1539Usually projects that provide pytest support will use :ref:`entry points <setuptools entry points>`, 1540so just installing those projects into an environment will make those fixtures available for use. 1541 1542In case you want to use fixtures from a project that does not use entry points, you can 1543define :globalvar:`pytest_plugins` in your top ``conftest.py`` file to register that module 1544as a plugin. 1545 1546Suppose you have some fixtures in ``mylibrary.fixtures`` and you want to reuse them into your 1547``app/tests`` directory. 1548 1549All you need to do is to define :globalvar:`pytest_plugins` in ``app/tests/conftest.py`` 1550pointing to that module. 1551 1552.. code-block:: python 1553 1554 pytest_plugins = "mylibrary.fixtures" 1555 1556This effectively registers ``mylibrary.fixtures`` as a plugin, making all its fixtures and 1557hooks available to tests in ``app/tests``. 1558 1559.. note:: 1560 1561 Sometimes users will *import* fixtures from other projects for use, however this is not 1562 recommended: importing fixtures into a module will register them in pytest 1563 as *defined* in that module. 1564 1565 This has minor consequences, such as appearing multiple times in ``pytest --help``, 1566 but it is not **recommended** because this behavior might change/stop working 1567 in future versions. 1568