1.. _fixture: 2.. _fixtures: 3.. _`fixture functions`: 4 5pytest fixtures: explicit, modular, scalable 6======================================================== 7 8.. currentmodule:: _pytest.python 9 10.. versionadded:: 2.0/2.3/2.4 11 12.. _`xUnit`: http://en.wikipedia.org/wiki/XUnit 13.. _`purpose of test fixtures`: http://en.wikipedia.org/wiki/Test_fixture#Software 14.. _`Dependency injection`: http://en.wikipedia.org/wiki/Dependency_injection 15 16The `purpose of test fixtures`_ is to provide a fixed baseline 17upon which tests can reliably and repeatedly execute. pytest fixtures 18offer dramatic improvements over the classic xUnit style of setup/teardown 19functions: 20 21* fixtures have explicit names and are activated by declaring their use 22 from test functions, modules, classes or whole projects. 23 24* fixtures are implemented in a modular manner, as each fixture name 25 triggers a *fixture function* which can itself use other fixtures. 26 27* fixture management scales from simple unit to complex 28 functional testing, allowing to parametrize fixtures and tests according 29 to configuration and component options, or to re-use fixtures 30 across function, class, module or whole test session scopes. 31 32In addition, pytest continues to support :ref:`xunitsetup`. You can mix 33both styles, moving incrementally from classic to new style, as you 34prefer. You can also start out from existing :ref:`unittest.TestCase 35style <unittest.TestCase>` or :ref:`nose based <nosestyle>` projects. 36 37 38.. _`funcargs`: 39.. _`funcarg mechanism`: 40.. _`fixture function`: 41.. _`@pytest.fixture`: 42.. _`pytest.fixture`: 43 44Fixtures as Function arguments 45----------------------------------------- 46 47Test functions can receive fixture objects by naming them as an input 48argument. For each argument name, a fixture function with that name provides 49the fixture object. Fixture functions are registered by marking them with 50:py:func:`@pytest.fixture <_pytest.python.fixture>`. Let's look at a simple 51self-contained test module containing a fixture and a test function 52using it:: 53 54 # content of ./test_smtpsimple.py 55 import pytest 56 57 @pytest.fixture 58 def smtp(): 59 import smtplib 60 return smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 61 62 def test_ehlo(smtp): 63 response, msg = smtp.ehlo() 64 assert response == 250 65 assert 0 # for demo purposes 66 67Here, the ``test_ehlo`` needs the ``smtp`` fixture value. pytest 68will discover and call the :py:func:`@pytest.fixture <_pytest.python.fixture>` 69marked ``smtp`` fixture function. Running the test looks like this:: 70 71 $ pytest test_smtpsimple.py 72 =========================== test session starts ============================ 73 platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y 74 rootdir: $REGENDOC_TMPDIR, inifile: 75 collected 1 item 76 77 test_smtpsimple.py F [100%] 78 79 ================================= FAILURES ================================= 80 ________________________________ test_ehlo _________________________________ 81 82 smtp = <smtplib.SMTP object at 0xdeadbeef> 83 84 def test_ehlo(smtp): 85 response, msg = smtp.ehlo() 86 assert response == 250 87 > assert 0 # for demo purposes 88 E assert 0 89 90 test_smtpsimple.py:11: AssertionError 91 ========================= 1 failed in 0.12 seconds ========================= 92 93In the failure traceback we see that the test function was called with a 94``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture 95function. The test function fails on our deliberate ``assert 0``. Here is 96the exact protocol used by ``pytest`` to call the test function this way: 97 981. pytest :ref:`finds <test discovery>` the ``test_ehlo`` because 99 of the ``test_`` prefix. The test function needs a function argument 100 named ``smtp``. A matching fixture function is discovered by 101 looking for a fixture-marked function named ``smtp``. 102 1032. ``smtp()`` is called to create an instance. 104 1053. ``test_ehlo(<SMTP instance>)`` is called and fails in the last 106 line of the test function. 107 108Note that if you misspell a function argument or want 109to use one that isn't available, you'll see an error 110with a list of available function arguments. 111 112.. note:: 113 114 You can always issue:: 115 116 pytest --fixtures test_simplefactory.py 117 118 to see available fixtures. 119 120Fixtures: a prime example of dependency injection 121--------------------------------------------------- 122 123Fixtures allow test functions to easily receive and work 124against specific pre-initialized application objects without having 125to care about import/setup/cleanup details. 126It's a prime example of `dependency injection`_ where fixture 127functions take the role of the *injector* and test functions are the 128*consumers* of fixture objects. 129 130.. _`conftest.py`: 131.. _`conftest`: 132 133``conftest.py``: sharing fixture functions 134------------------------------------------ 135 136If during implementing your tests you realize that you 137want to use a fixture function from multiple test files you can move it 138to a ``conftest.py`` file. 139You don't need to import the fixture you want to use in a test, it 140automatically gets discovered by pytest. The discovery of 141fixture functions starts at test classes, then test modules, then 142``conftest.py`` files and finally builtin and third party plugins. 143 144You can also use the ``conftest.py`` file to implement 145:ref:`local per-directory plugins <conftest.py plugins>`. 146 147Sharing test data 148----------------- 149 150If you want to make test data from files available to your tests, a good way 151to do this is by loading these data in a fixture for use by your tests. 152This makes use of the automatic caching mechanisms of pytest. 153 154Another good approach is by adding the data files in the ``tests`` folder. 155There are also community plugins available to help managing this aspect of 156testing, e.g. `pytest-datadir <https://github.com/gabrielcnr/pytest-datadir>`__ 157and `pytest-datafiles <https://pypi.python.org/pypi/pytest-datafiles>`__. 158 159.. _smtpshared: 160 161Scope: sharing a fixture instance across tests in a class, module or session 162---------------------------------------------------------------------------- 163 164.. regendoc:wipe 165 166Fixtures requiring network access depend on connectivity and are 167usually time-expensive to create. Extending the previous example, we 168can add a ``scope='module'`` parameter to the 169:py:func:`@pytest.fixture <_pytest.python.fixture>` invocation 170to cause the decorated ``smtp`` fixture function to only be invoked once 171per test *module* (the default is to invoke once per test *function*). 172Multiple test functions in a test module will thus 173each receive the same ``smtp`` fixture instance, thus saving time. 174 175The next example puts the fixture function into a separate ``conftest.py`` file 176so that tests from multiple test modules in the directory can 177access the fixture function:: 178 179 # content of conftest.py 180 import pytest 181 import smtplib 182 183 @pytest.fixture(scope="module") 184 def smtp(): 185 return smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 186 187The name of the fixture again is ``smtp`` and you can access its result by 188listing the name ``smtp`` as an input parameter in any test or fixture 189function (in or below the directory where ``conftest.py`` is located):: 190 191 # content of test_module.py 192 193 def test_ehlo(smtp): 194 response, msg = smtp.ehlo() 195 assert response == 250 196 assert b"smtp.gmail.com" in msg 197 assert 0 # for demo purposes 198 199 def test_noop(smtp): 200 response, msg = smtp.noop() 201 assert response == 250 202 assert 0 # for demo purposes 203 204We deliberately insert failing ``assert 0`` statements in order to 205inspect what is going on and can now run the tests:: 206 207 $ pytest test_module.py 208 =========================== test session starts ============================ 209 platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y 210 rootdir: $REGENDOC_TMPDIR, inifile: 211 collected 2 items 212 213 test_module.py FF [100%] 214 215 ================================= FAILURES ================================= 216 ________________________________ test_ehlo _________________________________ 217 218 smtp = <smtplib.SMTP object at 0xdeadbeef> 219 220 def test_ehlo(smtp): 221 response, msg = smtp.ehlo() 222 assert response == 250 223 assert b"smtp.gmail.com" in msg 224 > assert 0 # for demo purposes 225 E assert 0 226 227 test_module.py:6: AssertionError 228 ________________________________ test_noop _________________________________ 229 230 smtp = <smtplib.SMTP object at 0xdeadbeef> 231 232 def test_noop(smtp): 233 response, msg = smtp.noop() 234 assert response == 250 235 > assert 0 # for demo purposes 236 E assert 0 237 238 test_module.py:11: AssertionError 239 ========================= 2 failed in 0.12 seconds ========================= 240 241You see the two ``assert 0`` failing and more importantly you can also see 242that the same (module-scoped) ``smtp`` object was passed into the two 243test functions because pytest shows the incoming argument values in the 244traceback. As a result, the two test functions using ``smtp`` run as 245quick as a single one because they reuse the same instance. 246 247If you decide that you rather want to have a session-scoped ``smtp`` 248instance, you can simply declare it: 249 250.. code-block:: python 251 252 @pytest.fixture(scope="session") 253 def smtp(...): 254 # the returned fixture value will be shared for 255 # all tests needing it 256 257Finally, the ``class`` scope will invoke the fixture once per test *class*. 258 259.. _`finalization`: 260 261Fixture finalization / executing teardown code 262------------------------------------------------------------- 263 264pytest supports execution of fixture specific finalization code 265when the fixture goes out of scope. By using a ``yield`` statement instead of ``return``, all 266the code after the *yield* statement serves as the teardown code: 267 268.. code-block:: python 269 270 # content of conftest.py 271 272 import smtplib 273 import pytest 274 275 @pytest.fixture(scope="module") 276 def smtp(): 277 smtp = smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 278 yield smtp # provide the fixture value 279 print("teardown smtp") 280 smtp.close() 281 282The ``print`` and ``smtp.close()`` statements will execute when the last test in 283the module has finished execution, regardless of the exception status of the 284tests. 285 286Let's execute it:: 287 288 $ pytest -s -q --tb=no 289 FF [100%]teardown smtp 290 291 2 failed in 0.12 seconds 292 293We see that the ``smtp`` instance is finalized after the two 294tests finished execution. Note that if we decorated our fixture 295function with ``scope='function'`` then fixture setup and cleanup would 296occur around each single test. In either case the test 297module itself does not need to change or know about these details 298of fixture setup. 299 300Note that we can also seamlessly use the ``yield`` syntax with ``with`` statements: 301 302.. code-block:: python 303 304 # content of test_yield2.py 305 306 import smtplib 307 import pytest 308 309 @pytest.fixture(scope="module") 310 def smtp(): 311 with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp: 312 yield smtp # provide the fixture value 313 314 315The ``smtp`` connection will be closed after the test finished execution 316because the ``smtp`` object automatically closes when 317the ``with`` statement ends. 318 319Note that if an exception happens during the *setup* code (before the ``yield`` keyword), the 320*teardown* code (after the ``yield``) will not be called. 321 322An alternative option for executing *teardown* code is to 323make use of the ``addfinalizer`` method of the `request-context`_ object to register 324finalization functions. 325 326Here's the ``smtp`` fixture changed to use ``addfinalizer`` for cleanup: 327 328.. code-block:: python 329 330 # content of conftest.py 331 import smtplib 332 import pytest 333 334 @pytest.fixture(scope="module") 335 def smtp(request): 336 smtp = smtplib.SMTP("smtp.gmail.com", 587, timeout=5) 337 def fin(): 338 print ("teardown smtp") 339 smtp.close() 340 request.addfinalizer(fin) 341 return smtp # provide the fixture value 342 343 344Both ``yield`` and ``addfinalizer`` methods work similarly by calling their code after the test 345ends, but ``addfinalizer`` has two key differences over ``yield``: 346 3471. It is possible to register multiple finalizer functions. 348 3492. Finalizers will always be called regardless if the fixture *setup* code raises an exception. 350 This is handy to properly close all resources created by a fixture even if one of them 351 fails to be created/acquired:: 352 353 @pytest.fixture 354 def equipments(request): 355 r = [] 356 for port in ('C1', 'C3', 'C28'): 357 equip = connect(port) 358 request.addfinalizer(equip.disconnect) 359 r.append(equip) 360 return r 361 362 In the example above, if ``"C28"`` fails with an exception, ``"C1"`` and ``"C3"`` will still 363 be properly closed. Of course, if an exception happens before the finalize function is 364 registered then it will not be executed. 365 366 367.. _`request-context`: 368 369Fixtures can introspect the requesting test context 370------------------------------------------------------------- 371 372Fixture function can accept the :py:class:`request <FixtureRequest>` object 373to introspect the "requesting" test function, class or module context. 374Further extending the previous ``smtp`` fixture example, let's 375read an optional server URL from the test module which uses our fixture:: 376 377 # content of conftest.py 378 import pytest 379 import smtplib 380 381 @pytest.fixture(scope="module") 382 def smtp(request): 383 server = getattr(request.module, "smtpserver", "smtp.gmail.com") 384 smtp = smtplib.SMTP(server, 587, timeout=5) 385 yield smtp 386 print ("finalizing %s (%s)" % (smtp, server)) 387 smtp.close() 388 389We use the ``request.module`` attribute to optionally obtain an 390``smtpserver`` attribute from the test module. If we just execute 391again, nothing much has changed:: 392 393 $ pytest -s -q --tb=no 394 FF [100%]finalizing <smtplib.SMTP object at 0xdeadbeef> (smtp.gmail.com) 395 396 2 failed in 0.12 seconds 397 398Let's quickly create another test module that actually sets the 399server URL in its module namespace:: 400 401 # content of test_anothersmtp.py 402 403 smtpserver = "mail.python.org" # will be read by smtp fixture 404 405 def test_showhelo(smtp): 406 assert 0, smtp.helo() 407 408Running it:: 409 410 $ pytest -qq --tb=short test_anothersmtp.py 411 F [100%] 412 ================================= FAILURES ================================= 413 ______________________________ test_showhelo _______________________________ 414 test_anothersmtp.py:5: in test_showhelo 415 assert 0, smtp.helo() 416 E AssertionError: (250, b'mail.python.org') 417 E assert 0 418 ------------------------- Captured stdout teardown ------------------------- 419 finalizing <smtplib.SMTP object at 0xdeadbeef> (mail.python.org) 420 421voila! The ``smtp`` fixture function picked up our mail server name 422from the module namespace. 423 424.. _`fixture-parametrize`: 425 426Parametrizing fixtures 427----------------------------------------------------------------- 428 429Fixture functions can be parametrized in which case they will be called 430multiple times, each time executing the set of dependent tests, i. e. the 431tests that depend on this fixture. Test functions do usually not need 432to be aware of their re-running. Fixture parametrization helps to 433write exhaustive functional tests for components which themselves can be 434configured in multiple ways. 435 436Extending the previous example, we can flag the fixture to create two 437``smtp`` fixture instances which will cause all tests using the fixture 438to run twice. The fixture function gets access to each parameter 439through the special :py:class:`request <FixtureRequest>` object:: 440 441 # content of conftest.py 442 import pytest 443 import smtplib 444 445 @pytest.fixture(scope="module", 446 params=["smtp.gmail.com", "mail.python.org"]) 447 def smtp(request): 448 smtp = smtplib.SMTP(request.param, 587, timeout=5) 449 yield smtp 450 print ("finalizing %s" % smtp) 451 smtp.close() 452 453The main change is the declaration of ``params`` with 454:py:func:`@pytest.fixture <_pytest.python.fixture>`, a list of values 455for each of which the fixture function will execute and can access 456a value via ``request.param``. No test function code needs to change. 457So let's just do another run:: 458 459 $ pytest -q test_module.py 460 FFFF [100%] 461 ================================= FAILURES ================================= 462 ________________________ test_ehlo[smtp.gmail.com] _________________________ 463 464 smtp = <smtplib.SMTP object at 0xdeadbeef> 465 466 def test_ehlo(smtp): 467 response, msg = smtp.ehlo() 468 assert response == 250 469 assert b"smtp.gmail.com" in msg 470 > assert 0 # for demo purposes 471 E assert 0 472 473 test_module.py:6: AssertionError 474 ________________________ test_noop[smtp.gmail.com] _________________________ 475 476 smtp = <smtplib.SMTP object at 0xdeadbeef> 477 478 def test_noop(smtp): 479 response, msg = smtp.noop() 480 assert response == 250 481 > assert 0 # for demo purposes 482 E assert 0 483 484 test_module.py:11: AssertionError 485 ________________________ test_ehlo[mail.python.org] ________________________ 486 487 smtp = <smtplib.SMTP object at 0xdeadbeef> 488 489 def test_ehlo(smtp): 490 response, msg = smtp.ehlo() 491 assert response == 250 492 > assert b"smtp.gmail.com" in msg 493 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' 494 495 test_module.py:5: AssertionError 496 -------------------------- Captured stdout setup --------------------------- 497 finalizing <smtplib.SMTP object at 0xdeadbeef> 498 ________________________ test_noop[mail.python.org] ________________________ 499 500 smtp = <smtplib.SMTP object at 0xdeadbeef> 501 502 def test_noop(smtp): 503 response, msg = smtp.noop() 504 assert response == 250 505 > assert 0 # for demo purposes 506 E assert 0 507 508 test_module.py:11: AssertionError 509 ------------------------- Captured stdout teardown ------------------------- 510 finalizing <smtplib.SMTP object at 0xdeadbeef> 511 4 failed in 0.12 seconds 512 513We see that our two test functions each ran twice, against the different 514``smtp`` instances. Note also, that with the ``mail.python.org`` 515connection the second test fails in ``test_ehlo`` because a 516different server string is expected than what arrived. 517 518pytest will build a string that is the test ID for each fixture value 519in a parametrized fixture, e.g. ``test_ehlo[smtp.gmail.com]`` and 520``test_ehlo[mail.python.org]`` in the above examples. These IDs can 521be used with ``-k`` to select specific cases to run, and they will 522also identify the specific case when one is failing. Running pytest 523with ``--collect-only`` will show the generated IDs. 524 525Numbers, strings, booleans and None will have their usual string 526representation used in the test ID. For other objects, pytest will 527make a string based on the argument name. It is possible to customise 528the string used in a test ID for a certain fixture value by using the 529``ids`` keyword argument:: 530 531 # content of test_ids.py 532 import pytest 533 534 @pytest.fixture(params=[0, 1], ids=["spam", "ham"]) 535 def a(request): 536 return request.param 537 538 def test_a(a): 539 pass 540 541 def idfn(fixture_value): 542 if fixture_value == 0: 543 return "eggs" 544 else: 545 return None 546 547 @pytest.fixture(params=[0, 1], ids=idfn) 548 def b(request): 549 return request.param 550 551 def test_b(b): 552 pass 553 554The above shows how ``ids`` can be either a list of strings to use or 555a function which will be called with the fixture value and then 556has to return a string to use. In the latter case if the function 557return ``None`` then pytest's auto-generated ID will be used. 558 559Running the above tests results in the following test IDs being used:: 560 561 $ pytest --collect-only 562 =========================== test session starts ============================ 563 platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y 564 rootdir: $REGENDOC_TMPDIR, inifile: 565 collected 10 items 566 <Module 'test_anothersmtp.py'> 567 <Function 'test_showhelo[smtp.gmail.com]'> 568 <Function 'test_showhelo[mail.python.org]'> 569 <Module 'test_ids.py'> 570 <Function 'test_a[spam]'> 571 <Function 'test_a[ham]'> 572 <Function 'test_b[eggs]'> 573 <Function 'test_b[1]'> 574 <Module 'test_module.py'> 575 <Function 'test_ehlo[smtp.gmail.com]'> 576 <Function 'test_noop[smtp.gmail.com]'> 577 <Function 'test_ehlo[mail.python.org]'> 578 <Function 'test_noop[mail.python.org]'> 579 580 ======================= no tests ran in 0.12 seconds ======================= 581 582.. _`interdependent fixtures`: 583 584Modularity: using fixtures from a fixture function 585---------------------------------------------------------- 586 587You can not only use fixtures in test functions but fixture functions 588can use other fixtures themselves. This contributes to a modular design 589of your fixtures and allows re-use of framework-specific fixtures across 590many projects. As a simple example, we can extend the previous example 591and instantiate an object ``app`` where we stick the already defined 592``smtp`` resource into it:: 593 594 # content of test_appsetup.py 595 596 import pytest 597 598 class App(object): 599 def __init__(self, smtp): 600 self.smtp = smtp 601 602 @pytest.fixture(scope="module") 603 def app(smtp): 604 return App(smtp) 605 606 def test_smtp_exists(app): 607 assert app.smtp 608 609Here we declare an ``app`` fixture which receives the previously defined 610``smtp`` fixture and instantiates an ``App`` object with it. Let's run it:: 611 612 $ pytest -v test_appsetup.py 613 =========================== test session starts ============================ 614 platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5 615 cachedir: .cache 616 rootdir: $REGENDOC_TMPDIR, inifile: 617 collecting ... collected 2 items 618 619 test_appsetup.py::test_smtp_exists[smtp.gmail.com] PASSED [ 50%] 620 test_appsetup.py::test_smtp_exists[mail.python.org] PASSED [100%] 621 622 ========================= 2 passed in 0.12 seconds ========================= 623 624Due to the parametrization of ``smtp`` the test will run twice with two 625different ``App`` instances and respective smtp servers. There is no 626need for the ``app`` fixture to be aware of the ``smtp`` parametrization 627as pytest will fully analyse the fixture dependency graph. 628 629Note, that the ``app`` fixture has a scope of ``module`` and uses a 630module-scoped ``smtp`` fixture. The example would still work if ``smtp`` 631was cached on a ``session`` scope: it is fine for fixtures to use 632"broader" scoped fixtures but not the other way round: 633A session-scoped fixture could not use a module-scoped one in a 634meaningful way. 635 636 637.. _`automatic per-resource grouping`: 638 639Automatic grouping of tests by fixture instances 640---------------------------------------------------------- 641 642.. regendoc: wipe 643 644pytest minimizes the number of active fixtures during test runs. 645If you have a parametrized fixture, then all the tests using it will 646first execute with one instance and then finalizers are called 647before the next fixture instance is created. Among other things, 648this eases testing of applications which create and use global state. 649 650The following example uses two parametrized fixture, one of which is 651scoped on a per-module basis, and all the functions perform ``print`` calls 652to show the setup/teardown flow:: 653 654 # content of test_module.py 655 import pytest 656 657 @pytest.fixture(scope="module", params=["mod1", "mod2"]) 658 def modarg(request): 659 param = request.param 660 print (" SETUP modarg %s" % param) 661 yield param 662 print (" TEARDOWN modarg %s" % param) 663 664 @pytest.fixture(scope="function", params=[1,2]) 665 def otherarg(request): 666 param = request.param 667 print (" SETUP otherarg %s" % param) 668 yield param 669 print (" TEARDOWN otherarg %s" % param) 670 671 def test_0(otherarg): 672 print (" RUN test0 with otherarg %s" % otherarg) 673 def test_1(modarg): 674 print (" RUN test1 with modarg %s" % modarg) 675 def test_2(otherarg, modarg): 676 print (" RUN test2 with otherarg %s and modarg %s" % (otherarg, modarg)) 677 678 679Let's run the tests in verbose mode and with looking at the print-output:: 680 681 $ pytest -v -s test_module.py 682 =========================== test session starts ============================ 683 platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5 684 cachedir: .cache 685 rootdir: $REGENDOC_TMPDIR, inifile: 686 collecting ... collected 8 items 687 688 test_module.py::test_0[1] SETUP otherarg 1 689 RUN test0 with otherarg 1 690 PASSED [ 12%] TEARDOWN otherarg 1 691 692 test_module.py::test_0[2] SETUP otherarg 2 693 RUN test0 with otherarg 2 694 PASSED [ 25%] TEARDOWN otherarg 2 695 696 test_module.py::test_1[mod1] SETUP modarg mod1 697 RUN test1 with modarg mod1 698 PASSED [ 37%] 699 test_module.py::test_2[1-mod1] SETUP otherarg 1 700 RUN test2 with otherarg 1 and modarg mod1 701 PASSED [ 50%] TEARDOWN otherarg 1 702 703 test_module.py::test_2[2-mod1] SETUP otherarg 2 704 RUN test2 with otherarg 2 and modarg mod1 705 PASSED [ 62%] TEARDOWN otherarg 2 706 707 test_module.py::test_1[mod2] TEARDOWN modarg mod1 708 SETUP modarg mod2 709 RUN test1 with modarg mod2 710 PASSED [ 75%] 711 test_module.py::test_2[1-mod2] SETUP otherarg 1 712 RUN test2 with otherarg 1 and modarg mod2 713 PASSED [ 87%] TEARDOWN otherarg 1 714 715 test_module.py::test_2[2-mod2] SETUP otherarg 2 716 RUN test2 with otherarg 2 and modarg mod2 717 PASSED [100%] TEARDOWN otherarg 2 718 TEARDOWN modarg mod2 719 720 721 ========================= 8 passed in 0.12 seconds ========================= 722 723You can see that the parametrized module-scoped ``modarg`` resource caused an 724ordering of test execution that lead to the fewest possible "active" resources. 725The finalizer for the ``mod1`` parametrized resource was executed before the 726``mod2`` resource was setup. 727 728In particular notice that test_0 is completely independent and finishes first. 729Then test_1 is executed with ``mod1``, then test_2 with ``mod1``, then test_1 730with ``mod2`` and finally test_2 with ``mod2``. 731 732The ``otherarg`` parametrized resource (having function scope) was set up before 733and teared down after every test that used it. 734 735 736.. _`usefixtures`: 737 738Using fixtures from classes, modules or projects 739---------------------------------------------------------------------- 740 741.. regendoc:wipe 742 743Sometimes test functions do not directly need access to a fixture object. 744For example, tests may require to operate with an empty directory as the 745current working directory but otherwise do not care for the concrete 746directory. Here is how you can use the standard `tempfile 747<http://docs.python.org/library/tempfile.html>`_ and pytest fixtures to 748achieve it. We separate the creation of the fixture into a conftest.py 749file:: 750 751 # content of conftest.py 752 753 import pytest 754 import tempfile 755 import os 756 757 @pytest.fixture() 758 def cleandir(): 759 newpath = tempfile.mkdtemp() 760 os.chdir(newpath) 761 762and declare its use in a test module via a ``usefixtures`` marker:: 763 764 # content of test_setenv.py 765 import os 766 import pytest 767 768 @pytest.mark.usefixtures("cleandir") 769 class TestDirectoryInit(object): 770 def test_cwd_starts_empty(self): 771 assert os.listdir(os.getcwd()) == [] 772 with open("myfile", "w") as f: 773 f.write("hello") 774 775 def test_cwd_again_starts_empty(self): 776 assert os.listdir(os.getcwd()) == [] 777 778Due to the ``usefixtures`` marker, the ``cleandir`` fixture 779will be required for the execution of each test method, just as if 780you specified a "cleandir" function argument to each of them. Let's run it 781to verify our fixture is activated and the tests pass:: 782 783 $ pytest -q 784 .. [100%] 785 2 passed in 0.12 seconds 786 787You can specify multiple fixtures like this: 788 789.. code-block:: python 790 791 @pytest.mark.usefixtures("cleandir", "anotherfixture") 792 793and you may specify fixture usage at the test module level, using 794a generic feature of the mark mechanism: 795 796.. code-block:: python 797 798 pytestmark = pytest.mark.usefixtures("cleandir") 799 800Note that the assigned variable *must* be called ``pytestmark``, assigning e.g. 801``foomark`` will not activate the fixtures. 802 803Lastly you can put fixtures required by all tests in your project 804into an ini-file: 805 806.. code-block:: ini 807 808 # content of pytest.ini 809 [pytest] 810 usefixtures = cleandir 811 812 813.. _`autouse`: 814.. _`autouse fixtures`: 815 816Autouse fixtures (xUnit setup on steroids) 817---------------------------------------------------------------------- 818 819.. regendoc:wipe 820 821Occasionally, you may want to have fixtures get invoked automatically 822without declaring a function argument explicitly or a `usefixtures`_ decorator. 823As a practical example, suppose we have a database fixture which has a 824begin/rollback/commit architecture and we want to automatically surround 825each test method by a transaction and a rollback. Here is a dummy 826self-contained implementation of this idea:: 827 828 # content of test_db_transact.py 829 830 import pytest 831 832 class DB(object): 833 def __init__(self): 834 self.intransaction = [] 835 def begin(self, name): 836 self.intransaction.append(name) 837 def rollback(self): 838 self.intransaction.pop() 839 840 @pytest.fixture(scope="module") 841 def db(): 842 return DB() 843 844 class TestClass(object): 845 @pytest.fixture(autouse=True) 846 def transact(self, request, db): 847 db.begin(request.function.__name__) 848 yield 849 db.rollback() 850 851 def test_method1(self, db): 852 assert db.intransaction == ["test_method1"] 853 854 def test_method2(self, db): 855 assert db.intransaction == ["test_method2"] 856 857The class-level ``transact`` fixture is marked with *autouse=true* 858which implies that all test methods in the class will use this fixture 859without a need to state it in the test function signature or with a 860class-level ``usefixtures`` decorator. 861 862If we run it, we get two passing tests:: 863 864 $ pytest -q 865 .. [100%] 866 2 passed in 0.12 seconds 867 868Here is how autouse fixtures work in other scopes: 869 870- autouse fixtures obey the ``scope=`` keyword-argument: if an autouse fixture 871 has ``scope='session'`` it will only be run once, no matter where it is 872 defined. ``scope='class'`` means it will be run once per class, etc. 873 874- if an autouse fixture is defined in a test module, all its test 875 functions automatically use it. 876 877- if an autouse fixture is defined in a conftest.py file then all tests in 878 all test modules below its directory will invoke the fixture. 879 880- lastly, and **please use that with care**: if you define an autouse 881 fixture in a plugin, it will be invoked for all tests in all projects 882 where the plugin is installed. This can be useful if a fixture only 883 anyway works in the presence of certain settings e. g. in the ini-file. Such 884 a global fixture should always quickly determine if it should do 885 any work and avoid otherwise expensive imports or computation. 886 887Note that the above ``transact`` fixture may very well be a fixture that 888you want to make available in your project without having it generally 889active. The canonical way to do that is to put the transact definition 890into a conftest.py file **without** using ``autouse``:: 891 892 # content of conftest.py 893 @pytest.fixture 894 def transact(request, db): 895 db.begin() 896 yield 897 db.rollback() 898 899and then e.g. have a TestClass using it by declaring the need:: 900 901 @pytest.mark.usefixtures("transact") 902 class TestClass(object): 903 def test_method1(self): 904 ... 905 906All test methods in this TestClass will use the transaction fixture while 907other test classes or functions in the module will not use it unless 908they also add a ``transact`` reference. 909 910Overriding fixtures on various levels 911------------------------------------- 912 913In relatively large test suite, you most likely need to ``override`` a ``global`` or ``root`` fixture with a ``locally`` 914defined one, keeping the test code readable and maintainable. 915 916Override a fixture on a folder (conftest) level 917^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 918 919Given the tests file structure is: 920 921:: 922 923 tests/ 924 __init__.py 925 926 conftest.py 927 # content of tests/conftest.py 928 import pytest 929 930 @pytest.fixture 931 def username(): 932 return 'username' 933 934 test_something.py 935 # content of tests/test_something.py 936 def test_username(username): 937 assert username == 'username' 938 939 subfolder/ 940 __init__.py 941 942 conftest.py 943 # content of tests/subfolder/conftest.py 944 import pytest 945 946 @pytest.fixture 947 def username(username): 948 return 'overridden-' + username 949 950 test_something.py 951 # content of tests/subfolder/test_something.py 952 def test_username(username): 953 assert username == 'overridden-username' 954 955As you can see, a fixture with the same name can be overridden for certain test folder level. 956Note that the ``base`` or ``super`` fixture can be accessed from the ``overriding`` 957fixture easily - used in the example above. 958 959Override a fixture on a test module level 960^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 961 962Given the tests file structure is: 963 964:: 965 966 tests/ 967 __init__.py 968 969 conftest.py 970 # content of tests/conftest.py 971 @pytest.fixture 972 def username(): 973 return 'username' 974 975 test_something.py 976 # content of tests/test_something.py 977 import pytest 978 979 @pytest.fixture 980 def username(username): 981 return 'overridden-' + username 982 983 def test_username(username): 984 assert username == 'overridden-username' 985 986 test_something_else.py 987 # content of tests/test_something_else.py 988 import pytest 989 990 @pytest.fixture 991 def username(username): 992 return 'overridden-else-' + username 993 994 def test_username(username): 995 assert username == 'overridden-else-username' 996 997In the example above, a fixture with the same name can be overridden for certain test module. 998 999 1000Override a fixture with direct test parametrization 1001^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1002 1003Given the tests file structure is: 1004 1005:: 1006 1007 tests/ 1008 __init__.py 1009 1010 conftest.py 1011 # content of tests/conftest.py 1012 import pytest 1013 1014 @pytest.fixture 1015 def username(): 1016 return 'username' 1017 1018 @pytest.fixture 1019 def other_username(username): 1020 return 'other-' + username 1021 1022 test_something.py 1023 # content of tests/test_something.py 1024 import pytest 1025 1026 @pytest.mark.parametrize('username', ['directly-overridden-username']) 1027 def test_username(username): 1028 assert username == 'directly-overridden-username' 1029 1030 @pytest.mark.parametrize('username', ['directly-overridden-username-other']) 1031 def test_username_other(other_username): 1032 assert other_username == 'other-directly-overridden-username-other' 1033 1034In the example above, a fixture value is overridden by the test parameter value. Note that the value of the fixture 1035can be overridden this way even if the test doesn't use it directly (doesn't mention it in the function prototype). 1036 1037 1038Override a parametrized fixture with non-parametrized one and vice versa 1039^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1040 1041Given the tests file structure is: 1042 1043:: 1044 1045 tests/ 1046 __init__.py 1047 1048 conftest.py 1049 # content of tests/conftest.py 1050 import pytest 1051 1052 @pytest.fixture(params=['one', 'two', 'three']) 1053 def parametrized_username(request): 1054 return request.param 1055 1056 @pytest.fixture 1057 def non_parametrized_username(request): 1058 return 'username' 1059 1060 test_something.py 1061 # content of tests/test_something.py 1062 import pytest 1063 1064 @pytest.fixture 1065 def parametrized_username(): 1066 return 'overridden-username' 1067 1068 @pytest.fixture(params=['one', 'two', 'three']) 1069 def non_parametrized_username(request): 1070 return request.param 1071 1072 def test_username(parametrized_username): 1073 assert parametrized_username == 'overridden-username' 1074 1075 def test_parametrized_username(non_parametrized_username): 1076 assert non_parametrized_username in ['one', 'two', 'three'] 1077 1078 test_something_else.py 1079 # content of tests/test_something_else.py 1080 def test_username(parametrized_username): 1081 assert parametrized_username in ['one', 'two', 'three'] 1082 1083 def test_username(non_parametrized_username): 1084 assert non_parametrized_username == 'username' 1085 1086In the example above, a parametrized fixture is overridden with a non-parametrized version, and 1087a non-parametrized fixture is overridden with a parametrized version for certain test module. 1088The same applies for the test folder level obviously. 1089