commit
						6c8d8a99f4
					
				| 
						 | 
					@ -238,14 +238,17 @@ file which provides an alternative explanation for ``Foo`` objects:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   def pytest_assertrepr_compare(op, left, right):
 | 
					   def pytest_assertrepr_compare(op, left, right):
 | 
				
			||||||
       if isinstance(left, Foo) and isinstance(right, Foo) and op == "==":
 | 
					       if isinstance(left, Foo) and isinstance(right, Foo) and op == "==":
 | 
				
			||||||
           return ["Comparing Foo instances:", "   vals: %s != %s" % (left.val, right.val)]
 | 
					           return [
 | 
				
			||||||
 | 
					               "Comparing Foo instances:",
 | 
				
			||||||
 | 
					               "   vals: {} != {}".format(left.val, right.val),
 | 
				
			||||||
 | 
					           ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
now, given this test module:
 | 
					now, given this test module:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: python
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   # content of test_foocompare.py
 | 
					   # content of test_foocompare.py
 | 
				
			||||||
   class Foo(object):
 | 
					   class Foo:
 | 
				
			||||||
       def __init__(self, val):
 | 
					       def __init__(self, val):
 | 
				
			||||||
           self.val = val
 | 
					           self.val = val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,7 +162,10 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    no tests ran in 0.12 seconds
 | 
					    no tests ran in 0.12 seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can also interactively ask for help, e.g. by typing on the Python interactive prompt something like::
 | 
					You can also interactively ask for help, e.g. by typing on the Python interactive prompt something like:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    help(pytest)
 | 
					    help(pytest)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,15 +33,18 @@ Other plugins may access the `config.cache`_ object to set/get
 | 
				
			||||||
Rerunning only failures or failures first
 | 
					Rerunning only failures or failures first
 | 
				
			||||||
-----------------------------------------------
 | 
					-----------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First, let's create 50 test invocation of which only 2 fail::
 | 
					First, let's create 50 test invocation of which only 2 fail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_50.py
 | 
					    # content of test_50.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize("i", range(50))
 | 
					    @pytest.mark.parametrize("i", range(50))
 | 
				
			||||||
    def test_num(i):
 | 
					    def test_num(i):
 | 
				
			||||||
        if i in (17, 25):
 | 
					        if i in (17, 25):
 | 
				
			||||||
           pytest.fail("bad luck")
 | 
					            pytest.fail("bad luck")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you run this for the first time you will see two failures:
 | 
					If you run this for the first time you will see two failures:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -183,15 +186,19 @@ The new config.cache object
 | 
				
			||||||
Plugins or conftest.py support code can get a cached value using the
 | 
					Plugins or conftest.py support code can get a cached value using the
 | 
				
			||||||
pytest ``config`` object.  Here is a basic example plugin which
 | 
					pytest ``config`` object.  Here is a basic example plugin which
 | 
				
			||||||
implements a :ref:`fixture` which re-uses previously created state
 | 
					implements a :ref:`fixture` which re-uses previously created state
 | 
				
			||||||
across pytest invocations::
 | 
					across pytest invocations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_caching.py
 | 
					    # content of test_caching.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    import time
 | 
					    import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def expensive_computation():
 | 
					    def expensive_computation():
 | 
				
			||||||
        print("running expensive computation...")
 | 
					        print("running expensive computation...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture
 | 
					    @pytest.fixture
 | 
				
			||||||
    def mydata(request):
 | 
					    def mydata(request):
 | 
				
			||||||
        val = request.config.cache.get("example/value", None)
 | 
					        val = request.config.cache.get("example/value", None)
 | 
				
			||||||
| 
						 | 
					@ -201,6 +208,7 @@ across pytest invocations::
 | 
				
			||||||
            request.config.cache.set("example/value", val)
 | 
					            request.config.cache.set("example/value", val)
 | 
				
			||||||
        return val
 | 
					        return val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_function(mydata):
 | 
					    def test_function(mydata):
 | 
				
			||||||
        assert mydata == 23
 | 
					        assert mydata == 23
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,16 +49,21 @@ Using print statements for debugging
 | 
				
			||||||
---------------------------------------------------
 | 
					---------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
One primary benefit of the default capturing of stdout/stderr output
 | 
					One primary benefit of the default capturing of stdout/stderr output
 | 
				
			||||||
is that you can use print statements for debugging::
 | 
					is that you can use print statements for debugging:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_module.py
 | 
					    # content of test_module.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_function(function):
 | 
					    def setup_function(function):
 | 
				
			||||||
        print("setting up %s" % function)
 | 
					        print("setting up %s" % function)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_func1():
 | 
					    def test_func1():
 | 
				
			||||||
        assert True
 | 
					        assert True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_func2():
 | 
					    def test_func2():
 | 
				
			||||||
        assert False
 | 
					        assert False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,7 +455,9 @@ Internal classes accessed through ``Node``
 | 
				
			||||||
.. versionremoved:: 4.0
 | 
					.. versionremoved:: 4.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue
 | 
					Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue
 | 
				
			||||||
this warning::
 | 
					this warning:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    usage of Function.Module is deprecated, please use pytest.Module instead
 | 
					    usage of Function.Module is deprecated, please use pytest.Module instead
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,15 +191,21 @@ namespace in which your doctests run. It is intended to be used within
 | 
				
			||||||
your own fixtures to provide the tests that use them with context.
 | 
					your own fixtures to provide the tests that use them with context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``doctest_namespace`` is a standard ``dict`` object into which you
 | 
					``doctest_namespace`` is a standard ``dict`` object into which you
 | 
				
			||||||
place the objects you want to appear in the doctest namespace::
 | 
					place the objects you want to appear in the doctest namespace:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import numpy
 | 
					    import numpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(autouse=True)
 | 
					    @pytest.fixture(autouse=True)
 | 
				
			||||||
    def add_np(doctest_namespace):
 | 
					    def add_np(doctest_namespace):
 | 
				
			||||||
        doctest_namespace['np'] = numpy
 | 
					        doctest_namespace["np"] = numpy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
which can then be used in your doctests directly::
 | 
					which can then be used in your doctests directly:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of numpy.py
 | 
					    # content of numpy.py
 | 
				
			||||||
    def arange():
 | 
					    def arange():
 | 
				
			||||||
| 
						 | 
					@ -219,7 +225,9 @@ Skipping tests dynamically
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. versionadded:: 4.4
 | 
					.. versionadded:: 4.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can use ``pytest.skip`` to dynamically skip doctests. For example::
 | 
					You can use ``pytest.skip`` to dynamically skip doctests. For example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> import sys, pytest
 | 
					    >>> import sys, pytest
 | 
				
			||||||
    >>> if sys.platform.startswith('win'):
 | 
					    >>> if sys.platform.startswith('win'):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ example: specifying and selecting acceptance tests
 | 
				
			||||||
        return AcceptFixture(request)
 | 
					        return AcceptFixture(request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class AcceptFixture(object):
 | 
					    class AcceptFixture:
 | 
				
			||||||
        def __init__(self, request):
 | 
					        def __init__(self, request):
 | 
				
			||||||
            if not request.config.getoption("acceptance"):
 | 
					            if not request.config.getoption("acceptance"):
 | 
				
			||||||
                pytest.skip("specify -A to run acceptance tests")
 | 
					                pytest.skip("specify -A to run acceptance tests")
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ extend the `accept example`_ by putting this in our test module:
 | 
				
			||||||
        return arg
 | 
					        return arg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestSpecialAcceptance(object):
 | 
					    class TestSpecialAcceptance:
 | 
				
			||||||
        def test_sometest(self, accept):
 | 
					        def test_sometest(self, accept):
 | 
				
			||||||
            assert accept.tmpdir.join("special").check()
 | 
					            assert accept.tmpdir.join("special").check()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ You can "mark" a test function with custom metadata like this:
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        def test_method(self):
 | 
					        def test_method(self):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -278,7 +278,7 @@ its test methods:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.webtest
 | 
					    @pytest.mark.webtest
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        def test_startup(self):
 | 
					        def test_startup(self):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,7 +295,7 @@ Due to legacy reasons, it is possible to set the ``pytestmark`` attribute on a T
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        pytestmark = pytest.mark.webtest
 | 
					        pytestmark = pytest.mark.webtest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
or if you need to use multiple markers you can use a list:
 | 
					or if you need to use multiple markers you can use a list:
 | 
				
			||||||
| 
						 | 
					@ -305,7 +305,7 @@ or if you need to use multiple markers you can use a list:
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        pytestmark = [pytest.mark.webtest, pytest.mark.slowtest]
 | 
					        pytestmark = [pytest.mark.webtest, pytest.mark.slowtest]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can also set a module level marker::
 | 
					You can also set a module level marker::
 | 
				
			||||||
| 
						 | 
					@ -523,7 +523,7 @@ code you can read over all such settings.  Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.glob("class", x=2)
 | 
					    @pytest.mark.glob("class", x=2)
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        @pytest.mark.glob("function", x=3)
 | 
					        @pytest.mark.glob("function", x=3)
 | 
				
			||||||
        def test_something(self):
 | 
					        def test_something(self):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
| 
						 | 
					@ -539,7 +539,7 @@ test function.  From a conftest file we can read it like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_runtest_setup(item):
 | 
					    def pytest_runtest_setup(item):
 | 
				
			||||||
        for mark in item.iter_markers(name="glob"):
 | 
					        for mark in item.iter_markers(name="glob"):
 | 
				
			||||||
            print("glob args=%s kwargs=%s" % (mark.args, mark.kwargs))
 | 
					            print("glob args={} kwargs={}".format(mark.args, mark.kwargs))
 | 
				
			||||||
            sys.stdout.flush()
 | 
					            sys.stdout.flush()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's run this without capturing output and see what we get:
 | 
					Let's run this without capturing output and see what we get:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,24 +19,30 @@ Generating parameters combinations, depending on command line
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's say we want to execute a test with different computation
 | 
					Let's say we want to execute a test with different computation
 | 
				
			||||||
parameters and the parameter range shall be determined by a command
 | 
					parameters and the parameter range shall be determined by a command
 | 
				
			||||||
line argument.  Let's first write a simple (do-nothing) computation test::
 | 
					line argument.  Let's first write a simple (do-nothing) computation test:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_compute.py
 | 
					    # content of test_compute.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_compute(param1):
 | 
					    def test_compute(param1):
 | 
				
			||||||
        assert param1 < 4
 | 
					        assert param1 < 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now we add a test configuration like this::
 | 
					Now we add a test configuration like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_addoption(parser):
 | 
					    def pytest_addoption(parser):
 | 
				
			||||||
        parser.addoption("--all", action="store_true",
 | 
					        parser.addoption("--all", action="store_true", help="run all combinations")
 | 
				
			||||||
            help="run all combinations")
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_generate_tests(metafunc):
 | 
					    def pytest_generate_tests(metafunc):
 | 
				
			||||||
        if 'param1' in metafunc.fixturenames:
 | 
					        if "param1" in metafunc.fixturenames:
 | 
				
			||||||
            if metafunc.config.getoption('all'):
 | 
					            if metafunc.config.getoption("all"):
 | 
				
			||||||
                end = 5
 | 
					                end = 5
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                end = 2
 | 
					                end = 2
 | 
				
			||||||
| 
						 | 
					@ -83,7 +89,9 @@ Running pytest with ``--collect-only`` will show the generated IDs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Numbers, strings, booleans and None will have their usual string representation
 | 
					Numbers, strings, booleans and None will have their usual string representation
 | 
				
			||||||
used in the test ID. For other objects, pytest will make a string based on
 | 
					used in the test ID. For other objects, pytest will make a string based on
 | 
				
			||||||
the argument name::
 | 
					the argument name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_time.py
 | 
					    # content of test_time.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,7 +120,7 @@ the argument name::
 | 
				
			||||||
    def idfn(val):
 | 
					    def idfn(val):
 | 
				
			||||||
        if isinstance(val, (datetime,)):
 | 
					        if isinstance(val, (datetime,)):
 | 
				
			||||||
            # note this wouldn't show any hours/minutes/seconds
 | 
					            # note this wouldn't show any hours/minutes/seconds
 | 
				
			||||||
            return val.strftime('%Y%m%d')
 | 
					            return val.strftime("%Y%m%d")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize("a,b,expected", testdata, ids=idfn)
 | 
					    @pytest.mark.parametrize("a,b,expected", testdata, ids=idfn)
 | 
				
			||||||
| 
						 | 
					@ -120,12 +128,18 @@ the argument name::
 | 
				
			||||||
        diff = a - b
 | 
					        diff = a - b
 | 
				
			||||||
        assert diff == expected
 | 
					        assert diff == expected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize("a,b,expected", [
 | 
					
 | 
				
			||||||
        pytest.param(datetime(2001, 12, 12), datetime(2001, 12, 11),
 | 
					    @pytest.mark.parametrize(
 | 
				
			||||||
                     timedelta(1), id='forward'),
 | 
					        "a,b,expected",
 | 
				
			||||||
        pytest.param(datetime(2001, 12, 11), datetime(2001, 12, 12),
 | 
					        [
 | 
				
			||||||
                     timedelta(-1), id='backward'),
 | 
					            pytest.param(
 | 
				
			||||||
    ])
 | 
					                datetime(2001, 12, 12), datetime(2001, 12, 11), timedelta(1), id="forward"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            pytest.param(
 | 
				
			||||||
 | 
					                datetime(2001, 12, 11), datetime(2001, 12, 12), timedelta(-1), id="backward"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    def test_timedistance_v3(a, b, expected):
 | 
					    def test_timedistance_v3(a, b, expected):
 | 
				
			||||||
        diff = a - b
 | 
					        diff = a - b
 | 
				
			||||||
        assert diff == expected
 | 
					        assert diff == expected
 | 
				
			||||||
| 
						 | 
					@ -171,10 +185,13 @@ A quick port of "testscenarios"
 | 
				
			||||||
Here is a quick port to run tests configured with `test scenarios`_,
 | 
					Here is a quick port to run tests configured with `test scenarios`_,
 | 
				
			||||||
an add-on from Robert Collins for the standard unittest framework. We
 | 
					an add-on from Robert Collins for the standard unittest framework. We
 | 
				
			||||||
only have to work a bit to construct the correct arguments for pytest's
 | 
					only have to work a bit to construct the correct arguments for pytest's
 | 
				
			||||||
:py:func:`Metafunc.parametrize`::
 | 
					:py:func:`Metafunc.parametrize`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_scenarios.py
 | 
					    # content of test_scenarios.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_generate_tests(metafunc):
 | 
					    def pytest_generate_tests(metafunc):
 | 
				
			||||||
        idlist = []
 | 
					        idlist = []
 | 
				
			||||||
        argvalues = []
 | 
					        argvalues = []
 | 
				
			||||||
| 
						 | 
					@ -182,13 +199,15 @@ only have to work a bit to construct the correct arguments for pytest's
 | 
				
			||||||
            idlist.append(scenario[0])
 | 
					            idlist.append(scenario[0])
 | 
				
			||||||
            items = scenario[1].items()
 | 
					            items = scenario[1].items()
 | 
				
			||||||
            argnames = [x[0] for x in items]
 | 
					            argnames = [x[0] for x in items]
 | 
				
			||||||
            argvalues.append(([x[1] for x in items]))
 | 
					            argvalues.append([x[1] for x in items])
 | 
				
			||||||
        metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class")
 | 
					        metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    scenario1 = ('basic', {'attribute': 'value'})
 | 
					 | 
				
			||||||
    scenario2 = ('advanced', {'attribute': 'value2'})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestSampleWithScenarios(object):
 | 
					    scenario1 = ("basic", {"attribute": "value"})
 | 
				
			||||||
 | 
					    scenario2 = ("advanced", {"attribute": "value2"})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class TestSampleWithScenarios:
 | 
				
			||||||
        scenarios = [scenario1, scenario2]
 | 
					        scenarios = [scenario1, scenario2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_demo1(self, attribute):
 | 
					        def test_demo1(self, attribute):
 | 
				
			||||||
| 
						 | 
					@ -244,11 +263,15 @@ The parametrization of test functions happens at collection
 | 
				
			||||||
time.  It is a good idea to setup expensive resources like DB
 | 
					time.  It is a good idea to setup expensive resources like DB
 | 
				
			||||||
connections or subprocess only when the actual test is run.
 | 
					connections or subprocess only when the actual test is run.
 | 
				
			||||||
Here is a simple example how you can achieve that, first
 | 
					Here is a simple example how you can achieve that, first
 | 
				
			||||||
the actual test requiring a ``db`` object::
 | 
					the actual test requiring a ``db`` object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_backends.py
 | 
					    # content of test_backends.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_db_initialized(db):
 | 
					    def test_db_initialized(db):
 | 
				
			||||||
        # a dummy test
 | 
					        # a dummy test
 | 
				
			||||||
        if db.__class__.__name__ == "DB2":
 | 
					        if db.__class__.__name__ == "DB2":
 | 
				
			||||||
| 
						 | 
					@ -256,20 +279,27 @@ the actual test requiring a ``db`` object::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We can now add a test configuration that generates two invocations of
 | 
					We can now add a test configuration that generates two invocations of
 | 
				
			||||||
the ``test_db_initialized`` function and also implements a factory that
 | 
					the ``test_db_initialized`` function and also implements a factory that
 | 
				
			||||||
creates a database object for the actual test invocations::
 | 
					creates a database object for the actual test invocations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_generate_tests(metafunc):
 | 
					 | 
				
			||||||
        if 'db' in metafunc.fixturenames:
 | 
					 | 
				
			||||||
            metafunc.parametrize("db", ['d1', 'd2'], indirect=True)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class DB1(object):
 | 
					    def pytest_generate_tests(metafunc):
 | 
				
			||||||
 | 
					        if "db" in metafunc.fixturenames:
 | 
				
			||||||
 | 
					            metafunc.parametrize("db", ["d1", "d2"], indirect=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class DB1:
 | 
				
			||||||
        "one database object"
 | 
					        "one database object"
 | 
				
			||||||
    class DB2(object):
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class DB2:
 | 
				
			||||||
        "alternative database object"
 | 
					        "alternative database object"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture
 | 
					    @pytest.fixture
 | 
				
			||||||
    def db(request):
 | 
					    def db(request):
 | 
				
			||||||
        if request.param == "d1":
 | 
					        if request.param == "d1":
 | 
				
			||||||
| 
						 | 
					@ -327,23 +357,29 @@ parameter on particular arguments. It can be done by passing list or tuple of
 | 
				
			||||||
arguments' names to ``indirect``. In the example below there is a function ``test_indirect`` which uses
 | 
					arguments' names to ``indirect``. In the example below there is a function ``test_indirect`` which uses
 | 
				
			||||||
two fixtures: ``x`` and ``y``. Here we give to indirect the list, which contains the name of the
 | 
					two fixtures: ``x`` and ``y``. Here we give to indirect the list, which contains the name of the
 | 
				
			||||||
fixture ``x``. The indirect parameter will be applied to this argument only, and the value ``a``
 | 
					fixture ``x``. The indirect parameter will be applied to this argument only, and the value ``a``
 | 
				
			||||||
will be passed to respective fixture function::
 | 
					will be passed to respective fixture function:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_indirect_list.py
 | 
					    # content of test_indirect_list.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    @pytest.fixture(scope='function')
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @pytest.fixture(scope="function")
 | 
				
			||||||
    def x(request):
 | 
					    def x(request):
 | 
				
			||||||
        return request.param * 3
 | 
					        return request.param * 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope='function')
 | 
					
 | 
				
			||||||
 | 
					    @pytest.fixture(scope="function")
 | 
				
			||||||
    def y(request):
 | 
					    def y(request):
 | 
				
			||||||
        return request.param * 2
 | 
					        return request.param * 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize('x, y', [('a', 'b')], indirect=['x'])
 | 
					
 | 
				
			||||||
    def test_indirect(x,y):
 | 
					    @pytest.mark.parametrize("x, y", [("a", "b")], indirect=["x"])
 | 
				
			||||||
        assert x == 'aaa'
 | 
					    def test_indirect(x, y):
 | 
				
			||||||
        assert y == 'b'
 | 
					        assert x == "aaa"
 | 
				
			||||||
 | 
					        assert y == "b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The result of this test will be successful:
 | 
					The result of this test will be successful:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -370,23 +406,28 @@ Parametrizing test methods through per-class configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Here is an example ``pytest_generate_tests`` function implementing a
 | 
					Here is an example ``pytest_generate_tests`` function implementing a
 | 
				
			||||||
parametrization scheme similar to Michael Foord's `unittest
 | 
					parametrization scheme similar to Michael Foord's `unittest
 | 
				
			||||||
parametrizer`_ but in a lot less code::
 | 
					parametrizer`_ but in a lot less code:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of ./test_parametrize.py
 | 
					    # content of ./test_parametrize.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_generate_tests(metafunc):
 | 
					    def pytest_generate_tests(metafunc):
 | 
				
			||||||
        # called once per each test function
 | 
					        # called once per each test function
 | 
				
			||||||
        funcarglist = metafunc.cls.params[metafunc.function.__name__]
 | 
					        funcarglist = metafunc.cls.params[metafunc.function.__name__]
 | 
				
			||||||
        argnames = sorted(funcarglist[0])
 | 
					        argnames = sorted(funcarglist[0])
 | 
				
			||||||
        metafunc.parametrize(argnames, [[funcargs[name] for name in argnames]
 | 
					        metafunc.parametrize(
 | 
				
			||||||
                for funcargs in funcarglist])
 | 
					            argnames, [[funcargs[name] for name in argnames] for funcargs in funcarglist]
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestClass(object):
 | 
					
 | 
				
			||||||
 | 
					    class TestClass:
 | 
				
			||||||
        # a map specifying multiple argument sets for a test method
 | 
					        # a map specifying multiple argument sets for a test method
 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            'test_equals': [dict(a=1, b=2), dict(a=3, b=3), ],
 | 
					            "test_equals": [dict(a=1, b=2), dict(a=3, b=3)],
 | 
				
			||||||
            'test_zerodivision': [dict(a=1, b=0), ],
 | 
					            "test_zerodivision": [dict(a=1, b=0)],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_equals(self, a, b):
 | 
					        def test_equals(self, a, b):
 | 
				
			||||||
| 
						 | 
					@ -447,36 +488,47 @@ If you want to compare the outcomes of several implementations of a given
 | 
				
			||||||
API, you can write test functions that receive the already imported implementations
 | 
					API, you can write test functions that receive the already imported implementations
 | 
				
			||||||
and get skipped in case the implementation is not importable/available.  Let's
 | 
					and get skipped in case the implementation is not importable/available.  Let's
 | 
				
			||||||
say we have a "base" implementation and the other (possibly optimized ones)
 | 
					say we have a "base" implementation and the other (possibly optimized ones)
 | 
				
			||||||
need to provide similar results::
 | 
					need to provide similar results:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="session")
 | 
					    @pytest.fixture(scope="session")
 | 
				
			||||||
    def basemod(request):
 | 
					    def basemod(request):
 | 
				
			||||||
        return pytest.importorskip("base")
 | 
					        return pytest.importorskip("base")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="session", params=["opt1", "opt2"])
 | 
					    @pytest.fixture(scope="session", params=["opt1", "opt2"])
 | 
				
			||||||
    def optmod(request):
 | 
					    def optmod(request):
 | 
				
			||||||
        return pytest.importorskip(request.param)
 | 
					        return pytest.importorskip(request.param)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
And then a base implementation of a simple function::
 | 
					And then a base implementation of a simple function:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of base.py
 | 
					    # content of base.py
 | 
				
			||||||
    def func1():
 | 
					    def func1():
 | 
				
			||||||
        return 1
 | 
					        return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
And an optimized version::
 | 
					And an optimized version:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of opt1.py
 | 
					    # content of opt1.py
 | 
				
			||||||
    def func1():
 | 
					    def func1():
 | 
				
			||||||
        return 1.0001
 | 
					        return 1.0001
 | 
				
			||||||
 | 
					
 | 
				
			||||||
And finally a little test module::
 | 
					And finally a little test module:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_module.py
 | 
					    # content of test_module.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_func1(basemod, optmod):
 | 
					    def test_func1(basemod, optmod):
 | 
				
			||||||
        assert round(basemod.func1(), 3) == round(optmod.func1(), 3)
 | 
					        assert round(basemod.func1(), 3) == round(optmod.func1(), 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -579,22 +631,28 @@ Use :func:`pytest.raises` with the
 | 
				
			||||||
in which some tests raise exceptions and others do not.
 | 
					in which some tests raise exceptions and others do not.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is helpful to define a no-op context manager ``does_not_raise`` to serve
 | 
					It is helpful to define a no-op context manager ``does_not_raise`` to serve
 | 
				
			||||||
as a complement to ``raises``. For example::
 | 
					as a complement to ``raises``. For example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from contextlib import contextmanager
 | 
					    from contextlib import contextmanager
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @contextmanager
 | 
					    @contextmanager
 | 
				
			||||||
    def does_not_raise():
 | 
					    def does_not_raise():
 | 
				
			||||||
        yield
 | 
					        yield
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.parametrize('example_input,expectation', [
 | 
					    @pytest.mark.parametrize(
 | 
				
			||||||
        (3, does_not_raise()),
 | 
					        "example_input,expectation",
 | 
				
			||||||
        (2, does_not_raise()),
 | 
					        [
 | 
				
			||||||
        (1, does_not_raise()),
 | 
					            (3, does_not_raise()),
 | 
				
			||||||
        (0, pytest.raises(ZeroDivisionError)),
 | 
					            (2, does_not_raise()),
 | 
				
			||||||
    ])
 | 
					            (1, does_not_raise()),
 | 
				
			||||||
 | 
					            (0, pytest.raises(ZeroDivisionError)),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
    def test_division(example_input, expectation):
 | 
					    def test_division(example_input, expectation):
 | 
				
			||||||
        """Test how much I know division."""
 | 
					        """Test how much I know division."""
 | 
				
			||||||
        with expectation:
 | 
					        with expectation:
 | 
				
			||||||
| 
						 | 
					@ -604,14 +662,20 @@ In the example above, the first three test cases should run unexceptionally,
 | 
				
			||||||
while the fourth should raise ``ZeroDivisionError``.
 | 
					while the fourth should raise ``ZeroDivisionError``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you're only supporting Python 3.7+, you can simply use ``nullcontext``
 | 
					If you're only supporting Python 3.7+, you can simply use ``nullcontext``
 | 
				
			||||||
to define ``does_not_raise``::
 | 
					to define ``does_not_raise``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from contextlib import nullcontext as does_not_raise
 | 
					    from contextlib import nullcontext as does_not_raise
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Or, if you're supporting Python 3.3+ you can use::
 | 
					Or, if you're supporting Python 3.3+ you can use:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from contextlib import ExitStack as does_not_raise
 | 
					    from contextlib import ExitStack as does_not_raise
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Or, if desired, you can ``pip install contextlib2`` and use::
 | 
					Or, if desired, you can ``pip install contextlib2`` and use:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from contextlib2 import ExitStack as does_not_raise
 | 
					    from contextlib2 import ExitStack as does_not_raise
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,12 +131,15 @@ Here is an example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This would make ``pytest`` look for tests in files that match the ``check_*
 | 
					This would make ``pytest`` look for tests in files that match the ``check_*
 | 
				
			||||||
.py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods
 | 
					.py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods
 | 
				
			||||||
that match ``*_check``. For example, if we have::
 | 
					that match ``*_check``. For example, if we have:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of check_myapp.py
 | 
					    # content of check_myapp.py
 | 
				
			||||||
    class CheckMyApp(object):
 | 
					    class CheckMyApp:
 | 
				
			||||||
        def simple_check(self):
 | 
					        def simple_check(self):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def complex_check(self):
 | 
					        def complex_check(self):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +241,9 @@ You can easily instruct ``pytest`` to discover tests from every Python file:
 | 
				
			||||||
However, many projects will have a ``setup.py`` which they don't want to be
 | 
					However, many projects will have a ``setup.py`` which they don't want to be
 | 
				
			||||||
imported. Moreover, there may files only importable by a specific python
 | 
					imported. Moreover, there may files only importable by a specific python
 | 
				
			||||||
version. For such cases you can dynamically define files to be ignored by
 | 
					version. For such cases you can dynamically define files to be ignored by
 | 
				
			||||||
listing them in a ``conftest.py`` file::
 | 
					listing them in a ``conftest.py`` file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import sys
 | 
					    import sys
 | 
				
			||||||
| 
						 | 
					@ -247,7 +252,9 @@ listing them in a ``conftest.py`` file::
 | 
				
			||||||
    if sys.version_info[0] > 2:
 | 
					    if sys.version_info[0] > 2:
 | 
				
			||||||
        collect_ignore.append("pkg/module_py2.py")
 | 
					        collect_ignore.append("pkg/module_py2.py")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
and then if you have a module file like this::
 | 
					and then if you have a module file like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of pkg/module_py2.py
 | 
					    # content of pkg/module_py2.py
 | 
				
			||||||
    def test_only_on_python2():
 | 
					    def test_only_on_python2():
 | 
				
			||||||
| 
						 | 
					@ -256,10 +263,12 @@ and then if you have a module file like this::
 | 
				
			||||||
        except Exception, e:
 | 
					        except Exception, e:
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
and a ``setup.py`` dummy file like this::
 | 
					and a ``setup.py`` dummy file like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of setup.py
 | 
					    # content of setup.py
 | 
				
			||||||
    0/0  # will raise exception if imported
 | 
					    0 / 0  # will raise exception if imported
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you run with a Python 2 interpreter then you will find the one test and will
 | 
					If you run with a Python 2 interpreter then you will find the one test and will
 | 
				
			||||||
leave out the ``setup.py`` file:
 | 
					leave out the ``setup.py`` file:
 | 
				
			||||||
| 
						 | 
					@ -295,7 +304,9 @@ patterns to ``collect_ignore_glob``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The following example ``conftest.py`` ignores the file ``setup.py`` and in
 | 
					The following example ``conftest.py`` ignores the file ``setup.py`` and in
 | 
				
			||||||
addition all files that end with ``*_py2.py`` when executed with a Python 3
 | 
					addition all files that end with ``*_py2.py`` when executed with a Python 3
 | 
				
			||||||
interpreter::
 | 
					interpreter:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import sys
 | 
					    import sys
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,7 @@ Example:
 | 
				
			||||||
    def checkconfig(x):
 | 
					    def checkconfig(x):
 | 
				
			||||||
        __tracebackhide__ = True
 | 
					        __tracebackhide__ = True
 | 
				
			||||||
        if not hasattr(x, "config"):
 | 
					        if not hasattr(x, "config"):
 | 
				
			||||||
            pytest.fail("not configured: %s" % (x,))
 | 
					            pytest.fail("not configured: {}".format(x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_something():
 | 
					    def test_something():
 | 
				
			||||||
| 
						 | 
					@ -280,7 +280,7 @@ this to make sure unexpected exception types aren't hidden:
 | 
				
			||||||
    def checkconfig(x):
 | 
					    def checkconfig(x):
 | 
				
			||||||
        __tracebackhide__ = operator.methodcaller("errisinstance", ConfigException)
 | 
					        __tracebackhide__ = operator.methodcaller("errisinstance", ConfigException)
 | 
				
			||||||
        if not hasattr(x, "config"):
 | 
					        if not hasattr(x, "config"):
 | 
				
			||||||
            raise ConfigException("not configured: %s" % (x,))
 | 
					            raise ConfigException("not configured: {}".format(x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_something():
 | 
					    def test_something():
 | 
				
			||||||
| 
						 | 
					@ -491,7 +491,7 @@ tests in a class.  Here is a test module example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.incremental
 | 
					    @pytest.mark.incremental
 | 
				
			||||||
    class TestUserHandling(object):
 | 
					    class TestUserHandling:
 | 
				
			||||||
        def test_login(self):
 | 
					        def test_login(self):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -556,7 +556,7 @@ Here is an example for making a ``db`` fixture available in a directory:
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class DB(object):
 | 
					    class DB:
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,30 +5,36 @@ A session-scoped fixture effectively has access to all
 | 
				
			||||||
collected test items.  Here is an example of a fixture
 | 
					collected test items.  Here is an example of a fixture
 | 
				
			||||||
function which walks all collected tests and looks
 | 
					function which walks all collected tests and looks
 | 
				
			||||||
if their test class defines a ``callme`` method and
 | 
					if their test class defines a ``callme`` method and
 | 
				
			||||||
calls it::
 | 
					calls it:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="session", autouse=True)
 | 
					    @pytest.fixture(scope="session", autouse=True)
 | 
				
			||||||
    def callattr_ahead_of_alltests(request):
 | 
					    def callattr_ahead_of_alltests(request):
 | 
				
			||||||
        print("callattr_ahead_of_alltests called")
 | 
					        print("callattr_ahead_of_alltests called")
 | 
				
			||||||
        seen = set([None])
 | 
					        seen = {None}
 | 
				
			||||||
        session = request.node
 | 
					        session = request.node
 | 
				
			||||||
        for item in session.items:
 | 
					        for item in session.items:
 | 
				
			||||||
            cls = item.getparent(pytest.Class)
 | 
					            cls = item.getparent(pytest.Class)
 | 
				
			||||||
            if cls not in seen:
 | 
					            if cls not in seen:
 | 
				
			||||||
                if hasattr(cls.obj, "callme"):
 | 
					                if hasattr(cls.obj, "callme"):
 | 
				
			||||||
                   cls.obj.callme()
 | 
					                    cls.obj.callme()
 | 
				
			||||||
                seen.add(cls)
 | 
					                seen.add(cls)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test classes may now define a ``callme`` method which
 | 
					test classes may now define a ``callme`` method which
 | 
				
			||||||
will be called ahead of running any tests::
 | 
					will be called ahead of running any tests:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_module.py
 | 
					    # content of test_module.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestHello(object):
 | 
					
 | 
				
			||||||
 | 
					    class TestHello:
 | 
				
			||||||
        @classmethod
 | 
					        @classmethod
 | 
				
			||||||
        def callme(cls):
 | 
					        def callme(cls):
 | 
				
			||||||
            print("callme called!")
 | 
					            print("callme called!")
 | 
				
			||||||
| 
						 | 
					@ -39,16 +45,20 @@ will be called ahead of running any tests::
 | 
				
			||||||
        def test_method2(self):
 | 
					        def test_method2(self):
 | 
				
			||||||
            print("test_method1 called")
 | 
					            print("test_method1 called")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestOther(object):
 | 
					
 | 
				
			||||||
 | 
					    class TestOther:
 | 
				
			||||||
        @classmethod
 | 
					        @classmethod
 | 
				
			||||||
        def callme(cls):
 | 
					        def callme(cls):
 | 
				
			||||||
            print("callme other called")
 | 
					            print("callme other called")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_other(self):
 | 
					        def test_other(self):
 | 
				
			||||||
            print("test other")
 | 
					            print("test other")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # works with unittest as well ...
 | 
					    # works with unittest as well ...
 | 
				
			||||||
    import unittest
 | 
					    import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class SomeTest(unittest.TestCase):
 | 
					    class SomeTest(unittest.TestCase):
 | 
				
			||||||
        @classmethod
 | 
					        @classmethod
 | 
				
			||||||
        def callme(self):
 | 
					        def callme(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,9 @@ Running an existing test suite with pytest
 | 
				
			||||||
Say you want to contribute to an existing repository somewhere.
 | 
					Say you want to contribute to an existing repository somewhere.
 | 
				
			||||||
After pulling the code into your development space using some
 | 
					After pulling the code into your development space using some
 | 
				
			||||||
flavor of version control and (optionally) setting up a virtualenv
 | 
					flavor of version control and (optionally) setting up a virtualenv
 | 
				
			||||||
you will want to run::
 | 
					you will want to run:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cd <repository>
 | 
					    cd <repository>
 | 
				
			||||||
    pip install -e .  # Environment dependent alternatives include
 | 
					    pip install -e .  # Environment dependent alternatives include
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,20 +49,25 @@ argument. For each argument name, a fixture function with that name provides
 | 
				
			||||||
the fixture object.  Fixture functions are registered by marking them with
 | 
					the fixture object.  Fixture functions are registered by marking them with
 | 
				
			||||||
:py:func:`@pytest.fixture <_pytest.python.fixture>`.  Let's look at a simple
 | 
					:py:func:`@pytest.fixture <_pytest.python.fixture>`.  Let's look at a simple
 | 
				
			||||||
self-contained test module containing a fixture and a test function
 | 
					self-contained test module containing a fixture and a test function
 | 
				
			||||||
using it::
 | 
					using it:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of ./test_smtpsimple.py
 | 
					    # content of ./test_smtpsimple.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture
 | 
					    @pytest.fixture
 | 
				
			||||||
    def smtp_connection():
 | 
					    def smtp_connection():
 | 
				
			||||||
        import smtplib
 | 
					        import smtplib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
 | 
					        return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_ehlo(smtp_connection):
 | 
					    def test_ehlo(smtp_connection):
 | 
				
			||||||
        response, msg = smtp_connection.ehlo()
 | 
					        response, msg = smtp_connection.ehlo()
 | 
				
			||||||
        assert response == 250
 | 
					        assert response == 250
 | 
				
			||||||
        assert 0 # for demo purposes
 | 
					        assert 0  # for demo purposes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Here, the ``test_ehlo`` needs the ``smtp_connection`` fixture value.  pytest
 | 
					Here, the ``test_ehlo`` needs the ``smtp_connection`` fixture value.  pytest
 | 
				
			||||||
will discover and call the :py:func:`@pytest.fixture <_pytest.python.fixture>`
 | 
					will discover and call the :py:func:`@pytest.fixture <_pytest.python.fixture>`
 | 
				
			||||||
| 
						 | 
					@ -180,12 +185,15 @@ Possible values for ``scope`` are: ``function``, ``class``, ``module``, ``packag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The next example puts the fixture function into a separate ``conftest.py`` file
 | 
					The next example puts the fixture function into a separate ``conftest.py`` file
 | 
				
			||||||
so that tests from multiple test modules in the directory can
 | 
					so that tests from multiple test modules in the directory can
 | 
				
			||||||
access the fixture function::
 | 
					access the fixture function:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    import smtplib
 | 
					    import smtplib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module")
 | 
					    @pytest.fixture(scope="module")
 | 
				
			||||||
    def smtp_connection():
 | 
					    def smtp_connection():
 | 
				
			||||||
        return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
 | 
					        return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
 | 
				
			||||||
| 
						 | 
					@ -193,16 +201,20 @@ access the fixture function::
 | 
				
			||||||
The name of the fixture again is ``smtp_connection`` and you can access its
 | 
					The name of the fixture again is ``smtp_connection`` and you can access its
 | 
				
			||||||
result by listing the name ``smtp_connection`` as an input parameter in any
 | 
					result by listing the name ``smtp_connection`` as an input parameter in any
 | 
				
			||||||
test or fixture function (in or below the directory where ``conftest.py`` is
 | 
					test or fixture function (in or below the directory where ``conftest.py`` is
 | 
				
			||||||
located)::
 | 
					located):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_module.py
 | 
					    # content of test_module.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_ehlo(smtp_connection):
 | 
					    def test_ehlo(smtp_connection):
 | 
				
			||||||
        response, msg = smtp_connection.ehlo()
 | 
					        response, msg = smtp_connection.ehlo()
 | 
				
			||||||
        assert response == 250
 | 
					        assert response == 250
 | 
				
			||||||
        assert b"smtp.gmail.com" in msg
 | 
					        assert b"smtp.gmail.com" in msg
 | 
				
			||||||
        assert 0  # for demo purposes
 | 
					        assert 0  # for demo purposes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_noop(smtp_connection):
 | 
					    def test_noop(smtp_connection):
 | 
				
			||||||
        response, msg = smtp_connection.noop()
 | 
					        response, msg = smtp_connection.noop()
 | 
				
			||||||
        assert response == 250
 | 
					        assert response == 250
 | 
				
			||||||
| 
						 | 
					@ -477,18 +489,21 @@ Fixtures can introspect the requesting test context
 | 
				
			||||||
Fixture functions can accept the :py:class:`request <FixtureRequest>` object
 | 
					Fixture functions can accept the :py:class:`request <FixtureRequest>` object
 | 
				
			||||||
to introspect the "requesting" test function, class or module context.
 | 
					to introspect the "requesting" test function, class or module context.
 | 
				
			||||||
Further extending the previous ``smtp_connection`` fixture example, let's
 | 
					Further extending the previous ``smtp_connection`` fixture example, let's
 | 
				
			||||||
read an optional server URL from the test module which uses our fixture::
 | 
					read an optional server URL from the test module which uses our fixture:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    import smtplib
 | 
					    import smtplib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module")
 | 
					    @pytest.fixture(scope="module")
 | 
				
			||||||
    def smtp_connection(request):
 | 
					    def smtp_connection(request):
 | 
				
			||||||
        server = getattr(request.module, "smtpserver", "smtp.gmail.com")
 | 
					        server = getattr(request.module, "smtpserver", "smtp.gmail.com")
 | 
				
			||||||
        smtp_connection = smtplib.SMTP(server, 587, timeout=5)
 | 
					        smtp_connection = smtplib.SMTP(server, 587, timeout=5)
 | 
				
			||||||
        yield smtp_connection
 | 
					        yield smtp_connection
 | 
				
			||||||
        print("finalizing %s (%s)" % (smtp_connection, server))
 | 
					        print("finalizing {} ({})".format(smtp_connection, server))
 | 
				
			||||||
        smtp_connection.close()
 | 
					        smtp_connection.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We use the ``request.module`` attribute to optionally obtain an
 | 
					We use the ``request.module`` attribute to optionally obtain an
 | 
				
			||||||
| 
						 | 
					@ -503,12 +518,15 @@ again, nothing much has changed:
 | 
				
			||||||
    2 failed in 0.12 seconds
 | 
					    2 failed in 0.12 seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's quickly create another test module that actually sets the
 | 
					Let's quickly create another test module that actually sets the
 | 
				
			||||||
server URL in its module namespace::
 | 
					server URL in its module namespace:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_anothersmtp.py
 | 
					    # content of test_anothersmtp.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    smtpserver = "mail.python.org"  # will be read by smtp fixture
 | 
					    smtpserver = "mail.python.org"  # will be read by smtp fixture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_showhelo(smtp_connection):
 | 
					    def test_showhelo(smtp_connection):
 | 
				
			||||||
        assert 0, smtp_connection.helo()
 | 
					        assert 0, smtp_connection.helo()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -540,16 +558,14 @@ of a fixture is needed multiple times in a single test. Instead of returning
 | 
				
			||||||
data directly, the fixture instead returns a function which generates the data.
 | 
					data directly, the fixture instead returns a function which generates the data.
 | 
				
			||||||
This function can then be called multiple times in the test.
 | 
					This function can then be called multiple times in the test.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Factories can have parameters as needed::
 | 
					Factories can have parameters as needed:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture
 | 
					    @pytest.fixture
 | 
				
			||||||
    def make_customer_record():
 | 
					    def make_customer_record():
 | 
				
			||||||
 | 
					 | 
				
			||||||
        def _make_customer_record(name):
 | 
					        def _make_customer_record(name):
 | 
				
			||||||
            return {
 | 
					            return {"name": name, "orders": []}
 | 
				
			||||||
                "name": name,
 | 
					 | 
				
			||||||
                "orders": []
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return _make_customer_record
 | 
					        return _make_customer_record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -559,7 +575,9 @@ Factories can have parameters as needed::
 | 
				
			||||||
        customer_2 = make_customer_record("Mike")
 | 
					        customer_2 = make_customer_record("Mike")
 | 
				
			||||||
        customer_3 = make_customer_record("Meredith")
 | 
					        customer_3 = make_customer_record("Meredith")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If the data created by the factory requires managing, the fixture can take care of that::
 | 
					If the data created by the factory requires managing, the fixture can take care of that:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture
 | 
					    @pytest.fixture
 | 
				
			||||||
    def make_customer_record():
 | 
					    def make_customer_record():
 | 
				
			||||||
| 
						 | 
					@ -598,14 +616,16 @@ configured in multiple ways.
 | 
				
			||||||
Extending the previous example, we can flag the fixture to create two
 | 
					Extending the previous example, we can flag the fixture to create two
 | 
				
			||||||
``smtp_connection`` fixture instances which will cause all tests using the fixture
 | 
					``smtp_connection`` fixture instances which will cause all tests using the fixture
 | 
				
			||||||
to run twice.  The fixture function gets access to each parameter
 | 
					to run twice.  The fixture function gets access to each parameter
 | 
				
			||||||
through the special :py:class:`request <FixtureRequest>` object::
 | 
					through the special :py:class:`request <FixtureRequest>` object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    import smtplib
 | 
					    import smtplib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module",
 | 
					
 | 
				
			||||||
                    params=["smtp.gmail.com", "mail.python.org"])
 | 
					    @pytest.fixture(scope="module", params=["smtp.gmail.com", "mail.python.org"])
 | 
				
			||||||
    def smtp_connection(request):
 | 
					    def smtp_connection(request):
 | 
				
			||||||
        smtp_connection = smtplib.SMTP(request.param, 587, timeout=5)
 | 
					        smtp_connection = smtplib.SMTP(request.param, 587, timeout=5)
 | 
				
			||||||
        yield smtp_connection
 | 
					        yield smtp_connection
 | 
				
			||||||
| 
						 | 
					@ -690,28 +710,35 @@ Numbers, strings, booleans and None will have their usual string
 | 
				
			||||||
representation used in the test ID. For other objects, pytest will
 | 
					representation used in the test ID. For other objects, pytest will
 | 
				
			||||||
make a string based on the argument name.  It is possible to customise
 | 
					make a string based on the argument name.  It is possible to customise
 | 
				
			||||||
the string used in a test ID for a certain fixture value by using the
 | 
					the string used in a test ID for a certain fixture value by using the
 | 
				
			||||||
``ids`` keyword argument::
 | 
					``ids`` keyword argument:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   # content of test_ids.py
 | 
					   # content of test_ids.py
 | 
				
			||||||
   import pytest
 | 
					   import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   @pytest.fixture(params=[0, 1], ids=["spam", "ham"])
 | 
					   @pytest.fixture(params=[0, 1], ids=["spam", "ham"])
 | 
				
			||||||
   def a(request):
 | 
					   def a(request):
 | 
				
			||||||
       return request.param
 | 
					       return request.param
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   def test_a(a):
 | 
					   def test_a(a):
 | 
				
			||||||
       pass
 | 
					       pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   def idfn(fixture_value):
 | 
					   def idfn(fixture_value):
 | 
				
			||||||
       if fixture_value == 0:
 | 
					       if fixture_value == 0:
 | 
				
			||||||
           return "eggs"
 | 
					           return "eggs"
 | 
				
			||||||
       else:
 | 
					       else:
 | 
				
			||||||
           return None
 | 
					           return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   @pytest.fixture(params=[0, 1], ids=idfn)
 | 
					   @pytest.fixture(params=[0, 1], ids=idfn)
 | 
				
			||||||
   def b(request):
 | 
					   def b(request):
 | 
				
			||||||
       return request.param
 | 
					       return request.param
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   def test_b(b):
 | 
					   def test_b(b):
 | 
				
			||||||
       pass
 | 
					       pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -754,14 +781,19 @@ Using marks with parametrized fixtures
 | 
				
			||||||
:func:`pytest.param` can be used to apply marks in values sets of parametrized fixtures in the same way
 | 
					:func:`pytest.param` can be used to apply marks in values sets of parametrized fixtures in the same way
 | 
				
			||||||
that they can be used with :ref:`@pytest.mark.parametrize <@pytest.mark.parametrize>`.
 | 
					that they can be used with :ref:`@pytest.mark.parametrize <@pytest.mark.parametrize>`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example::
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_fixture_marks.py
 | 
					    # content of test_fixture_marks.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(params=[0, 1, pytest.param(2, marks=pytest.mark.skip)])
 | 
					    @pytest.fixture(params=[0, 1, pytest.param(2, marks=pytest.mark.skip)])
 | 
				
			||||||
    def data_set(request):
 | 
					    def data_set(request):
 | 
				
			||||||
        return request.param
 | 
					        return request.param
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_data(data_set):
 | 
					    def test_data(data_set):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -792,20 +824,25 @@ can use other fixtures themselves.  This contributes to a modular design
 | 
				
			||||||
of your fixtures and allows re-use of framework-specific fixtures across
 | 
					of your fixtures and allows re-use of framework-specific fixtures across
 | 
				
			||||||
many projects.  As a simple example, we can extend the previous example
 | 
					many projects.  As a simple example, we can extend the previous example
 | 
				
			||||||
and instantiate an object ``app`` where we stick the already defined
 | 
					and instantiate an object ``app`` where we stick the already defined
 | 
				
			||||||
``smtp_connection`` resource into it::
 | 
					``smtp_connection`` resource into it:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_appsetup.py
 | 
					    # content of test_appsetup.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class App(object):
 | 
					
 | 
				
			||||||
 | 
					    class App:
 | 
				
			||||||
        def __init__(self, smtp_connection):
 | 
					        def __init__(self, smtp_connection):
 | 
				
			||||||
            self.smtp_connection = smtp_connection
 | 
					            self.smtp_connection = smtp_connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module")
 | 
					    @pytest.fixture(scope="module")
 | 
				
			||||||
    def app(smtp_connection):
 | 
					    def app(smtp_connection):
 | 
				
			||||||
        return App(smtp_connection)
 | 
					        return App(smtp_connection)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_smtp_connection_exists(app):
 | 
					    def test_smtp_connection_exists(app):
 | 
				
			||||||
        assert app.smtp_connection
 | 
					        assert app.smtp_connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -854,11 +891,14 @@ this eases testing of applications which create and use global state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The following example uses two parametrized fixtures, one of which is
 | 
					The following example uses two parametrized fixtures, one of which is
 | 
				
			||||||
scoped on a per-module basis, and all the functions perform ``print`` calls
 | 
					scoped on a per-module basis, and all the functions perform ``print`` calls
 | 
				
			||||||
to show the setup/teardown flow::
 | 
					to show the setup/teardown flow:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_module.py
 | 
					    # content of test_module.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module", params=["mod1", "mod2"])
 | 
					    @pytest.fixture(scope="module", params=["mod1", "mod2"])
 | 
				
			||||||
    def modarg(request):
 | 
					    def modarg(request):
 | 
				
			||||||
        param = request.param
 | 
					        param = request.param
 | 
				
			||||||
| 
						 | 
					@ -866,19 +906,25 @@ to show the setup/teardown flow::
 | 
				
			||||||
        yield param
 | 
					        yield param
 | 
				
			||||||
        print("  TEARDOWN modarg %s" % param)
 | 
					        print("  TEARDOWN modarg %s" % param)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="function", params=[1,2])
 | 
					
 | 
				
			||||||
 | 
					    @pytest.fixture(scope="function", params=[1, 2])
 | 
				
			||||||
    def otherarg(request):
 | 
					    def otherarg(request):
 | 
				
			||||||
        param = request.param
 | 
					        param = request.param
 | 
				
			||||||
        print("  SETUP otherarg %s" % param)
 | 
					        print("  SETUP otherarg %s" % param)
 | 
				
			||||||
        yield param
 | 
					        yield param
 | 
				
			||||||
        print("  TEARDOWN otherarg %s" % param)
 | 
					        print("  TEARDOWN otherarg %s" % param)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_0(otherarg):
 | 
					    def test_0(otherarg):
 | 
				
			||||||
        print("  RUN test0 with otherarg %s" % otherarg)
 | 
					        print("  RUN test0 with otherarg %s" % otherarg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_1(modarg):
 | 
					    def test_1(modarg):
 | 
				
			||||||
        print("  RUN test1 with modarg %s" % modarg)
 | 
					        print("  RUN test1 with modarg %s" % modarg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_2(otherarg, modarg):
 | 
					    def test_2(otherarg, modarg):
 | 
				
			||||||
        print("  RUN test2 with otherarg %s and modarg %s" % (otherarg, modarg))
 | 
					        print("  RUN test2 with otherarg {} and modarg {}".format(otherarg, modarg))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's run the tests in verbose mode and with looking at the print-output:
 | 
					Let's run the tests in verbose mode and with looking at the print-output:
 | 
				
			||||||
| 
						 | 
					@ -953,7 +999,9 @@ current working directory but otherwise do not care for the concrete
 | 
				
			||||||
directory.  Here is how you can use the standard `tempfile
 | 
					directory.  Here is how you can use the standard `tempfile
 | 
				
			||||||
<http://docs.python.org/library/tempfile.html>`_ and pytest fixtures to
 | 
					<http://docs.python.org/library/tempfile.html>`_ and pytest fixtures to
 | 
				
			||||||
achieve it.  We separate the creation of the fixture into a conftest.py
 | 
					achieve it.  We separate the creation of the fixture into a conftest.py
 | 
				
			||||||
file::
 | 
					file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -961,19 +1009,23 @@ file::
 | 
				
			||||||
    import tempfile
 | 
					    import tempfile
 | 
				
			||||||
    import os
 | 
					    import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture()
 | 
					    @pytest.fixture()
 | 
				
			||||||
    def cleandir():
 | 
					    def cleandir():
 | 
				
			||||||
        newpath = tempfile.mkdtemp()
 | 
					        newpath = tempfile.mkdtemp()
 | 
				
			||||||
        os.chdir(newpath)
 | 
					        os.chdir(newpath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
and declare its use in a test module via a ``usefixtures`` marker::
 | 
					and declare its use in a test module via a ``usefixtures`` marker:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_setenv.py
 | 
					    # content of test_setenv.py
 | 
				
			||||||
    import os
 | 
					    import os
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.usefixtures("cleandir")
 | 
					    @pytest.mark.usefixtures("cleandir")
 | 
				
			||||||
    class TestDirectoryInit(object):
 | 
					    class TestDirectoryInit:
 | 
				
			||||||
        def test_cwd_starts_empty(self):
 | 
					        def test_cwd_starts_empty(self):
 | 
				
			||||||
            assert os.listdir(os.getcwd()) == []
 | 
					            assert os.listdir(os.getcwd()) == []
 | 
				
			||||||
            with open("myfile", "w") as f:
 | 
					            with open("myfile", "w") as f:
 | 
				
			||||||
| 
						 | 
					@ -1050,25 +1102,32 @@ without declaring a function argument explicitly or a `usefixtures`_ decorator.
 | 
				
			||||||
As a practical example, suppose we have a database fixture which has a
 | 
					As a practical example, suppose we have a database fixture which has a
 | 
				
			||||||
begin/rollback/commit architecture and we want to automatically surround
 | 
					begin/rollback/commit architecture and we want to automatically surround
 | 
				
			||||||
each test method by a transaction and a rollback.  Here is a dummy
 | 
					each test method by a transaction and a rollback.  Here is a dummy
 | 
				
			||||||
self-contained implementation of this idea::
 | 
					self-contained implementation of this idea:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_db_transact.py
 | 
					    # content of test_db_transact.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class DB(object):
 | 
					
 | 
				
			||||||
 | 
					    class DB:
 | 
				
			||||||
        def __init__(self):
 | 
					        def __init__(self):
 | 
				
			||||||
            self.intransaction = []
 | 
					            self.intransaction = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def begin(self, name):
 | 
					        def begin(self, name):
 | 
				
			||||||
            self.intransaction.append(name)
 | 
					            self.intransaction.append(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def rollback(self):
 | 
					        def rollback(self):
 | 
				
			||||||
            self.intransaction.pop()
 | 
					            self.intransaction.pop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="module")
 | 
					    @pytest.fixture(scope="module")
 | 
				
			||||||
    def db():
 | 
					    def db():
 | 
				
			||||||
        return DB()
 | 
					        return DB()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestClass(object):
 | 
					
 | 
				
			||||||
 | 
					    class TestClass:
 | 
				
			||||||
        @pytest.fixture(autouse=True)
 | 
					        @pytest.fixture(autouse=True)
 | 
				
			||||||
        def transact(self, request, db):
 | 
					        def transact(self, request, db):
 | 
				
			||||||
            db.begin(request.function.__name__)
 | 
					            db.begin(request.function.__name__)
 | 
				
			||||||
| 
						 | 
					@ -1116,7 +1175,9 @@ Here is how autouse fixtures work in other scopes:
 | 
				
			||||||
Note that the above ``transact`` fixture may very well be a fixture that
 | 
					Note that the above ``transact`` fixture may very well be a fixture that
 | 
				
			||||||
you want to make available in your project without having it generally
 | 
					you want to make available in your project without having it generally
 | 
				
			||||||
active.  The canonical way to do that is to put the transact definition
 | 
					active.  The canonical way to do that is to put the transact definition
 | 
				
			||||||
into a conftest.py file **without** using ``autouse``::
 | 
					into a conftest.py file **without** using ``autouse``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    @pytest.fixture
 | 
					    @pytest.fixture
 | 
				
			||||||
| 
						 | 
					@ -1125,10 +1186,12 @@ into a conftest.py file **without** using ``autouse``::
 | 
				
			||||||
        yield
 | 
					        yield
 | 
				
			||||||
        db.rollback()
 | 
					        db.rollback()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
and then e.g. have a TestClass using it by declaring the need::
 | 
					and then e.g. have a TestClass using it by declaring the need:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.usefixtures("transact")
 | 
					    @pytest.mark.usefixtures("transact")
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        def test_method1(self):
 | 
					        def test_method1(self):
 | 
				
			||||||
            ...
 | 
					            ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,19 +21,23 @@ funcarg for a test function is required.  If a factory wants to
 | 
				
			||||||
re-use a resource across different scopes, it often used
 | 
					re-use a resource across different scopes, it often used
 | 
				
			||||||
the ``request.cached_setup()`` helper to manage caching of
 | 
					the ``request.cached_setup()`` helper to manage caching of
 | 
				
			||||||
resources.  Here is a basic example how we could implement
 | 
					resources.  Here is a basic example how we could implement
 | 
				
			||||||
a per-session Database object::
 | 
					a per-session Database object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
    class Database(object):
 | 
					    class Database:
 | 
				
			||||||
        def __init__(self):
 | 
					        def __init__(self):
 | 
				
			||||||
            print("database instance created")
 | 
					            print("database instance created")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def destroy(self):
 | 
					        def destroy(self):
 | 
				
			||||||
            print("database instance destroyed")
 | 
					            print("database instance destroyed")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_funcarg__db(request):
 | 
					    def pytest_funcarg__db(request):
 | 
				
			||||||
        return request.cached_setup(setup=DataBase,
 | 
					        return request.cached_setup(
 | 
				
			||||||
                                    teardown=lambda db: db.destroy,
 | 
					            setup=DataBase, teardown=lambda db: db.destroy, scope="session"
 | 
				
			||||||
                                    scope="session")
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are several limitations and difficulties with this approach:
 | 
					There are several limitations and difficulties with this approach:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,7 +72,9 @@ Direct scoping of fixture/funcarg factories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Instead of calling cached_setup() with a cache scope, you can use the
 | 
					Instead of calling cached_setup() with a cache scope, you can use the
 | 
				
			||||||
:ref:`@pytest.fixture <pytest.fixture>` decorator and directly state
 | 
					:ref:`@pytest.fixture <pytest.fixture>` decorator and directly state
 | 
				
			||||||
the scope::
 | 
					the scope:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="session")
 | 
					    @pytest.fixture(scope="session")
 | 
				
			||||||
    def db(request):
 | 
					    def db(request):
 | 
				
			||||||
| 
						 | 
					@ -90,11 +96,13 @@ Previously, funcarg factories could not directly cause parametrization.
 | 
				
			||||||
You needed to specify a ``@parametrize`` decorator on your test function
 | 
					You needed to specify a ``@parametrize`` decorator on your test function
 | 
				
			||||||
or implement a ``pytest_generate_tests`` hook to perform
 | 
					or implement a ``pytest_generate_tests`` hook to perform
 | 
				
			||||||
parametrization, i.e. calling a test multiple times with different value
 | 
					parametrization, i.e. calling a test multiple times with different value
 | 
				
			||||||
sets.  pytest-2.3 introduces a decorator for use on the factory itself::
 | 
					sets.  pytest-2.3 introduces a decorator for use on the factory itself:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(params=["mysql", "pg"])
 | 
					    @pytest.fixture(params=["mysql", "pg"])
 | 
				
			||||||
    def db(request):
 | 
					    def db(request):
 | 
				
			||||||
        ... # use request.param
 | 
					        ...  # use request.param
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Here the factory will be invoked twice (with the respective "mysql"
 | 
					Here the factory will be invoked twice (with the respective "mysql"
 | 
				
			||||||
and "pg" values set as ``request.param`` attributes) and all of
 | 
					and "pg" values set as ``request.param`` attributes) and all of
 | 
				
			||||||
| 
						 | 
					@ -107,7 +115,9 @@ allow to re-use already written factories because effectively
 | 
				
			||||||
parametrized via
 | 
					parametrized via
 | 
				
			||||||
:py:func:`~_pytest.python.Metafunc.parametrize(indirect=True)` calls.
 | 
					:py:func:`~_pytest.python.Metafunc.parametrize(indirect=True)` calls.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Of course it's perfectly fine to combine parametrization and scoping::
 | 
					Of course it's perfectly fine to combine parametrization and scoping:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="session", params=["mysql", "pg"])
 | 
					    @pytest.fixture(scope="session", params=["mysql", "pg"])
 | 
				
			||||||
    def db(request):
 | 
					    def db(request):
 | 
				
			||||||
| 
						 | 
					@ -128,7 +138,9 @@ No ``pytest_funcarg__`` prefix when using @fixture decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When using the ``@fixture`` decorator the name of the function
 | 
					When using the ``@fixture`` decorator the name of the function
 | 
				
			||||||
denotes the name under which the resource can be accessed as a function
 | 
					denotes the name under which the resource can be accessed as a function
 | 
				
			||||||
argument::
 | 
					argument:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture()
 | 
					    @pytest.fixture()
 | 
				
			||||||
    def db(request):
 | 
					    def db(request):
 | 
				
			||||||
| 
						 | 
					@ -137,7 +149,9 @@ argument::
 | 
				
			||||||
The name under which the funcarg resource can be requested is ``db``.
 | 
					The name under which the funcarg resource can be requested is ``db``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can still use the "old" non-decorator way of specifying funcarg factories
 | 
					You can still use the "old" non-decorator way of specifying funcarg factories
 | 
				
			||||||
aka::
 | 
					aka:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_funcarg__db(request):
 | 
					    def pytest_funcarg__db(request):
 | 
				
			||||||
        ...
 | 
					        ...
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,12 +35,15 @@ Install ``pytest``
 | 
				
			||||||
Create your first test
 | 
					Create your first test
 | 
				
			||||||
----------------------------------------------------------
 | 
					----------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create a simple test function with just four lines of code::
 | 
					Create a simple test function with just four lines of code:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_sample.py
 | 
					    # content of test_sample.py
 | 
				
			||||||
    def func(x):
 | 
					    def func(x):
 | 
				
			||||||
        return x + 1
 | 
					        return x + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_answer():
 | 
					    def test_answer():
 | 
				
			||||||
        assert func(3) == 5
 | 
					        assert func(3) == 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,13 +86,18 @@ Run multiple tests
 | 
				
			||||||
Assert that a certain exception is raised
 | 
					Assert that a certain exception is raised
 | 
				
			||||||
--------------------------------------------------------------
 | 
					--------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Use the :ref:`raises <assertraises>` helper to assert that some code raises an exception::
 | 
					Use the :ref:`raises <assertraises>` helper to assert that some code raises an exception:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_sysexit.py
 | 
					    # content of test_sysexit.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def f():
 | 
					    def f():
 | 
				
			||||||
        raise SystemExit(1)
 | 
					        raise SystemExit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_mytest():
 | 
					    def test_mytest():
 | 
				
			||||||
        with pytest.raises(SystemExit):
 | 
					        with pytest.raises(SystemExit):
 | 
				
			||||||
            f()
 | 
					            f()
 | 
				
			||||||
| 
						 | 
					@ -105,17 +113,19 @@ Execute the test function with “quiet” reporting mode:
 | 
				
			||||||
Group multiple tests in a class
 | 
					Group multiple tests in a class
 | 
				
			||||||
--------------------------------------------------------------
 | 
					--------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Once you develop multiple tests, you may want to group them into a class. pytest makes it easy to create a class containing more than one test::
 | 
					Once you develop multiple tests, you may want to group them into a class. pytest makes it easy to create a class containing more than one test:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_class.py
 | 
					    # content of test_class.py
 | 
				
			||||||
    class TestClass(object):
 | 
					    class TestClass:
 | 
				
			||||||
        def test_one(self):
 | 
					        def test_one(self):
 | 
				
			||||||
            x = "this"
 | 
					            x = "this"
 | 
				
			||||||
            assert 'h' in x
 | 
					            assert "h" in x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_two(self):
 | 
					        def test_two(self):
 | 
				
			||||||
            x = "hello"
 | 
					            x = "hello"
 | 
				
			||||||
            assert hasattr(x, 'check')
 | 
					            assert hasattr(x, "check")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``pytest`` discovers all tests following its :ref:`Conventions for Python test discovery <test discovery>`, so it finds both ``test_`` prefixed functions. There is no need to subclass anything. We can simply run the module by passing its filename:
 | 
					``pytest`` discovers all tests following its :ref:`Conventions for Python test discovery <test discovery>`, so it finds both ``test_`` prefixed functions. There is no need to subclass anything. We can simply run the module by passing its filename:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,7 +152,9 @@ The first test passed and the second failed. You can easily see the intermediate
 | 
				
			||||||
Request a unique temporary directory for functional tests
 | 
					Request a unique temporary directory for functional tests
 | 
				
			||||||
--------------------------------------------------------------
 | 
					--------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``pytest`` provides `Builtin fixtures/function arguments <https://docs.pytest.org/en/latest/builtin.html>`_ to request arbitrary resources, like a unique temporary directory::
 | 
					``pytest`` provides `Builtin fixtures/function arguments <https://docs.pytest.org/en/latest/builtin.html>`_ to request arbitrary resources, like a unique temporary directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_tmpdir.py
 | 
					    # content of test_tmpdir.py
 | 
				
			||||||
    def test_needsfiles(tmpdir):
 | 
					    def test_needsfiles(tmpdir):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,13 +12,17 @@ pip_ for installing your application and any dependencies,
 | 
				
			||||||
as well as the ``pytest`` package itself.
 | 
					as well as the ``pytest`` package itself.
 | 
				
			||||||
This ensures your code and dependencies are isolated from your system Python installation.
 | 
					This ensures your code and dependencies are isolated from your system Python installation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Next, place a ``setup.py`` file in the root of your package with the following minimum content::
 | 
					Next, place a ``setup.py`` file in the root of your package with the following minimum content:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from setuptools import setup, find_packages
 | 
					    from setuptools import setup, find_packages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setup(name="PACKAGENAME", packages=find_packages())
 | 
					    setup(name="PACKAGENAME", packages=find_packages())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Where ``PACKAGENAME`` is the name of your package. You can then install your package in "editable" mode by running from the same directory::
 | 
					Where ``PACKAGENAME`` is the name of your package. You can then install your package in "editable" mode by running from the same directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     pip install -e .
 | 
					     pip install -e .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,7 +64,9 @@ Tests outside application code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Putting tests into an extra directory outside your actual application code
 | 
					Putting tests into an extra directory outside your actual application code
 | 
				
			||||||
might be useful if you have many functional tests or for other reasons want
 | 
					might be useful if you have many functional tests or for other reasons want
 | 
				
			||||||
to keep tests separate from actual application code (often a good idea)::
 | 
					to keep tests separate from actual application code (often a good idea):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setup.py
 | 
					    setup.py
 | 
				
			||||||
    mypkg/
 | 
					    mypkg/
 | 
				
			||||||
| 
						 | 
					@ -92,7 +98,9 @@ be imported as ``test_app`` and ``test_view`` top-level modules by adding ``test
 | 
				
			||||||
``sys.path``.
 | 
					``sys.path``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you need to have test modules with the same name, you might add ``__init__.py`` files to your
 | 
					If you need to have test modules with the same name, you might add ``__init__.py`` files to your
 | 
				
			||||||
``tests`` folder and subfolders, changing them to packages::
 | 
					``tests`` folder and subfolders, changing them to packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setup.py
 | 
					    setup.py
 | 
				
			||||||
    mypkg/
 | 
					    mypkg/
 | 
				
			||||||
| 
						 | 
					@ -114,7 +122,9 @@ This is problematic if you are using a tool like `tox`_ to test your package in
 | 
				
			||||||
because you want to test the *installed* version of your package, not the local code from the repository.
 | 
					because you want to test the *installed* version of your package, not the local code from the repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In this situation, it is **strongly** suggested to use a ``src`` layout where application root package resides in a
 | 
					In this situation, it is **strongly** suggested to use a ``src`` layout where application root package resides in a
 | 
				
			||||||
sub-directory of your root::
 | 
					sub-directory of your root:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setup.py
 | 
					    setup.py
 | 
				
			||||||
    src/
 | 
					    src/
 | 
				
			||||||
| 
						 | 
					@ -140,7 +150,9 @@ Tests as part of application code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Inlining test directories into your application package
 | 
					Inlining test directories into your application package
 | 
				
			||||||
is useful if you have direct relation between tests and application modules and
 | 
					is useful if you have direct relation between tests and application modules and
 | 
				
			||||||
want to distribute them along with your application::
 | 
					want to distribute them along with your application:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setup.py
 | 
					    setup.py
 | 
				
			||||||
    mypkg/
 | 
					    mypkg/
 | 
				
			||||||
| 
						 | 
					@ -153,7 +165,9 @@ want to distribute them along with your application::
 | 
				
			||||||
            test_view.py
 | 
					            test_view.py
 | 
				
			||||||
            ...
 | 
					            ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In this scheme, it is easy to run your tests using the ``--pyargs`` option::
 | 
					In this scheme, it is easy to run your tests using the ``--pyargs`` option:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest --pyargs mypkg
 | 
					    pytest --pyargs mypkg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,9 @@ caplog fixture
 | 
				
			||||||
^^^^^^^^^^^^^^
 | 
					^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Inside tests it is possible to change the log level for the captured log
 | 
					Inside tests it is possible to change the log level for the captured log
 | 
				
			||||||
messages.  This is supported by the ``caplog`` fixture::
 | 
					messages.  This is supported by the ``caplog`` fixture:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_foo(caplog):
 | 
					    def test_foo(caplog):
 | 
				
			||||||
        caplog.set_level(logging.INFO)
 | 
					        caplog.set_level(logging.INFO)
 | 
				
			||||||
| 
						 | 
					@ -78,59 +80,69 @@ messages.  This is supported by the ``caplog`` fixture::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
By default the level is set on the root logger,
 | 
					By default the level is set on the root logger,
 | 
				
			||||||
however as a convenience it is also possible to set the log level of any
 | 
					however as a convenience it is also possible to set the log level of any
 | 
				
			||||||
logger::
 | 
					logger:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_foo(caplog):
 | 
					    def test_foo(caplog):
 | 
				
			||||||
        caplog.set_level(logging.CRITICAL, logger='root.baz')
 | 
					        caplog.set_level(logging.CRITICAL, logger="root.baz")
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The log levels set are restored automatically at the end of the test.
 | 
					The log levels set are restored automatically at the end of the test.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is also possible to use a context manager to temporarily change the log
 | 
					It is also possible to use a context manager to temporarily change the log
 | 
				
			||||||
level inside a ``with`` block::
 | 
					level inside a ``with`` block:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_bar(caplog):
 | 
					    def test_bar(caplog):
 | 
				
			||||||
        with caplog.at_level(logging.INFO):
 | 
					        with caplog.at_level(logging.INFO):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Again, by default the level of the root logger is affected but the level of any
 | 
					Again, by default the level of the root logger is affected but the level of any
 | 
				
			||||||
logger can be changed instead with::
 | 
					logger can be changed instead with:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_bar(caplog):
 | 
					    def test_bar(caplog):
 | 
				
			||||||
        with caplog.at_level(logging.CRITICAL, logger='root.baz'):
 | 
					        with caplog.at_level(logging.CRITICAL, logger="root.baz"):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Lastly all the logs sent to the logger during the test run are made available on
 | 
					Lastly all the logs sent to the logger during the test run are made available on
 | 
				
			||||||
the fixture in the form of both the ``logging.LogRecord`` instances and the final log text.
 | 
					the fixture in the form of both the ``logging.LogRecord`` instances and the final log text.
 | 
				
			||||||
This is useful for when you want to assert on the contents of a message::
 | 
					This is useful for when you want to assert on the contents of a message:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_baz(caplog):
 | 
					    def test_baz(caplog):
 | 
				
			||||||
        func_under_test()
 | 
					        func_under_test()
 | 
				
			||||||
        for record in caplog.records:
 | 
					        for record in caplog.records:
 | 
				
			||||||
            assert record.levelname != 'CRITICAL'
 | 
					            assert record.levelname != "CRITICAL"
 | 
				
			||||||
        assert 'wally' not in caplog.text
 | 
					        assert "wally" not in caplog.text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For all the available attributes of the log records see the
 | 
					For all the available attributes of the log records see the
 | 
				
			||||||
``logging.LogRecord`` class.
 | 
					``logging.LogRecord`` class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can also resort to ``record_tuples`` if all you want to do is to ensure,
 | 
					You can also resort to ``record_tuples`` if all you want to do is to ensure,
 | 
				
			||||||
that certain messages have been logged under a given logger name with a given
 | 
					that certain messages have been logged under a given logger name with a given
 | 
				
			||||||
severity and message::
 | 
					severity and message:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_foo(caplog):
 | 
					    def test_foo(caplog):
 | 
				
			||||||
        logging.getLogger().info('boo %s', 'arg')
 | 
					        logging.getLogger().info("boo %s", "arg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert caplog.record_tuples == [
 | 
					        assert caplog.record_tuples == [("root", logging.INFO, "boo arg")]
 | 
				
			||||||
            ('root', logging.INFO, 'boo arg'),
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can call ``caplog.clear()`` to reset the captured log records in a test::
 | 
					You can call ``caplog.clear()`` to reset the captured log records in a test:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_something_with_clearing_records(caplog):
 | 
					    def test_something_with_clearing_records(caplog):
 | 
				
			||||||
        some_method_that_creates_log_records()
 | 
					        some_method_that_creates_log_records()
 | 
				
			||||||
        caplog.clear()
 | 
					        caplog.clear()
 | 
				
			||||||
        your_test_method()
 | 
					        your_test_method()
 | 
				
			||||||
        assert ['Foo'] == [rec.message for rec in caplog.records]
 | 
					        assert ["Foo"] == [rec.message for rec in caplog.records]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The ``caplog.records`` attribute contains records from the current stage only, so
 | 
					The ``caplog.records`` attribute contains records from the current stage only, so
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -272,7 +272,7 @@ to do this using the ``setenv`` and ``delenv`` method. Our example code to test:
 | 
				
			||||||
        username = os.getenv("USER")
 | 
					        username = os.getenv("USER")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if username is None:
 | 
					        if username is None:
 | 
				
			||||||
            raise EnvironmentError("USER environment is not set.")
 | 
					            raise OSError("USER environment is not set.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return username.lower()
 | 
					        return username.lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,7 +296,7 @@ both paths can be safely tested without impacting the running environment:
 | 
				
			||||||
        """Remove the USER env var and assert EnvironmentError is raised."""
 | 
					        """Remove the USER env var and assert EnvironmentError is raised."""
 | 
				
			||||||
        monkeypatch.delenv("USER", raising=False)
 | 
					        monkeypatch.delenv("USER", raising=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with pytest.raises(EnvironmentError):
 | 
					        with pytest.raises(OSError):
 | 
				
			||||||
            _ = get_os_user_lower()
 | 
					            _ = get_os_user_lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This behavior can be moved into ``fixture`` structures and shared across tests:
 | 
					This behavior can be moved into ``fixture`` structures and shared across tests:
 | 
				
			||||||
| 
						 | 
					@ -323,7 +323,7 @@ This behavior can be moved into ``fixture`` structures and shared across tests:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_raise_exception(mock_env_missing):
 | 
					    def test_raise_exception(mock_env_missing):
 | 
				
			||||||
        with pytest.raises(EnvironmentError):
 | 
					        with pytest.raises(OSError):
 | 
				
			||||||
            _ = get_os_user_lower()
 | 
					            _ = get_os_user_lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,9 @@ Installing and Using plugins
 | 
				
			||||||
This section talks about installing and using third party plugins.
 | 
					This section talks about installing and using third party plugins.
 | 
				
			||||||
For writing your own plugins, please refer to :ref:`writing-plugins`.
 | 
					For writing your own plugins, please refer to :ref:`writing-plugins`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Installing a third party plugin can be easily done with ``pip``::
 | 
					Installing a third party plugin can be easily done with ``pip``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pip install pytest-NAME
 | 
					    pip install pytest-NAME
 | 
				
			||||||
    pip uninstall pytest-NAME
 | 
					    pip uninstall pytest-NAME
 | 
				
			||||||
| 
						 | 
					@ -95,7 +97,9 @@ Finding out which plugins are active
 | 
				
			||||||
------------------------------------
 | 
					------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you want to find out which plugins are active in your
 | 
					If you want to find out which plugins are active in your
 | 
				
			||||||
environment you can type::
 | 
					environment you can type:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest --trace-config
 | 
					    pytest --trace-config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,7 +112,9 @@ and their names. It will also print local plugins aka
 | 
				
			||||||
Deactivating / unregistering a plugin by name
 | 
					Deactivating / unregistering a plugin by name
 | 
				
			||||||
---------------------------------------------
 | 
					---------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can prevent plugins from loading or unregister them::
 | 
					You can prevent plugins from loading or unregister them:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest -p no:NAME
 | 
					    pytest -p no:NAME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,9 @@ Consider this file and directory layout::
 | 
				
			||||||
             |- test_foo.py
 | 
					             |- test_foo.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When executing::
 | 
					When executing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest root/
 | 
					    pytest root/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +56,9 @@ Consider this file and directory layout::
 | 
				
			||||||
             |- test_foo.py
 | 
					             |- test_foo.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
When executing::
 | 
					When executing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest root/
 | 
					    pytest root/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -469,9 +469,11 @@ testdir
 | 
				
			||||||
This fixture provides a :class:`Testdir` instance useful for black-box testing of test files, making it ideal to
 | 
					This fixture provides a :class:`Testdir` instance useful for black-box testing of test files, making it ideal to
 | 
				
			||||||
test plugins.
 | 
					test plugins.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To use it, include in your top-most ``conftest.py`` file::
 | 
					To use it, include in your top-most ``conftest.py`` file:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest_plugins = 'pytester'
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pytest_plugins = "pytester"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1001,6 +1003,8 @@ passed multiple times. The expected format is ``name=value``. For example::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   issuing ``pytest test_hello.py`` actually means::
 | 
					   issuing ``pytest test_hello.py`` actually means::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   .. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pytest --maxfail=2 -rf test_hello.py
 | 
					        pytest --maxfail=2 -rf test_hello.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   Default is to add no options.
 | 
					   Default is to add no options.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,7 +145,7 @@ You can use the ``skipif`` marker (as any other marker) on classes:
 | 
				
			||||||
.. code-block:: python
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")
 | 
					    @pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")
 | 
				
			||||||
    class TestPosixCalls(object):
 | 
					    class TestPosixCalls:
 | 
				
			||||||
        def test_function(self):
 | 
					        def test_function(self):
 | 
				
			||||||
            "will not be setup or run under 'win32' platform"
 | 
					            "will not be setup or run under 'win32' platform"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,13 +180,17 @@ Skipping on a missing import dependency
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can use the following helper at module level
 | 
					You can use the following helper at module level
 | 
				
			||||||
or within a test or test setup function::
 | 
					or within a test or test setup function:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    docutils = pytest.importorskip("docutils")
 | 
					    docutils = pytest.importorskip("docutils")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If ``docutils`` cannot be imported here, this will lead to a
 | 
					If ``docutils`` cannot be imported here, this will lead to a
 | 
				
			||||||
skip outcome of the test.  You can also skip based on the
 | 
					skip outcome of the test.  You can also skip based on the
 | 
				
			||||||
version number of a library::
 | 
					version number of a library:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    docutils = pytest.importorskip("docutils", minversion="0.3")
 | 
					    docutils = pytest.importorskip("docutils", minversion="0.3")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,7 +227,9 @@ XFail: mark test functions as expected to fail
 | 
				
			||||||
----------------------------------------------
 | 
					----------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can use the ``xfail`` marker to indicate that you
 | 
					You can use the ``xfail`` marker to indicate that you
 | 
				
			||||||
expect a test to fail::
 | 
					expect a test to fail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.xfail
 | 
					    @pytest.mark.xfail
 | 
				
			||||||
    def test_function():
 | 
					    def test_function():
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,10 +90,14 @@ provide a temporary directory unique to the test invocation,
 | 
				
			||||||
created in the `base temporary directory`_.
 | 
					created in the `base temporary directory`_.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
``tmpdir`` is a `py.path.local`_ object which offers ``os.path`` methods
 | 
					``tmpdir`` is a `py.path.local`_ object which offers ``os.path`` methods
 | 
				
			||||||
and more.  Here is an example test usage::
 | 
					and more.  Here is an example test usage:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_tmpdir.py
 | 
					    # content of test_tmpdir.py
 | 
				
			||||||
    import os
 | 
					    import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_create_file(tmpdir):
 | 
					    def test_create_file(tmpdir):
 | 
				
			||||||
        p = tmpdir.mkdir("sub").join("hello.txt")
 | 
					        p = tmpdir.mkdir("sub").join("hello.txt")
 | 
				
			||||||
        p.write("content")
 | 
					        p.write("content")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,9 @@ It's meant for leveraging existing ``unittest``-based test suites
 | 
				
			||||||
to use pytest as a test runner and also allow to incrementally adapt
 | 
					to use pytest as a test runner and also allow to incrementally adapt
 | 
				
			||||||
the test suite to take full advantage of pytest's features.
 | 
					the test suite to take full advantage of pytest's features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To run an existing ``unittest``-style test suite using ``pytest``, type::
 | 
					To run an existing ``unittest``-style test suite using ``pytest``, type:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest tests
 | 
					    pytest tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +80,9 @@ Running your unittest with ``pytest`` allows you to use its
 | 
				
			||||||
tests.  Assuming you have at least skimmed the pytest fixture features,
 | 
					tests.  Assuming you have at least skimmed the pytest fixture features,
 | 
				
			||||||
let's jump-start into an example that integrates a pytest ``db_class``
 | 
					let's jump-start into an example that integrates a pytest ``db_class``
 | 
				
			||||||
fixture, setting up a class-cached database object, and then reference
 | 
					fixture, setting up a class-cached database object, and then reference
 | 
				
			||||||
it from a unittest-style test::
 | 
					it from a unittest-style test:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of conftest.py
 | 
					    # content of conftest.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,10 +91,12 @@ it from a unittest-style test::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.fixture(scope="class")
 | 
					    @pytest.fixture(scope="class")
 | 
				
			||||||
    def db_class(request):
 | 
					    def db_class(request):
 | 
				
			||||||
        class DummyDB(object):
 | 
					        class DummyDB:
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # set a class attribute on the invoking test context
 | 
					        # set a class attribute on the invoking test context
 | 
				
			||||||
        request.cls.db = DummyDB()
 | 
					        request.cls.db = DummyDB()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -103,21 +109,24 @@ as the ``cls`` attribute, denoting the class from which the fixture
 | 
				
			||||||
is used.  This architecture de-couples fixture writing from actual test
 | 
					is used.  This architecture de-couples fixture writing from actual test
 | 
				
			||||||
code and allows re-use of the fixture by a minimal reference, the fixture
 | 
					code and allows re-use of the fixture by a minimal reference, the fixture
 | 
				
			||||||
name.  So let's write an actual ``unittest.TestCase`` class using our
 | 
					name.  So let's write an actual ``unittest.TestCase`` class using our
 | 
				
			||||||
fixture definition::
 | 
					fixture definition:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_unittest_db.py
 | 
					    # content of test_unittest_db.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import unittest
 | 
					    import unittest
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.mark.usefixtures("db_class")
 | 
					    @pytest.mark.usefixtures("db_class")
 | 
				
			||||||
    class MyTest(unittest.TestCase):
 | 
					    class MyTest(unittest.TestCase):
 | 
				
			||||||
        def test_method1(self):
 | 
					        def test_method1(self):
 | 
				
			||||||
            assert hasattr(self, "db")
 | 
					            assert hasattr(self, "db")
 | 
				
			||||||
            assert 0, self.db   # fail for demo purposes
 | 
					            assert 0, self.db  # fail for demo purposes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_method2(self):
 | 
					        def test_method2(self):
 | 
				
			||||||
            assert 0, self.db   # fail for demo purposes
 | 
					            assert 0, self.db  # fail for demo purposes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The ``@pytest.mark.usefixtures("db_class")`` class-decorator makes sure that
 | 
					The ``@pytest.mark.usefixtures("db_class")`` class-decorator makes sure that
 | 
				
			||||||
the pytest fixture function ``db_class`` is called once per class.
 | 
					the pytest fixture function ``db_class`` is called once per class.
 | 
				
			||||||
| 
						 | 
					@ -179,17 +188,19 @@ Let's look at an ``initdir`` fixture which makes all test methods of a
 | 
				
			||||||
``TestCase`` class execute in a temporary directory with a
 | 
					``TestCase`` class execute in a temporary directory with a
 | 
				
			||||||
pre-initialized ``samplefile.ini``.  Our ``initdir`` fixture itself uses
 | 
					pre-initialized ``samplefile.ini``.  Our ``initdir`` fixture itself uses
 | 
				
			||||||
the pytest builtin :ref:`tmpdir <tmpdir>` fixture to delegate the
 | 
					the pytest builtin :ref:`tmpdir <tmpdir>` fixture to delegate the
 | 
				
			||||||
creation of a per-test temporary directory::
 | 
					creation of a per-test temporary directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of test_unittest_cleandir.py
 | 
					    # content of test_unittest_cleandir.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    import unittest
 | 
					    import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class MyTest(unittest.TestCase):
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyTest(unittest.TestCase):
 | 
				
			||||||
        @pytest.fixture(autouse=True)
 | 
					        @pytest.fixture(autouse=True)
 | 
				
			||||||
        def initdir(self, tmpdir):
 | 
					        def initdir(self, tmpdir):
 | 
				
			||||||
            tmpdir.chdir() # change to pytest-provided temporary directory
 | 
					            tmpdir.chdir()  # change to pytest-provided temporary directory
 | 
				
			||||||
            tmpdir.join("samplefile.ini").write("# testdata")
 | 
					            tmpdir.join("samplefile.ini").write("# testdata")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def test_method(self):
 | 
					        def test_method(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -652,7 +652,7 @@ to all tests.
 | 
				
			||||||
        record_testsuite_property("STORAGE_TYPE", "CEPH")
 | 
					        record_testsuite_property("STORAGE_TYPE", "CEPH")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class TestMe(object):
 | 
					    class TestMe:
 | 
				
			||||||
        def test_foo(self):
 | 
					        def test_foo(self):
 | 
				
			||||||
            assert True
 | 
					            assert True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -754,24 +754,33 @@ Calling pytest from Python code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can invoke ``pytest`` from Python code directly::
 | 
					You can invoke ``pytest`` from Python code directly:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest.main()
 | 
					    pytest.main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
this acts as if you would call "pytest" from the command line.
 | 
					this acts as if you would call "pytest" from the command line.
 | 
				
			||||||
It will not raise ``SystemExit`` but return the exitcode instead.
 | 
					It will not raise ``SystemExit`` but return the exitcode instead.
 | 
				
			||||||
You can pass in options and arguments::
 | 
					You can pass in options and arguments:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest.main(['-x', 'mytestdir'])
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can specify additional plugins to ``pytest.main``::
 | 
					    pytest.main(["-x", "mytestdir"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can specify additional plugins to ``pytest.main``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # content of myinvoke.py
 | 
					    # content of myinvoke.py
 | 
				
			||||||
    import pytest
 | 
					    import pytest
 | 
				
			||||||
    class MyPlugin(object):
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class MyPlugin:
 | 
				
			||||||
        def pytest_sessionfinish(self):
 | 
					        def pytest_sessionfinish(self):
 | 
				
			||||||
            print("*** test run reporting finishing")
 | 
					            print("*** test run reporting finishing")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest.main(["-qq"], plugins=[MyPlugin()])
 | 
					    pytest.main(["-qq"], plugins=[MyPlugin()])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Running it will show that ``MyPlugin`` was added and its
 | 
					Running it will show that ``MyPlugin`` was added and its
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,6 +180,7 @@ This will ignore all warnings of type ``DeprecationWarning`` where the start of
 | 
				
			||||||
the regular expression ``".*U.*mode is deprecated"``.
 | 
					the regular expression ``".*U.*mode is deprecated"``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. note::
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    If warnings are configured at the interpreter level, using
 | 
					    If warnings are configured at the interpreter level, using
 | 
				
			||||||
    the `PYTHONWARNINGS <https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS>`_ environment variable or the
 | 
					    the `PYTHONWARNINGS <https://docs.python.org/3/using/cmdline.html#envvar-PYTHONWARNINGS>`_ environment variable or the
 | 
				
			||||||
    ``-W`` command-line option, pytest will not configure any filters by default.
 | 
					    ``-W`` command-line option, pytest will not configure any filters by default.
 | 
				
			||||||
| 
						 | 
					@ -277,7 +278,9 @@ argument ``match`` to assert that the exception matches a text or regex::
 | 
				
			||||||
      ...
 | 
					      ...
 | 
				
			||||||
    Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted...
 | 
					    Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can also call ``pytest.warns`` on a function or code string::
 | 
					You can also call ``pytest.warns`` on a function or code string:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pytest.warns(expected_warning, func, *args, **kwargs)
 | 
					    pytest.warns(expected_warning, func, *args, **kwargs)
 | 
				
			||||||
    pytest.warns(expected_warning, "func(*args, **kwargs)")
 | 
					    pytest.warns(expected_warning, "func(*args, **kwargs)")
 | 
				
			||||||
| 
						 | 
					@ -411,7 +414,7 @@ These warnings might be filtered using the same builtin mechanisms used to filte
 | 
				
			||||||
Please read our :ref:`backwards-compatibility` to learn how we proceed about deprecating and eventually removing
 | 
					Please read our :ref:`backwards-compatibility` to learn how we proceed about deprecating and eventually removing
 | 
				
			||||||
features.
 | 
					features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The following warning types ares used by pytest and are part of the public API:
 | 
					The following warning types are used by pytest and are part of the public API:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. autoclass:: pytest.PytestWarning
 | 
					.. autoclass:: pytest.PytestWarning
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -693,7 +693,7 @@ declaring the hook functions directly in your plugin module, for example:
 | 
				
			||||||
    # contents of myplugin.py
 | 
					    # contents of myplugin.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class DeferPlugin(object):
 | 
					    class DeferPlugin:
 | 
				
			||||||
        """Simple plugin to defer pytest-xdist hook functions."""
 | 
					        """Simple plugin to defer pytest-xdist hook functions."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def pytest_testnodedown(self, node, error):
 | 
					        def pytest_testnodedown(self, node, error):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,11 +27,14 @@ Module level setup/teardown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you have multiple test functions and test classes in a single
 | 
					If you have multiple test functions and test classes in a single
 | 
				
			||||||
module you can optionally implement the following fixture methods
 | 
					module you can optionally implement the following fixture methods
 | 
				
			||||||
which will usually be called once for all the functions::
 | 
					which will usually be called once for all the functions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_module(module):
 | 
					    def setup_module(module):
 | 
				
			||||||
        """ setup any state specific to the execution of the given module."""
 | 
					        """ setup any state specific to the execution of the given module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def teardown_module(module):
 | 
					    def teardown_module(module):
 | 
				
			||||||
        """ teardown any state that was previously setup with a setup_module
 | 
					        """ teardown any state that was previously setup with a setup_module
 | 
				
			||||||
        method.
 | 
					        method.
 | 
				
			||||||
| 
						 | 
					@ -43,7 +46,9 @@ Class level setup/teardown
 | 
				
			||||||
----------------------------------
 | 
					----------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Similarly, the following methods are called at class level before
 | 
					Similarly, the following methods are called at class level before
 | 
				
			||||||
and after all test methods of the class are called::
 | 
					and after all test methods of the class are called:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def setup_class(cls):
 | 
					    def setup_class(cls):
 | 
				
			||||||
| 
						 | 
					@ -51,6 +56,7 @@ and after all test methods of the class are called::
 | 
				
			||||||
        usually contains tests).
 | 
					        usually contains tests).
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def teardown_class(cls):
 | 
					    def teardown_class(cls):
 | 
				
			||||||
        """ teardown any state that was previously setup with a call to
 | 
					        """ teardown any state that was previously setup with a call to
 | 
				
			||||||
| 
						 | 
					@ -60,13 +66,16 @@ and after all test methods of the class are called::
 | 
				
			||||||
Method and function level setup/teardown
 | 
					Method and function level setup/teardown
 | 
				
			||||||
-----------------------------------------------
 | 
					-----------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Similarly, the following methods are called around each method invocation::
 | 
					Similarly, the following methods are called around each method invocation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_method(self, method):
 | 
					    def setup_method(self, method):
 | 
				
			||||||
        """ setup any state tied to the execution of the given method in a
 | 
					        """ setup any state tied to the execution of the given method in a
 | 
				
			||||||
        class.  setup_method is invoked for every test method of a class.
 | 
					        class.  setup_method is invoked for every test method of a class.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def teardown_method(self, method):
 | 
					    def teardown_method(self, method):
 | 
				
			||||||
        """ teardown any state that was previously setup with a setup_method
 | 
					        """ teardown any state that was previously setup with a setup_method
 | 
				
			||||||
        call.
 | 
					        call.
 | 
				
			||||||
| 
						 | 
					@ -75,13 +84,16 @@ Similarly, the following methods are called around each method invocation::
 | 
				
			||||||
As of pytest-3.0, the ``method`` parameter is optional.
 | 
					As of pytest-3.0, the ``method`` parameter is optional.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you would rather define test functions directly at module level
 | 
					If you would rather define test functions directly at module level
 | 
				
			||||||
you can also use the following functions to implement fixtures::
 | 
					you can also use the following functions to implement fixtures:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup_function(function):
 | 
					    def setup_function(function):
 | 
				
			||||||
        """ setup any state tied to the execution of the given function.
 | 
					        """ setup any state tied to the execution of the given function.
 | 
				
			||||||
        Invoked for every test function in the module.
 | 
					        Invoked for every test function in the module.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def teardown_function(function):
 | 
					    def teardown_function(function):
 | 
				
			||||||
        """ teardown any state that was previously setup with a setup_function
 | 
					        """ teardown any state that was previously setup with a setup_function
 | 
				
			||||||
        call.
 | 
					        call.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue