ran blacken-docs

This commit is contained in:
boris 2019-08-06 13:34:58 -07:00
parent 75d0b899bb
commit 5f95dce956
17 changed files with 163 additions and 66 deletions

View File

@ -238,7 +238,10 @@ 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: {} != {}".format(left.val, right.val)] return [
"Comparing Foo instances:",
" vals: {} != {}".format(left.val, right.val),
]
now, given this test module: now, given this test module:

View File

@ -167,4 +167,5 @@ You can also interactively ask for help, e.g. by typing on the Python interactiv
.. code-block:: python .. code-block:: python
import pytest import pytest
help(pytest) help(pytest)

View File

@ -40,10 +40,11 @@ First, let's create 50 test invocation of which only 2 fail::
# 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:
@ -193,9 +194,11 @@ across pytest invocations::
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)
@ -205,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

View File

@ -55,12 +55,15 @@ is that you can use print statements for debugging::
# 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

View File

@ -197,9 +197,11 @@ place the objects you want to appear in the doctest namespace::
# 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::

View File

@ -25,6 +25,7 @@ line argument. Let's first write a simple (do-nothing) computation test::
# content of test_compute.py # content of test_compute.py
def test_compute(param1): def test_compute(param1):
assert param1 < 4 assert param1 < 4
@ -34,13 +35,14 @@ Now we add a test configuration like this::
# 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
@ -118,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)
@ -126,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
@ -183,6 +191,7 @@ only have to work a bit to construct the correct arguments for pytest's
# content of test_scenarios.py # content of test_scenarios.py
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
idlist = [] idlist = []
argvalues = [] argvalues = []
@ -193,8 +202,10 @@ only have to work a bit to construct the correct arguments for pytest's
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'}) scenario1 = ("basic", {"attribute": "value"})
scenario2 = ("advanced", {"attribute": "value2"})
class TestSampleWithScenarios: class TestSampleWithScenarios:
scenarios = [scenario1, scenario2] scenarios = [scenario1, scenario2]
@ -259,6 +270,8 @@ the actual test requiring a ``db`` object::
# 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":
@ -273,15 +286,20 @@ creates a database object for the actual test invocations::
# content of conftest.py # content of conftest.py
import pytest import pytest
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
if 'db' in metafunc.fixturenames: if "db" in metafunc.fixturenames:
metafunc.parametrize("db", ['d1', 'd2'], indirect=True) metafunc.parametrize("db", ["d1", "d2"], indirect=True)
class DB1: class DB1:
"one database object" "one database object"
class DB2: 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":
@ -346,18 +364,22 @@ will be passed to respective fixture function::
# 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:
@ -391,18 +413,21 @@ parametrizer`_ but in a lot less code::
# 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: 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):
@ -471,10 +496,12 @@ need to provide similar results::
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)
@ -501,6 +528,7 @@ And finally a little test module::
# 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)
@ -610,17 +638,21 @@ as a complement to ``raises``. For example::
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:

View File

@ -139,6 +139,7 @@ that match ``*_check``. For example, if we have::
class CheckMyApp: class CheckMyApp:
def simple_check(self): def simple_check(self):
pass pass
def complex_check(self): def complex_check(self):
pass pass
@ -267,7 +268,7 @@ and a ``setup.py`` dummy file like this::
.. code-block:: python .. 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:

View File

@ -13,6 +13,7 @@ calls it::
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")
@ -22,7 +23,7 @@ calls it::
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
@ -32,6 +33,7 @@ will be called ahead of running any tests::
# content of test_module.py # content of test_module.py
class TestHello: class TestHello:
@classmethod @classmethod
def callme(cls): def callme(cls):
@ -43,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: 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):

View File

@ -56,15 +56,18 @@ using it::
# 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>`
@ -190,6 +193,7 @@ access the fixture function::
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)
@ -203,12 +207,14 @@ located)::
# 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
@ -491,6 +497,7 @@ read an optional server URL from the test module which uses our fixture::
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")
@ -519,6 +526,7 @@ server URL in its module namespace::
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()
@ -556,12 +564,8 @@ Factories can have parameters as needed::
@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
@ -620,8 +624,8 @@ through the special :py:class:`request <FixtureRequest>` object::
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
@ -713,23 +717,28 @@ the string used in a test ID for a certain fixture value by using the
# 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
@ -778,10 +787,13 @@ Example::
# 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
@ -820,14 +832,17 @@ and instantiate an object ``app`` where we stick the already defined
import pytest import pytest
class App: 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
@ -883,6 +898,7 @@ to show the setup/teardown flow::
# 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
@ -890,17 +906,23 @@ 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 {} and modarg {}".format(otherarg, modarg)) print(" RUN test2 with otherarg {} and modarg {}".format(otherarg, modarg))
@ -987,6 +1009,7 @@ file::
import tempfile import tempfile
import os import os
@pytest.fixture() @pytest.fixture()
def cleandir(): def cleandir():
newpath = tempfile.mkdtemp() newpath = tempfile.mkdtemp()
@ -1000,6 +1023,7 @@ and declare its use in a test module via a ``usefixtures`` marker::
import os import os
import pytest import pytest
@pytest.mark.usefixtures("cleandir") @pytest.mark.usefixtures("cleandir")
class TestDirectoryInit: class TestDirectoryInit:
def test_cwd_starts_empty(self): def test_cwd_starts_empty(self):
@ -1086,18 +1110,23 @@ self-contained implementation of this idea::
import pytest import pytest
class DB: 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: class TestClass:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def transact(self, request, db): def transact(self, request, db):

View File

@ -29,13 +29,15 @@ a per-session Database object::
class Database: 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:
@ -100,7 +102,7 @@ sets. pytest-2.3 introduces a decorator for use on the factory itself::
@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

View File

@ -43,6 +43,7 @@ Create a simple test function with just four lines of code::
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
@ -91,9 +92,12 @@ Use the :ref:`raises <assertraises>` helper to assert that some code raises an e
# 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()
@ -117,11 +121,11 @@ Once you develop multiple tests, you may want to group them into a class. pytest
class TestClass: 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:

View File

@ -85,7 +85,7 @@ logger::
.. code-block:: python .. 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.
@ -105,7 +105,7 @@ logger can be changed instead with::
.. code-block:: python .. 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
@ -117,8 +117,8 @@ This is useful for when you want to assert on the contents of a message::
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.
@ -130,11 +130,9 @@ severity and message::
.. code-block:: python .. 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::
@ -144,7 +142,7 @@ You can call ``caplog.clear()`` to reset the captured log records in a test::
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

View File

@ -473,7 +473,7 @@ To use it, include in your top-most ``conftest.py`` file::
.. code-block:: python .. code-block:: python
pytest_plugins = 'pytester' pytest_plugins = "pytester"

View File

@ -96,6 +96,8 @@ and more. Here is an example test usage::
# 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")

View File

@ -91,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: 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()
@ -116,14 +118,15 @@ fixture definition::
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.
@ -193,11 +196,11 @@ creation of a per-test temporary directory::
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):

View File

@ -766,7 +766,7 @@ You can pass in options and arguments::
.. code-block:: python .. code-block:: python
pytest.main(['-x', 'mytestdir']) pytest.main(["-x", "mytestdir"])
You can specify additional plugins to ``pytest.main``:: You can specify additional plugins to ``pytest.main``::
@ -774,10 +774,13 @@ You can specify additional plugins to ``pytest.main``::
# content of myinvoke.py # content of myinvoke.py
import pytest import pytest
class MyPlugin: 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

View File

@ -34,6 +34,7 @@ which will usually be called once for all the functions::
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.
@ -55,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
@ -73,6 +75,7 @@ Similarly, the following methods are called around each method invocation::
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.
@ -90,6 +93,7 @@ you can also use the following functions to implement fixtures::
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.