Merge remote-tracking branch 'upstream/master' into merge-master-into-features
This commit is contained in:
commit
1fff81e21d
1
AUTHORS
1
AUTHORS
|
@ -107,6 +107,7 @@ Kale Kundert
|
||||||
Katarzyna Jachim
|
Katarzyna Jachim
|
||||||
Kevin Cox
|
Kevin Cox
|
||||||
Kodi B. Arfer
|
Kodi B. Arfer
|
||||||
|
Kostis Anagnostopoulos
|
||||||
Lawrence Mitchell
|
Lawrence Mitchell
|
||||||
Lee Kamentsky
|
Lee Kamentsky
|
||||||
Lev Maximov
|
Lev Maximov
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
..
|
..
|
||||||
You should *NOT* be adding new change log entries to this file, this
|
You should *NOT* be adding new change log entries to this file, this
|
||||||
file is managed by towncrier. You *may* edit previous change logs to
|
file is managed by towncrier. You *may* edit previous change logs to
|
||||||
fix problems like typo corrections or such.
|
fix problems like typo corrections or such.
|
||||||
|
@ -377,7 +377,7 @@ Features
|
||||||
- Match ``warns`` signature to ``raises`` by adding ``match`` keyword. (`#2708
|
- Match ``warns`` signature to ``raises`` by adding ``match`` keyword. (`#2708
|
||||||
<https://github.com/pytest-dev/pytest/issues/2708>`_)
|
<https://github.com/pytest-dev/pytest/issues/2708>`_)
|
||||||
|
|
||||||
- Pytest now captures and displays output from the standard `logging` module.
|
- Pytest now captures and displays output from the standard ``logging`` module.
|
||||||
The user can control the logging level to be captured by specifying options
|
The user can control the logging level to be captured by specifying options
|
||||||
in ``pytest.ini``, the command line and also during individual tests using
|
in ``pytest.ini``, the command line and also during individual tests using
|
||||||
markers. Also, a ``caplog`` fixture is available that enables users to test
|
markers. Also, a ``caplog`` fixture is available that enables users to test
|
||||||
|
|
|
@ -197,9 +197,9 @@ def _ensure_only_one_capture_fixture(request, name):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def capsys(request):
|
def capsys(request):
|
||||||
"""Enable capturing of writes to sys.stdout/sys.stderr and make
|
"""Enable capturing of writes to ``sys.stdout`` and ``sys.stderr`` and make
|
||||||
captured output available via ``capsys.readouterr()`` method calls
|
captured output available via ``capsys.readouterr()`` method calls
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``text``
|
which return a ``(out, err)`` namedtuple. ``out`` and ``err`` will be ``text``
|
||||||
objects.
|
objects.
|
||||||
"""
|
"""
|
||||||
_ensure_only_one_capture_fixture(request, 'capsys')
|
_ensure_only_one_capture_fixture(request, 'capsys')
|
||||||
|
@ -209,7 +209,7 @@ def capsys(request):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def capsysbinary(request):
|
def capsysbinary(request):
|
||||||
"""Enable capturing of writes to sys.stdout/sys.stderr and make
|
"""Enable capturing of writes to ``sys.stdout`` and ``sys.stderr`` and make
|
||||||
captured output available via ``capsys.readouterr()`` method calls
|
captured output available via ``capsys.readouterr()`` method calls
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``bytes``
|
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``bytes``
|
||||||
objects.
|
objects.
|
||||||
|
@ -225,7 +225,7 @@ def capsysbinary(request):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def capfd(request):
|
def capfd(request):
|
||||||
"""Enable capturing of writes to file descriptors 1 and 2 and make
|
"""Enable capturing of writes to file descriptors ``1`` and ``2`` and make
|
||||||
captured output available via ``capfd.readouterr()`` method calls
|
captured output available via ``capfd.readouterr()`` method calls
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``text``
|
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``text``
|
||||||
objects.
|
objects.
|
||||||
|
@ -272,6 +272,10 @@ def _install_capture_fixture_on_item(request, capture_class):
|
||||||
|
|
||||||
|
|
||||||
class CaptureFixture(object):
|
class CaptureFixture(object):
|
||||||
|
"""
|
||||||
|
Object returned by :py:func:`capsys`, :py:func:`capsysbinary`, :py:func:`capfd` and :py:func:`capfdbinary`
|
||||||
|
fixtures.
|
||||||
|
"""
|
||||||
def __init__(self, captureclass, request):
|
def __init__(self, captureclass, request):
|
||||||
self.captureclass = captureclass
|
self.captureclass = captureclass
|
||||||
self.request = request
|
self.request = request
|
||||||
|
@ -288,6 +292,10 @@ class CaptureFixture(object):
|
||||||
cap.stop_capturing()
|
cap.stop_capturing()
|
||||||
|
|
||||||
def readouterr(self):
|
def readouterr(self):
|
||||||
|
"""Read and return the captured output so far, resetting the internal buffer.
|
||||||
|
|
||||||
|
:return: captured content as a namedtuple with ``out`` and ``err`` string attributes
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return self._capture.readouterr()
|
return self._capture.readouterr()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -295,6 +303,7 @@ class CaptureFixture(object):
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def disabled(self):
|
def disabled(self):
|
||||||
|
"""Temporarily disables capture while inside the 'with' block."""
|
||||||
self._capture.suspend_capturing()
|
self._capture.suspend_capturing()
|
||||||
capmanager = self.request.config.pluginmanager.getplugin('capturemanager')
|
capmanager = self.request.config.pluginmanager.getplugin('capturemanager')
|
||||||
capmanager.suspend_global_capture(item=None, in_=False)
|
capmanager.suspend_global_capture(item=None, in_=False)
|
||||||
|
@ -476,7 +485,7 @@ class FDCaptureBinary(object):
|
||||||
os.dup2(targetfd_save, self.targetfd)
|
os.dup2(targetfd_save, self.targetfd)
|
||||||
os.close(targetfd_save)
|
os.close(targetfd_save)
|
||||||
self.syscapture.done()
|
self.syscapture.done()
|
||||||
self.tmpfile.close()
|
_attempt_to_close_capture_file(self.tmpfile)
|
||||||
|
|
||||||
def suspend(self):
|
def suspend(self):
|
||||||
self.syscapture.suspend()
|
self.syscapture.suspend()
|
||||||
|
@ -530,7 +539,7 @@ class SysCapture(object):
|
||||||
def done(self):
|
def done(self):
|
||||||
setattr(sys, self.name, self._old)
|
setattr(sys, self.name, self._old)
|
||||||
del self._old
|
del self._old
|
||||||
self.tmpfile.close()
|
_attempt_to_close_capture_file(self.tmpfile)
|
||||||
|
|
||||||
def suspend(self):
|
def suspend(self):
|
||||||
setattr(sys, self.name, self._old)
|
setattr(sys, self.name, self._old)
|
||||||
|
@ -551,7 +560,7 @@ class SysCaptureBinary(SysCapture):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class DontReadFromInput(object):
|
class DontReadFromInput(six.Iterator):
|
||||||
"""Temporary stub class. Ideally when stdin is accessed, the
|
"""Temporary stub class. Ideally when stdin is accessed, the
|
||||||
capturing should be turned off, with possibly all data captured
|
capturing should be turned off, with possibly all data captured
|
||||||
so far sent to the screen. This should be configurable, though,
|
so far sent to the screen. This should be configurable, though,
|
||||||
|
@ -565,7 +574,10 @@ class DontReadFromInput(object):
|
||||||
raise IOError("reading from stdin while output is captured")
|
raise IOError("reading from stdin while output is captured")
|
||||||
readline = read
|
readline = read
|
||||||
readlines = read
|
readlines = read
|
||||||
__iter__ = read
|
__next__ = read
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self):
|
||||||
raise UnsupportedOperation("redirected stdin is pseudofile, "
|
raise UnsupportedOperation("redirected stdin is pseudofile, "
|
||||||
|
@ -681,3 +693,14 @@ def _py36_windowsconsoleio_workaround(stream):
|
||||||
sys.__stdin__ = sys.stdin = _reopen_stdio(sys.stdin, 'rb')
|
sys.__stdin__ = sys.stdin = _reopen_stdio(sys.stdin, 'rb')
|
||||||
sys.__stdout__ = sys.stdout = _reopen_stdio(sys.stdout, 'wb')
|
sys.__stdout__ = sys.stdout = _reopen_stdio(sys.stdout, 'wb')
|
||||||
sys.__stderr__ = sys.stderr = _reopen_stdio(sys.stderr, 'wb')
|
sys.__stderr__ = sys.stderr = _reopen_stdio(sys.stderr, 'wb')
|
||||||
|
|
||||||
|
|
||||||
|
def _attempt_to_close_capture_file(f):
|
||||||
|
"""Suppress IOError when closing the temporary file used for capturing streams in py27 (#2370)"""
|
||||||
|
if six.PY2:
|
||||||
|
try:
|
||||||
|
f.close()
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
f.close()
|
||||||
|
|
|
@ -171,7 +171,7 @@ class PytestPluginManager(PluginManager):
|
||||||
Overwrites :py:class:`pluggy.PluginManager <pluggy.PluginManager>` to add pytest-specific
|
Overwrites :py:class:`pluggy.PluginManager <pluggy.PluginManager>` to add pytest-specific
|
||||||
functionality:
|
functionality:
|
||||||
|
|
||||||
* loading plugins from the command line, ``PYTEST_PLUGIN`` env variable and
|
* loading plugins from the command line, ``PYTEST_PLUGINS`` env variable and
|
||||||
``pytest_plugins`` global variables found in plugins being loaded;
|
``pytest_plugins`` global variables found in plugins being loaded;
|
||||||
* ``conftest.py`` loading during start-up;
|
* ``conftest.py`` loading during start-up;
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -462,6 +462,6 @@ def _fix_spoof_python2(runner, encoding):
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def doctest_namespace():
|
def doctest_namespace():
|
||||||
"""
|
"""
|
||||||
Inject names into the doctest namespace.
|
Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests.
|
||||||
"""
|
"""
|
||||||
return dict()
|
return dict()
|
||||||
|
|
|
@ -858,7 +858,7 @@ class FixtureFunctionMarker(object):
|
||||||
|
|
||||||
|
|
||||||
def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
|
def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
|
||||||
""" (return a) decorator to mark a fixture factory function.
|
"""Decorator to mark a fixture factory function.
|
||||||
|
|
||||||
This decorator can be used (with or without parameters) to define a
|
This decorator can be used (with or without parameters) to define a
|
||||||
fixture function. The name of the fixture function can later be
|
fixture function. The name of the fixture function can later be
|
||||||
|
@ -923,7 +923,15 @@ defaultfuncargprefixmarker = fixture()
|
||||||
|
|
||||||
@fixture(scope="session")
|
@fixture(scope="session")
|
||||||
def pytestconfig(request):
|
def pytestconfig(request):
|
||||||
""" the pytest config object with access to command line opts."""
|
"""Session-scoped fixture that returns the :class:`_pytest.config.Config` object.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
def test_foo(pytestconfig):
|
||||||
|
if pytestconfig.getoption("verbose"):
|
||||||
|
...
|
||||||
|
|
||||||
|
"""
|
||||||
return request.config
|
return request.config
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,13 @@ def record_property(request):
|
||||||
"""Add an extra properties the calling test.
|
"""Add an extra properties the calling test.
|
||||||
User properties become part of the test report and are available to the
|
User properties become part of the test report and are available to the
|
||||||
configured reporters, like JUnit XML.
|
configured reporters, like JUnit XML.
|
||||||
The fixture is callable with ``(name, value)``.
|
The fixture is callable with ``(name, value)``, with value being automatically
|
||||||
|
xml-encoded.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
def test_function(record_property):
|
||||||
|
record_property("example_key", 1)
|
||||||
"""
|
"""
|
||||||
request.node.warn(
|
request.node.warn(
|
||||||
code='C3',
|
code='C3',
|
||||||
|
|
|
@ -176,6 +176,10 @@ class LogCaptureHandler(logging.StreamHandler):
|
||||||
self.records.append(record)
|
self.records.append(record)
|
||||||
logging.StreamHandler.emit(self, record)
|
logging.StreamHandler.emit(self, record)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.records = []
|
||||||
|
self.stream = py.io.TextIO()
|
||||||
|
|
||||||
|
|
||||||
class LogCaptureFixture(object):
|
class LogCaptureFixture(object):
|
||||||
"""Provides access and control of log capturing."""
|
"""Provides access and control of log capturing."""
|
||||||
|
@ -197,6 +201,9 @@ class LogCaptureFixture(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def handler(self):
|
def handler(self):
|
||||||
|
"""
|
||||||
|
:rtype: LogCaptureHandler
|
||||||
|
"""
|
||||||
return self._item.catch_log_handler
|
return self._item.catch_log_handler
|
||||||
|
|
||||||
def get_records(self, when):
|
def get_records(self, when):
|
||||||
|
@ -239,8 +246,8 @@ class LogCaptureFixture(object):
|
||||||
return [(r.name, r.levelno, r.getMessage()) for r in self.records]
|
return [(r.name, r.levelno, r.getMessage()) for r in self.records]
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""Reset the list of log records."""
|
"""Reset the list of log records and the captured log text."""
|
||||||
self.handler.records = []
|
self.handler.reset()
|
||||||
|
|
||||||
def set_level(self, level, logger=None):
|
def set_level(self, level, logger=None):
|
||||||
"""Sets the level for capturing of logs. The level will be restored to its previous value at the end of
|
"""Sets the level for capturing of logs. The level will be restored to its previous value at the end of
|
||||||
|
@ -285,6 +292,7 @@ def caplog(request):
|
||||||
* caplog.text() -> string containing formatted log output
|
* caplog.text() -> string containing formatted log output
|
||||||
* caplog.records() -> list of logging.LogRecord instances
|
* caplog.records() -> list of logging.LogRecord instances
|
||||||
* caplog.record_tuples() -> list of (logger_name, level, message) tuples
|
* caplog.record_tuples() -> list of (logger_name, level, message) tuples
|
||||||
|
* caplog.clear() -> clear captured records and formatted log output string
|
||||||
"""
|
"""
|
||||||
result = LogCaptureFixture(request.node)
|
result = LogCaptureFixture(request.node)
|
||||||
yield result
|
yield result
|
||||||
|
|
|
@ -20,6 +20,21 @@ class MarkerError(Exception):
|
||||||
|
|
||||||
|
|
||||||
def param(*values, **kw):
|
def param(*values, **kw):
|
||||||
|
"""Specify a parameter in a `pytest.mark.parametrize`_ call.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("test_input,expected", [
|
||||||
|
("3+5", 8),
|
||||||
|
pytest.param("6*9", 42, marks=pytest.mark.xfail),
|
||||||
|
])
|
||||||
|
def test_eval(test_input, expected):
|
||||||
|
assert eval(test_input) == expected
|
||||||
|
|
||||||
|
:param values: variable args of the values of the parameter set, in order.
|
||||||
|
:keyword marks: a single mark or a list of marks to be applied to this parameter set.
|
||||||
|
:keyword str id: the id to attribute to this parameter set.
|
||||||
|
"""
|
||||||
return ParameterSet.param(*values, **kw)
|
return ParameterSet.param(*values, **kw)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ class MonkeyPatch(object):
|
||||||
For convenience you can specify a string as ``target`` which
|
For convenience you can specify a string as ``target`` which
|
||||||
will be interpreted as a dotted import path, with the last part
|
will be interpreted as a dotted import path, with the last part
|
||||||
being the attribute name. Example:
|
being the attribute name. Example:
|
||||||
``monkeypatch.setattr("os.getcwd", lambda x: "/")``
|
``monkeypatch.setattr("os.getcwd", lambda: "/")``
|
||||||
would set the ``getcwd`` function of the ``os`` module.
|
would set the ``getcwd`` function of the ``os`` module.
|
||||||
|
|
||||||
The ``raising`` value determines if the setattr should fail
|
The ``raising`` value determines if the setattr should fail
|
||||||
|
|
|
@ -717,7 +717,7 @@ class CallSpec2(object):
|
||||||
|
|
||||||
class Metafunc(fixtures.FuncargnamesCompatAttr):
|
class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||||
"""
|
"""
|
||||||
Metafunc objects are passed to the ``pytest_generate_tests`` hook.
|
Metafunc objects are passed to the :func:`pytest_generate_tests <_pytest.hookspec.pytest_generate_tests>` hook.
|
||||||
They help to inspect a test function and to generate tests according to
|
They help to inspect a test function and to generate tests according to
|
||||||
test configuration or values specified in the class or module where a
|
test configuration or values specified in the class or module where a
|
||||||
test function is defined.
|
test function is defined.
|
||||||
|
|
|
@ -548,8 +548,9 @@ def raises(expected_exception, *args, **kwargs):
|
||||||
The string will be evaluated using the same ``locals()`` and ``globals()``
|
The string will be evaluated using the same ``locals()`` and ``globals()``
|
||||||
at the moment of the ``raises`` call.
|
at the moment of the ``raises`` call.
|
||||||
|
|
||||||
.. autoclass:: _pytest._code.ExceptionInfo
|
.. currentmodule:: _pytest._code
|
||||||
:members:
|
|
||||||
|
Consult the API of ``excinfo`` objects: :class:`ExceptionInfo`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Similar to caught exception objects in Python, explicitly clearing
|
Similar to caught exception objects in Python, explicitly clearing
|
||||||
|
|
|
@ -16,10 +16,7 @@ from _pytest.outcomes import fail
|
||||||
|
|
||||||
@yield_fixture
|
@yield_fixture
|
||||||
def recwarn():
|
def recwarn():
|
||||||
"""Return a WarningsRecorder instance that provides these methods:
|
"""Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.
|
||||||
|
|
||||||
* ``pop(category=None)``: return last warning matching the category.
|
|
||||||
* ``clear()``: clear list of warnings
|
|
||||||
|
|
||||||
See http://docs.python.org/library/warnings.html for information
|
See http://docs.python.org/library/warnings.html for information
|
||||||
on warning categories.
|
on warning categories.
|
||||||
|
@ -88,11 +85,11 @@ class _DeprecatedCallContext(object):
|
||||||
def warns(expected_warning, *args, **kwargs):
|
def warns(expected_warning, *args, **kwargs):
|
||||||
"""Assert that code raises a particular class of warning.
|
"""Assert that code raises a particular class of warning.
|
||||||
|
|
||||||
Specifically, the input @expected_warning can be a warning class or
|
Specifically, the parameter ``expected_warning`` can be a warning class or
|
||||||
tuple of warning classes, and the code must return that warning
|
sequence of warning classes, and the inside the ``with`` block must issue a warning of that class or
|
||||||
(if a single class) or one of those warnings (if a tuple).
|
classes.
|
||||||
|
|
||||||
This helper produces a list of ``warnings.WarningMessage`` objects,
|
This helper produces a list of :class:`warnings.WarningMessage` objects,
|
||||||
one for each warning raised.
|
one for each warning raised.
|
||||||
|
|
||||||
This function can be used as a context manager, or any of the other ways
|
This function can be used as a context manager, or any of the other ways
|
||||||
|
|
|
@ -116,6 +116,8 @@ def tmpdir(request, tmpdir_factory):
|
||||||
created as a sub directory of the base temporary
|
created as a sub directory of the base temporary
|
||||||
directory. The returned object is a `py.path.local`_
|
directory. The returned object is a `py.path.local`_
|
||||||
path object.
|
path object.
|
||||||
|
|
||||||
|
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
|
||||||
"""
|
"""
|
||||||
name = request.node.name
|
name = request.node.name
|
||||||
name = re.sub(r"[\W]", "_", name)
|
name = re.sub(r"[\W]", "_", name)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added a `reference <https://docs.pytest.org/en/latest/reference.html>`_ page to the docs.
|
|
@ -0,0 +1 @@
|
||||||
|
Suppress ``IOError`` when closing the temporary file used for capturing streams in Python 2.7.
|
|
@ -0,0 +1 @@
|
||||||
|
Added ``doc`` to norecursedirs in tox.ini
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed ``clear()`` method on ``caplog`` fixture which cleared ``records``,
|
||||||
|
but not the ``text`` property.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix a python example when calling a fixture in doc/en/usage.rst
|
|
@ -0,0 +1,3 @@
|
||||||
|
During test collection, when stdin is not allowed to be read, the
|
||||||
|
``DontReadFromStdin`` object still allow itself to be iterable and
|
||||||
|
resolved to an iterator without crashing.
|
|
@ -2,15 +2,16 @@
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ pathto('index') }}">Home</a></li>
|
<li><a href="{{ pathto('index') }}">Home</a></li>
|
||||||
<li><a href="{{ pathto('contents') }}">Contents</a></li>
|
|
||||||
<li><a href="{{ pathto('getting-started') }}">Install</a></li>
|
<li><a href="{{ pathto('getting-started') }}">Install</a></li>
|
||||||
|
<li><a href="{{ pathto('contents') }}">Contents</a></li>
|
||||||
|
<li><a href="{{ pathto('reference') }}">Reference</a></li>
|
||||||
<li><a href="{{ pathto('example/index') }}">Examples</a></li>
|
<li><a href="{{ pathto('example/index') }}">Examples</a></li>
|
||||||
<li><a href="{{ pathto('customize') }}">Customize</a></li>
|
<li><a href="{{ pathto('customize') }}">Customize</a></li>
|
||||||
<li><a href="{{ pathto('contact') }}">Contact</a></li>
|
|
||||||
<li><a href="{{ pathto('talks') }}">Talks/Posts</a></li>
|
|
||||||
<li><a href="{{ pathto('changelog') }}">Changelog</a></li>
|
<li><a href="{{ pathto('changelog') }}">Changelog</a></li>
|
||||||
|
<li><a href="{{ pathto('contributing') }}">Contributing</a></li>
|
||||||
<li><a href="{{ pathto('backwards-compatibility') }}">Backwards Compatibility</a></li>
|
<li><a href="{{ pathto('backwards-compatibility') }}">Backwards Compatibility</a></li>
|
||||||
<li><a href="{{ pathto('license') }}">License</a></li>
|
<li><a href="{{ pathto('license') }}">License</a></li>
|
||||||
|
<li><a href="{{ pathto('contact') }}">Contact Channels</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{%- if display_toc %}
|
{%- if display_toc %}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
<h3>Useful Links</h3>
|
<h3>Useful Links</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ pathto('index') }}">The pytest Website</a></li>
|
|
||||||
<li><a href="{{ pathto('contributing') }}">Contribution Guide</a></li>
|
|
||||||
<li><a href="https://pypi.python.org/pypi/pytest">pytest @ PyPI</a></li>
|
<li><a href="https://pypi.python.org/pypi/pytest">pytest @ PyPI</a></li>
|
||||||
<li><a href="https://github.com/pytest-dev/pytest/">pytest @ GitHub</a></li>
|
<li><a href="https://github.com/pytest-dev/pytest/">pytest @ GitHub</a></li>
|
||||||
<li><a href="http://plugincompat.herokuapp.com/">3rd party plugins</a></li>
|
<li><a href="http://plugincompat.herokuapp.com/">3rd party plugins</a></li>
|
||||||
|
|
|
@ -1,166 +1,24 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
.. _`pytest helpers`:
|
.. _`pytest helpers`:
|
||||||
|
|
||||||
Pytest API and builtin fixtures
|
Pytest API and builtin fixtures
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
This is a list of ``pytest.*`` API functions and fixtures.
|
|
||||||
|
Most of the information of this page has been moved over to :ref:`reference`.
|
||||||
|
|
||||||
For information on plugin hooks and objects, see :ref:`plugins`.
|
For information on plugin hooks and objects, see :ref:`plugins`.
|
||||||
|
|
||||||
For information on the ``pytest.mark`` mechanism, see :ref:`mark`.
|
For information on the ``pytest.mark`` mechanism, see :ref:`mark`.
|
||||||
|
|
||||||
For the below objects, you can also interactively ask for help, e.g. by
|
For information about fixtures, see :ref:`fixtures`. To see a complete list of available fixtures, type::
|
||||||
typing on the Python interactive prompt something like::
|
|
||||||
|
$ pytest -q --fixtures
|
||||||
|
|
||||||
|
|
||||||
|
You can also interactively ask for help, e.g. by typing on the Python interactive prompt something like::
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
help(pytest)
|
help(pytest)
|
||||||
|
|
||||||
.. currentmodule:: pytest
|
|
||||||
|
|
||||||
Invoking pytest interactively
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
.. autofunction:: main
|
|
||||||
|
|
||||||
More examples at :ref:`pytest.main-usage`
|
|
||||||
|
|
||||||
|
|
||||||
Helpers for assertions about Exceptions/Warnings
|
|
||||||
--------------------------------------------------------
|
|
||||||
|
|
||||||
.. autofunction:: raises
|
|
||||||
|
|
||||||
Examples at :ref:`assertraises`.
|
|
||||||
|
|
||||||
.. autofunction:: deprecated_call
|
|
||||||
|
|
||||||
Comparing floating point numbers
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
.. autofunction:: approx
|
|
||||||
|
|
||||||
Raising a specific test outcome
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
You can use the following functions in your test, fixture or setup
|
|
||||||
functions to force a certain test outcome. Note that most often
|
|
||||||
you can rather use declarative marks, see :ref:`skipping`.
|
|
||||||
|
|
||||||
.. autofunction:: _pytest.outcomes.fail
|
|
||||||
.. autofunction:: _pytest.outcomes.skip
|
|
||||||
.. autofunction:: _pytest.outcomes.importorskip
|
|
||||||
.. autofunction:: _pytest.outcomes.xfail
|
|
||||||
.. autofunction:: _pytest.outcomes.exit
|
|
||||||
|
|
||||||
Fixtures and requests
|
|
||||||
-----------------------------------------------------
|
|
||||||
|
|
||||||
To mark a fixture function:
|
|
||||||
|
|
||||||
.. autofunction:: _pytest.fixtures.fixture
|
|
||||||
|
|
||||||
Tutorial at :ref:`fixtures`.
|
|
||||||
|
|
||||||
The ``request`` object that can be used from fixture functions.
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.fixtures.FixtureRequest()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
||||||
.. _builtinfixtures:
|
|
||||||
.. _builtinfuncargs:
|
|
||||||
|
|
||||||
Builtin fixtures/function arguments
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
You can ask for available builtin or project-custom
|
|
||||||
:ref:`fixtures <fixtures>` by typing::
|
|
||||||
|
|
||||||
$ pytest -q --fixtures
|
|
||||||
cache
|
|
||||||
Return a cache object that can persist state between testing sessions.
|
|
||||||
|
|
||||||
cache.get(key, default)
|
|
||||||
cache.set(key, value)
|
|
||||||
|
|
||||||
Keys must be a ``/`` separated value, where the first part is usually the
|
|
||||||
name of your plugin or application to avoid clashes with other cache users.
|
|
||||||
|
|
||||||
Values can be any object handled by the json stdlib module.
|
|
||||||
capsys
|
|
||||||
Enable capturing of writes to sys.stdout/sys.stderr and make
|
|
||||||
captured output available via ``capsys.readouterr()`` method calls
|
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``text``
|
|
||||||
objects.
|
|
||||||
capsysbinary
|
|
||||||
Enable capturing of writes to sys.stdout/sys.stderr and make
|
|
||||||
captured output available via ``capsys.readouterr()`` method calls
|
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``bytes``
|
|
||||||
objects.
|
|
||||||
capfd
|
|
||||||
Enable capturing of writes to file descriptors 1 and 2 and make
|
|
||||||
captured output available via ``capfd.readouterr()`` method calls
|
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be ``text``
|
|
||||||
objects.
|
|
||||||
capfdbinary
|
|
||||||
Enable capturing of write to file descriptors 1 and 2 and make
|
|
||||||
captured output available via ``capfdbinary.readouterr`` method calls
|
|
||||||
which return a ``(out, err)`` tuple. ``out`` and ``err`` will be
|
|
||||||
``bytes`` objects.
|
|
||||||
doctest_namespace
|
|
||||||
Inject names into the doctest namespace.
|
|
||||||
pytestconfig
|
|
||||||
the pytest config object with access to command line opts.
|
|
||||||
record_property
|
|
||||||
Add an extra properties the calling test.
|
|
||||||
User properties become part of the test report and are available to the
|
|
||||||
configured reporters, like JUnit XML.
|
|
||||||
The fixture is callable with ``(name, value)``.
|
|
||||||
record_xml_attribute
|
|
||||||
Add extra xml attributes to the tag for the calling test.
|
|
||||||
The fixture is callable with ``(name, value)``, with value being automatically
|
|
||||||
xml-encoded
|
|
||||||
caplog
|
|
||||||
Access and control log capturing.
|
|
||||||
|
|
||||||
Captured logs are available through the following methods::
|
|
||||||
|
|
||||||
* caplog.text() -> string containing formatted log output
|
|
||||||
* caplog.records() -> list of logging.LogRecord instances
|
|
||||||
* caplog.record_tuples() -> list of (logger_name, level, message) tuples
|
|
||||||
monkeypatch
|
|
||||||
The returned ``monkeypatch`` fixture provides these
|
|
||||||
helper methods to modify objects, dictionaries or os.environ::
|
|
||||||
|
|
||||||
monkeypatch.setattr(obj, name, value, raising=True)
|
|
||||||
monkeypatch.delattr(obj, name, raising=True)
|
|
||||||
monkeypatch.setitem(mapping, name, value)
|
|
||||||
monkeypatch.delitem(obj, name, raising=True)
|
|
||||||
monkeypatch.setenv(name, value, prepend=False)
|
|
||||||
monkeypatch.delenv(name, value, raising=True)
|
|
||||||
monkeypatch.syspath_prepend(path)
|
|
||||||
monkeypatch.chdir(path)
|
|
||||||
|
|
||||||
All modifications will be undone after the requesting
|
|
||||||
test function or fixture has finished. The ``raising``
|
|
||||||
parameter determines if a KeyError or AttributeError
|
|
||||||
will be raised if the set/deletion operation has no target.
|
|
||||||
recwarn
|
|
||||||
Return a WarningsRecorder instance that provides these methods:
|
|
||||||
|
|
||||||
* ``pop(category=None)``: return last warning matching the category.
|
|
||||||
* ``clear()``: clear list of warnings
|
|
||||||
|
|
||||||
See http://docs.python.org/library/warnings.html for information
|
|
||||||
on warning categories.
|
|
||||||
tmpdir_factory
|
|
||||||
Return a TempdirFactory instance for the test session.
|
|
||||||
tmpdir
|
|
||||||
Return a temporary directory path object
|
|
||||||
which is unique to each test function invocation,
|
|
||||||
created as a sub directory of the base temporary
|
|
||||||
directory. The returned object is a `py.path.local`_
|
|
||||||
path object.
|
|
||||||
|
|
||||||
no tests ran in 0.12 seconds
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ the cache and this will be quick::
|
||||||
test_caching.py:14: AssertionError
|
test_caching.py:14: AssertionError
|
||||||
1 failed in 0.12 seconds
|
1 failed in 0.12 seconds
|
||||||
|
|
||||||
See the `cache-api`_ for more details.
|
See the :ref:`cache-api` for more details.
|
||||||
|
|
||||||
|
|
||||||
Inspecting Cache content
|
Inspecting Cache content
|
||||||
|
@ -251,22 +251,3 @@ servers where isolation and correctness is more important
|
||||||
than speed.
|
than speed.
|
||||||
|
|
||||||
|
|
||||||
.. _`cache-api`:
|
|
||||||
|
|
||||||
config.cache API
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The ``config.cache`` object allows other plugins,
|
|
||||||
including ``conftest.py`` files,
|
|
||||||
to safely and flexibly store and retrieve values across
|
|
||||||
test runs because the ``config`` object is available
|
|
||||||
in many places.
|
|
||||||
|
|
||||||
Under the hood, the cache plugin uses the simple
|
|
||||||
dumps/loads API of the json stdlib module
|
|
||||||
|
|
||||||
.. currentmodule:: _pytest.cacheprovider
|
|
||||||
|
|
||||||
.. automethod:: Cache.get
|
|
||||||
.. automethod:: Cache.set
|
|
||||||
.. automethod:: Cache.makedir
|
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
|
|
||||||
import os, sys
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from _pytest import __version__ as version
|
from _pytest import __version__ as version
|
||||||
|
|
||||||
release = ".".join(version.split(".")[:2])
|
release = ".".join(version.split(".")[:2])
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
@ -38,7 +41,7 @@ todo_include_todos = 1
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.autosummary',
|
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.autosummary',
|
||||||
'sphinx.ext.intersphinx', 'sphinx.ext.viewcode']
|
'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', 'sphinxcontrib_trio']
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
@ -310,9 +313,7 @@ texinfo_documents = [
|
||||||
|
|
||||||
|
|
||||||
# Example configuration for intersphinx: refer to the Python standard library.
|
# Example configuration for intersphinx: refer to the Python standard library.
|
||||||
intersphinx_mapping = {'python': ('http://docs.python.org/', None),
|
intersphinx_mapping = {'python': ('http://docs.python.org/3', None)}
|
||||||
# 'lib': ("http://docs.python.org/2.7library/", None),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
|
|
@ -14,7 +14,6 @@ Full pytest documentation
|
||||||
usage
|
usage
|
||||||
existingtestsuite
|
existingtestsuite
|
||||||
assert
|
assert
|
||||||
builtin
|
|
||||||
fixture
|
fixture
|
||||||
monkeypatch
|
monkeypatch
|
||||||
tmpdir
|
tmpdir
|
||||||
|
@ -31,6 +30,7 @@ Full pytest documentation
|
||||||
plugins
|
plugins
|
||||||
writing_plugins
|
writing_plugins
|
||||||
logging
|
logging
|
||||||
|
reference
|
||||||
|
|
||||||
goodpractices
|
goodpractices
|
||||||
pythonpath
|
pythonpath
|
||||||
|
|
|
@ -156,222 +156,4 @@ above will show verbose output because ``-v`` overwrites ``-q``.
|
||||||
Builtin configuration file options
|
Builtin configuration file options
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
Here is a list of builtin configuration options that may be written in a ``pytest.ini``, ``tox.ini`` or ``setup.cfg``
|
For the full list of options consult the :ref:`reference documentation <ini options ref>`.
|
||||||
file, usually located at the root of your repository. All options must be under a ``[pytest]`` section
|
|
||||||
(``[tool:pytest]`` for ``setup.cfg`` files).
|
|
||||||
|
|
||||||
Configuration file options may be overwritten in the command-line by using ``-o/--override``, which can also be
|
|
||||||
passed multiple times. The expected format is ``name=value``. For example::
|
|
||||||
|
|
||||||
pytest -o console_output_style=classic -o cache_dir=/tmp/mycache
|
|
||||||
|
|
||||||
|
|
||||||
.. confval:: minversion
|
|
||||||
|
|
||||||
Specifies a minimal pytest version required for running tests.
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
minversion = 3.0 # will fail if we run with pytest-2.8
|
|
||||||
|
|
||||||
.. confval:: addopts
|
|
||||||
|
|
||||||
Add the specified ``OPTS`` to the set of command line arguments as if they
|
|
||||||
had been specified by the user. Example: if you have this ini file content:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
addopts = --maxfail=2 -rf # exit after 2 failures, report fail info
|
|
||||||
|
|
||||||
issuing ``pytest test_hello.py`` actually means::
|
|
||||||
|
|
||||||
pytest --maxfail=2 -rf test_hello.py
|
|
||||||
|
|
||||||
Default is to add no options.
|
|
||||||
|
|
||||||
.. confval:: norecursedirs
|
|
||||||
|
|
||||||
Set the directory basename patterns to avoid when recursing
|
|
||||||
for test discovery. The individual (fnmatch-style) patterns are
|
|
||||||
applied to the basename of a directory to decide if to recurse into it.
|
|
||||||
Pattern matching characters::
|
|
||||||
|
|
||||||
* matches everything
|
|
||||||
? matches any single character
|
|
||||||
[seq] matches any character in seq
|
|
||||||
[!seq] matches any char not in seq
|
|
||||||
|
|
||||||
Default patterns are ``'.*', 'build', 'dist', 'CVS', '_darcs', '{arch}', '*.egg', 'venv'``.
|
|
||||||
Setting a ``norecursedirs`` replaces the default. Here is an example of
|
|
||||||
how to avoid certain directories:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
norecursedirs = .svn _build tmp*
|
|
||||||
|
|
||||||
This would tell ``pytest`` to not look into typical subversion or
|
|
||||||
sphinx-build directories or into any ``tmp`` prefixed directory.
|
|
||||||
|
|
||||||
Additionally, ``pytest`` will attempt to intelligently identify and ignore a
|
|
||||||
virtualenv by the presence of an activation script. Any directory deemed to
|
|
||||||
be the root of a virtual environment will not be considered during test
|
|
||||||
collection unless ``‑‑collect‑in‑virtualenv`` is given. Note also that
|
|
||||||
``norecursedirs`` takes precedence over ``‑‑collect‑in‑virtualenv``; e.g. if
|
|
||||||
you intend to run tests in a virtualenv with a base directory that matches
|
|
||||||
``'.*'`` you *must* override ``norecursedirs`` in addition to using the
|
|
||||||
``‑‑collect‑in‑virtualenv`` flag.
|
|
||||||
|
|
||||||
.. confval:: testpaths
|
|
||||||
|
|
||||||
.. versionadded:: 2.8
|
|
||||||
|
|
||||||
Sets list of directories that should be searched for tests when
|
|
||||||
no specific directories, files or test ids are given in the command line when
|
|
||||||
executing pytest from the :ref:`rootdir <rootdir>` directory.
|
|
||||||
Useful when all project tests are in a known location to speed up
|
|
||||||
test collection and to avoid picking up undesired tests by accident.
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
testpaths = testing doc
|
|
||||||
|
|
||||||
This tells pytest to only look for tests in ``testing`` and ``doc``
|
|
||||||
directories when executing from the root directory.
|
|
||||||
|
|
||||||
.. confval:: python_files
|
|
||||||
|
|
||||||
One or more Glob-style file patterns determining which python files
|
|
||||||
are considered as test modules. By default, pytest will consider
|
|
||||||
any file matching with ``test_*.py`` and ``*_test.py`` globs as a test
|
|
||||||
module.
|
|
||||||
|
|
||||||
.. confval:: python_classes
|
|
||||||
|
|
||||||
One or more name prefixes or glob-style patterns determining which classes
|
|
||||||
are considered for test collection. By default, pytest will consider any
|
|
||||||
class prefixed with ``Test`` as a test collection. Here is an example of how
|
|
||||||
to collect tests from classes that end in ``Suite``:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
python_classes = *Suite
|
|
||||||
|
|
||||||
Note that ``unittest.TestCase`` derived classes are always collected
|
|
||||||
regardless of this option, as ``unittest``'s own collection framework is used
|
|
||||||
to collect those tests.
|
|
||||||
|
|
||||||
.. confval:: python_functions
|
|
||||||
|
|
||||||
One or more name prefixes or glob-patterns determining which test functions
|
|
||||||
and methods are considered tests. By default, pytest will consider any
|
|
||||||
function prefixed with ``test`` as a test. Here is an example of how
|
|
||||||
to collect test functions and methods that end in ``_test``:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
python_functions = *_test
|
|
||||||
|
|
||||||
Note that this has no effect on methods that live on a ``unittest
|
|
||||||
.TestCase`` derived class, as ``unittest``'s own collection framework is used
|
|
||||||
to collect those tests.
|
|
||||||
|
|
||||||
See :ref:`change naming conventions` for more detailed examples.
|
|
||||||
|
|
||||||
.. confval:: doctest_optionflags
|
|
||||||
|
|
||||||
One or more doctest flag names from the standard ``doctest`` module.
|
|
||||||
:doc:`See how pytest handles doctests <doctest>`.
|
|
||||||
|
|
||||||
.. confval:: confcutdir
|
|
||||||
|
|
||||||
Sets a directory where search upwards for ``conftest.py`` files stops.
|
|
||||||
By default, pytest will stop searching for ``conftest.py`` files upwards
|
|
||||||
from ``pytest.ini``/``tox.ini``/``setup.cfg`` of the project if any,
|
|
||||||
or up to the file-system root.
|
|
||||||
|
|
||||||
|
|
||||||
.. confval:: filterwarnings
|
|
||||||
|
|
||||||
.. versionadded:: 3.1
|
|
||||||
|
|
||||||
Sets a list of filters and actions that should be taken for matched
|
|
||||||
warnings. By default all warnings emitted during the test session
|
|
||||||
will be displayed in a summary at the end of the test session.
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
filterwarnings =
|
|
||||||
error
|
|
||||||
ignore::DeprecationWarning
|
|
||||||
|
|
||||||
This tells pytest to ignore deprecation warnings and turn all other warnings
|
|
||||||
into errors. For more information please refer to :ref:`warnings`.
|
|
||||||
|
|
||||||
.. confval:: cache_dir
|
|
||||||
|
|
||||||
.. versionadded:: 3.2
|
|
||||||
|
|
||||||
Sets a directory where stores content of cache plugin. Default directory is
|
|
||||||
``.cache`` which is created in :ref:`rootdir <rootdir>`. Directory may be
|
|
||||||
relative or absolute path. If setting relative path, then directory is created
|
|
||||||
relative to :ref:`rootdir <rootdir>`. Additionally path may contain environment
|
|
||||||
variables, that will be expanded. For more information about cache plugin
|
|
||||||
please refer to :ref:`cache_provider`.
|
|
||||||
|
|
||||||
|
|
||||||
.. confval:: console_output_style
|
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
|
||||||
|
|
||||||
Sets the console output style while running tests:
|
|
||||||
|
|
||||||
* ``classic``: classic pytest output.
|
|
||||||
* ``progress``: like classic pytest output, but with a progress indicator.
|
|
||||||
|
|
||||||
The default is ``progress``, but you can fallback to ``classic`` if you prefer or
|
|
||||||
the new mode is causing unexpected problems:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
console_output_style = classic
|
|
||||||
|
|
||||||
|
|
||||||
.. confval:: empty_parameter_set_mark
|
|
||||||
|
|
||||||
.. versionadded:: 3.4
|
|
||||||
|
|
||||||
Allows to pick the action for empty parametersets in parameterization
|
|
||||||
|
|
||||||
* ``skip`` skips tests with a empty parameterset (default)
|
|
||||||
* ``xfail`` marks tests with a empty parameterset as xfail(run=False)
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
# content of pytest.ini
|
|
||||||
[pytest]
|
|
||||||
empty_parameter_set_mark = xfail
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The default value of this option is planned to change to ``xfail`` in future releases
|
|
||||||
as this is considered less error prone, see `#3155`_ for more details.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _`#3155`: https://github.com/pytest-dev/pytest/issues/3155
|
|
||||||
|
|
|
@ -121,6 +121,8 @@ you want to continue the test even when you have failures, do::
|
||||||
pytest --doctest-modules --doctest-continue-on-failure
|
pytest --doctest-modules --doctest-continue-on-failure
|
||||||
|
|
||||||
|
|
||||||
|
.. _`doctest_namespace`:
|
||||||
|
|
||||||
The 'doctest_namespace' fixture
|
The 'doctest_namespace' fixture
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
Basic patterns and examples
|
Basic patterns and examples
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
|
.. _request example:
|
||||||
|
|
||||||
Pass different values to a test function, depending on command line options
|
Pass different values to a test function, depending on command line options
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -764,6 +766,8 @@ and run it::
|
||||||
You'll see that the fixture finalizers could use the precise reporting
|
You'll see that the fixture finalizers could use the precise reporting
|
||||||
information.
|
information.
|
||||||
|
|
||||||
|
.. _pytest current test env:
|
||||||
|
|
||||||
``PYTEST_CURRENT_TEST`` environment variable
|
``PYTEST_CURRENT_TEST`` environment variable
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -172,9 +172,10 @@ Continue reading
|
||||||
Check out additional pytest resources to help you customize tests for your unique workflow:
|
Check out additional pytest resources to help you customize tests for your unique workflow:
|
||||||
|
|
||||||
* ":ref:`cmdline`" for command line invocation examples
|
* ":ref:`cmdline`" for command line invocation examples
|
||||||
* ":ref:`goodpractices`" for virtualenv and test layouts
|
|
||||||
* ":ref:`existingtestsuite`" for working with pre-existing tests
|
* ":ref:`existingtestsuite`" for working with pre-existing tests
|
||||||
|
* ":ref:`mark`" for information on the ``pytest.mark`` mechanism
|
||||||
* ":ref:`fixtures`" for providing a functional baseline to your tests
|
* ":ref:`fixtures`" for providing a functional baseline to your tests
|
||||||
* ":ref:`plugins`" for managing and writing plugins
|
* ":ref:`plugins`" for managing and writing plugins
|
||||||
|
* ":ref:`goodpractices`" for virtualenv and test layouts
|
||||||
|
|
||||||
.. include:: links.inc
|
.. include:: links.inc
|
||||||
|
|
|
@ -144,11 +144,9 @@ the records for the ``setup`` and ``call`` stages during teardown like so:
|
||||||
pytest.fail('warning messages encountered during testing: {}'.format(messages))
|
pytest.fail('warning messages encountered during testing: {}'.format(messages))
|
||||||
|
|
||||||
|
|
||||||
caplog fixture API
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.logging.LogCaptureFixture
|
The full API is available at :class:`_pytest.logging.LogCaptureFixture`.
|
||||||
:members:
|
|
||||||
|
|
||||||
.. _live_logs:
|
.. _live_logs:
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
Marking test functions with attributes
|
Marking test functions with attributes
|
||||||
=================================================================
|
=================================================================
|
||||||
|
|
||||||
.. currentmodule:: _pytest.mark
|
|
||||||
|
|
||||||
By using the ``pytest.mark`` helper you can easily set
|
By using the ``pytest.mark`` helper you can easily set
|
||||||
metadata on your test functions. There are
|
metadata on your test functions. There are
|
||||||
|
@ -27,15 +26,3 @@ which also serve as documentation.
|
||||||
:ref:`fixtures <fixtures>`.
|
:ref:`fixtures <fixtures>`.
|
||||||
|
|
||||||
|
|
||||||
API reference for mark related objects
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
.. autoclass:: MarkGenerator
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: MarkDecorator
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: MarkInfo
|
|
||||||
:members:
|
|
||||||
|
|
||||||
|
|
|
@ -63,13 +63,9 @@ so that any attempts within tests to create http requests will fail.
|
||||||
help although there's no guarantee.
|
help although there's no guarantee.
|
||||||
|
|
||||||
|
|
||||||
Method reference of the monkeypatch fixture
|
.. currentmodule:: _pytest.monkeypatch
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
.. autoclass:: MonkeyPatch
|
API Reference
|
||||||
:members:
|
-------------
|
||||||
|
|
||||||
``monkeypatch.setattr/delattr/delitem/delenv()`` all
|
|
||||||
by default raise an Exception if the target does not exist.
|
|
||||||
Pass ``raising=False`` if you want to skip this check.
|
|
||||||
|
|
||||||
|
Consult the docs for the :class:`MonkeyPatch` class.
|
||||||
|
|
|
@ -33,7 +33,7 @@ pytest enables test parametrization at several levels:
|
||||||
.. versionchanged:: 2.4
|
.. versionchanged:: 2.4
|
||||||
Several improvements.
|
Several improvements.
|
||||||
|
|
||||||
The builtin ``pytest.mark.parametrize`` decorator enables
|
The builtin :ref:`pytest.mark.parametrize ref` decorator enables
|
||||||
parametrization of arguments for a test function. Here is a typical example
|
parametrization of arguments for a test function. Here is a typical example
|
||||||
of a test function that implements checking that a certain input leads
|
of a test function that implements checking that a certain input leads
|
||||||
to an expected output::
|
to an expected output::
|
||||||
|
@ -206,12 +206,3 @@ More examples
|
||||||
|
|
||||||
For further examples, you might want to look at :ref:`more
|
For further examples, you might want to look at :ref:`more
|
||||||
parametrization examples <paramexamples>`.
|
parametrization examples <paramexamples>`.
|
||||||
|
|
||||||
.. _`metafunc object`:
|
|
||||||
|
|
||||||
The **metafunc** object
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
.. currentmodule:: _pytest.python
|
|
||||||
.. autoclass:: Metafunc
|
|
||||||
:members:
|
|
||||||
|
|
|
@ -61,10 +61,11 @@ status against different pytest and Python versions, please visit
|
||||||
|
|
||||||
You may also discover more plugins through a `pytest- pypi.python.org search`_.
|
You may also discover more plugins through a `pytest- pypi.python.org search`_.
|
||||||
|
|
||||||
.. _`available installable plugins`:
|
|
||||||
.. _`pytest- pypi.python.org search`: http://pypi.python.org/pypi?%3Aaction=search&term=pytest-&submit=search
|
.. _`pytest- pypi.python.org search`: http://pypi.python.org/pypi?%3Aaction=search&term=pytest-&submit=search
|
||||||
|
|
||||||
|
|
||||||
|
.. _`available installable plugins`:
|
||||||
|
|
||||||
Requiring/Loading plugins in a test module or conftest file
|
Requiring/Loading plugins in a test module or conftest file
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
@ -120,36 +121,3 @@ CI server), you can set ``PYTEST_ADDOPTS`` environment variable to
|
||||||
See :ref:`findpluginname` for how to obtain the name of a plugin.
|
See :ref:`findpluginname` for how to obtain the name of a plugin.
|
||||||
|
|
||||||
.. _`builtin plugins`:
|
.. _`builtin plugins`:
|
||||||
|
|
||||||
Pytest default plugin reference
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
You can find the source code for the following plugins
|
|
||||||
in the `pytest repository <https://github.com/pytest-dev/pytest>`_.
|
|
||||||
|
|
||||||
.. autosummary::
|
|
||||||
|
|
||||||
_pytest.assertion
|
|
||||||
_pytest.cacheprovider
|
|
||||||
_pytest.capture
|
|
||||||
_pytest.config
|
|
||||||
_pytest.doctest
|
|
||||||
_pytest.helpconfig
|
|
||||||
_pytest.junitxml
|
|
||||||
_pytest.mark
|
|
||||||
_pytest.monkeypatch
|
|
||||||
_pytest.nose
|
|
||||||
_pytest.pastebin
|
|
||||||
_pytest.debugging
|
|
||||||
_pytest.pytester
|
|
||||||
_pytest.python
|
|
||||||
_pytest.recwarn
|
|
||||||
_pytest.resultlog
|
|
||||||
_pytest.runner
|
|
||||||
_pytest.main
|
|
||||||
_pytest.logging
|
|
||||||
_pytest.skipping
|
|
||||||
_pytest.terminal
|
|
||||||
_pytest.tmpdir
|
|
||||||
_pytest.unittest
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,4 @@
|
||||||
# pinning sphinx to 1.4.* due to search issues with rtd:
|
# pinning sphinx to 1.4.* due to search issues with rtd:
|
||||||
# https://github.com/rtfd/readthedocs-sphinx-ext/issues/25
|
# https://github.com/rtfd/readthedocs-sphinx-ext/issues/25
|
||||||
sphinx ==1.4.*
|
sphinx ==1.4.*
|
||||||
|
sphinxcontrib-trio
|
||||||
|
|
|
@ -71,6 +71,8 @@ It is also possible to skip the whole module using
|
||||||
The imperative method is useful when it is not possible to evaluate the skip condition
|
The imperative method is useful when it is not possible to evaluate the skip condition
|
||||||
during import time.
|
during import time.
|
||||||
|
|
||||||
|
**Reference**: :ref:`pytest.mark.skip ref`
|
||||||
|
|
||||||
``skipif``
|
``skipif``
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -116,6 +118,8 @@ Alternatively, you can use :ref:`condition strings
|
||||||
<string conditions>` instead of booleans, but they can't be shared between modules easily
|
<string conditions>` instead of booleans, but they can't be shared between modules easily
|
||||||
so they are supported mainly for backward compatibility reasons.
|
so they are supported mainly for backward compatibility reasons.
|
||||||
|
|
||||||
|
**Reference**: :ref:`pytest.mark.skipif ref`
|
||||||
|
|
||||||
|
|
||||||
Skip all test functions of a class or module
|
Skip all test functions of a class or module
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -232,15 +236,10 @@ This will unconditionally make ``test_function`` ``XFAIL``. Note that no other c
|
||||||
after ``pytest.xfail`` call, differently from the marker. That's because it is implemented
|
after ``pytest.xfail`` call, differently from the marker. That's because it is implemented
|
||||||
internally by raising a known exception.
|
internally by raising a known exception.
|
||||||
|
|
||||||
Here's the signature of the ``xfail`` **marker** (not the function), using Python 3 keyword-only
|
**Reference**: :ref:`pytest.mark.xfail ref`
|
||||||
arguments syntax:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def xfail(condition=None, *, reason=None, raises=None, run=True, strict=False):
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _`xfail strict tutorial`:
|
||||||
|
|
||||||
``strict`` parameter
|
``strict`` parameter
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -51,6 +51,9 @@ Running this would result in a passed test except for the last
|
||||||
test_tmpdir.py:7: AssertionError
|
test_tmpdir.py:7: AssertionError
|
||||||
========================= 1 failed in 0.12 seconds =========================
|
========================= 1 failed in 0.12 seconds =========================
|
||||||
|
|
||||||
|
|
||||||
|
.. _`tmpdir factory example`:
|
||||||
|
|
||||||
The 'tmpdir_factory' fixture
|
The 'tmpdir_factory' fixture
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
@ -81,12 +84,8 @@ to save time:
|
||||||
img = load_image(image_file)
|
img = load_image(image_file)
|
||||||
# compute and test histogram
|
# compute and test histogram
|
||||||
|
|
||||||
``tmpdir_factory`` instances have the following methods:
|
See :ref:`tmpdir_factory API <tmpdir factory api>` for details.
|
||||||
|
|
||||||
.. currentmodule:: _pytest.tmpdir
|
|
||||||
|
|
||||||
.. automethod:: TempdirFactory.mktemp
|
|
||||||
.. automethod:: TempdirFactory.getbasetemp
|
|
||||||
|
|
||||||
.. _`base temporary directory`:
|
.. _`base temporary directory`:
|
||||||
|
|
||||||
|
|
|
@ -220,8 +220,10 @@ To set the name of the root test suite xml item, you can configure the ``junit_s
|
||||||
[pytest]
|
[pytest]
|
||||||
junit_suite_name = my_suite
|
junit_suite_name = my_suite
|
||||||
|
|
||||||
|
.. _record_property example:
|
||||||
|
|
||||||
record_property
|
record_property
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
.. versionadded:: 2.8
|
.. versionadded:: 2.8
|
||||||
.. versionchanged:: 3.5
|
.. versionchanged:: 3.5
|
||||||
|
@ -306,7 +308,7 @@ To add an additional xml attribute to a testcase element, you can use
|
||||||
print('hello world')
|
print('hello world')
|
||||||
assert True
|
assert True
|
||||||
|
|
||||||
Unlike ``record_xml_property``, this will not add a new child element.
|
Unlike ``record_property``, this will not add a new child element.
|
||||||
Instead, this will add an attribute ``assertions="REQ-1234"`` inside the generated
|
Instead, this will add an attribute ``assertions="REQ-1234"`` inside the generated
|
||||||
``testcase`` tag and override the default ``classname`` with ``"classname=custom_classname"``:
|
``testcase`` tag and override the default ``classname`` with ``"classname=custom_classname"``:
|
||||||
|
|
||||||
|
@ -371,7 +373,7 @@ to all testcases you can use ``LogXML.add_global_properties``
|
||||||
my_junit.add_global_property('ARCH', 'PPC')
|
my_junit.add_global_property('ARCH', 'PPC')
|
||||||
my_junit.add_global_property('STORAGE_TYPE', 'CEPH')
|
my_junit.add_global_property('STORAGE_TYPE', 'CEPH')
|
||||||
|
|
||||||
@pytest.mark.usefixtures(log_global_env_facts)
|
@pytest.mark.usefixtures(log_global_env_facts.__name__)
|
||||||
def start_and_prepare_env():
|
def start_and_prepare_env():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -250,23 +250,11 @@ The ``recwarn`` fixture will record warnings for the whole function::
|
||||||
Both ``recwarn`` and ``pytest.warns`` return the same interface for recorded
|
Both ``recwarn`` and ``pytest.warns`` return the same interface for recorded
|
||||||
warnings: a WarningsRecorder instance. To view the recorded warnings, you can
|
warnings: a WarningsRecorder instance. To view the recorded warnings, you can
|
||||||
iterate over this instance, call ``len`` on it to get the number of recorded
|
iterate over this instance, call ``len`` on it to get the number of recorded
|
||||||
warnings, or index into it to get a particular recorded warning. It also
|
warnings, or index into it to get a particular recorded warning.
|
||||||
provides these methods:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.recwarn.WarningsRecorder()
|
.. currentmodule:: _pytest.warnings
|
||||||
:members:
|
|
||||||
|
|
||||||
Each recorded warning has the attributes ``message``, ``category``,
|
Full API: :class:`WarningsRecorder`.
|
||||||
``filename``, ``lineno``, ``file``, and ``line``. The ``category`` is the
|
|
||||||
class of the warning. The ``message`` is the warning itself; calling
|
|
||||||
``str(message)`` will return the actual message of the warning.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
:class:`RecordedWarning` was changed from a plain class to a namedtuple in pytest 3.1
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
``DeprecationWarning`` and ``PendingDeprecationWarning`` are treated
|
|
||||||
differently; see :ref:`ensuring_function_triggers`.
|
|
||||||
|
|
||||||
.. _`ensuring a function triggers a deprecation warning`:
|
.. _`ensuring a function triggers a deprecation warning`:
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ only want to use but not write plugins.
|
||||||
A plugin contains one or multiple hook functions. :ref:`Writing hooks <writinghooks>`
|
A plugin contains one or multiple hook functions. :ref:`Writing hooks <writinghooks>`
|
||||||
explains the basics and details of how you can write a hook function yourself.
|
explains the basics and details of how you can write a hook function yourself.
|
||||||
``pytest`` implements all aspects of configuration, collection, running and
|
``pytest`` implements all aspects of configuration, collection, running and
|
||||||
reporting by calling `well specified hooks`_ of the following plugins:
|
reporting by calling :ref:`well specified hooks <hook-reference>` of the following plugins:
|
||||||
|
|
||||||
* :ref:`builtin plugins`: loaded from pytest's internal ``_pytest`` directory.
|
* builtin plugins: loaded from pytest's internal ``_pytest`` directory.
|
||||||
|
|
||||||
* :ref:`external plugins <extplugins>`: modules discovered through
|
* :ref:`external plugins <extplugins>`: modules discovered through
|
||||||
`setuptools entry points`_
|
`setuptools entry points`_
|
||||||
|
@ -109,10 +109,10 @@ If you want to write a plugin, there are many real-life examples
|
||||||
you can copy from:
|
you can copy from:
|
||||||
|
|
||||||
* a custom collection example plugin: :ref:`yaml plugin`
|
* a custom collection example plugin: :ref:`yaml plugin`
|
||||||
* around 20 :ref:`builtin plugins` which provide pytest's own functionality
|
* builtin plugins which provide pytest's own functionality
|
||||||
* many `external plugins <http://plugincompat.herokuapp.com>`_ providing additional features
|
* many `external plugins <http://plugincompat.herokuapp.com>`_ providing additional features
|
||||||
|
|
||||||
All of these plugins implement the documented `well specified hooks`_
|
All of these plugins implement :ref:`hooks <hook-reference>` and/or :ref:`fixtures <fixture>`
|
||||||
to extend and add functionality.
|
to extend and add functionality.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -167,7 +167,7 @@ it in your setuptools-invocation:
|
||||||
|
|
||||||
If a package is installed this way, ``pytest`` will load
|
If a package is installed this way, ``pytest`` will load
|
||||||
``myproject.pluginmodule`` as a plugin which can define
|
``myproject.pluginmodule`` as a plugin which can define
|
||||||
`well specified hooks`_.
|
:ref:`hooks <hook-reference>`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
@ -176,6 +176,8 @@ If a package is installed this way, ``pytest`` will load
|
||||||
to make it easy for users to find your plugin.
|
to make it easy for users to find your plugin.
|
||||||
|
|
||||||
|
|
||||||
|
.. _assertion-rewriting:
|
||||||
|
|
||||||
Assertion Rewriting
|
Assertion Rewriting
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -196,6 +198,7 @@ assertion rewriting to be enabled you need to ask ``pytest``
|
||||||
explicitly to rewrite this module before it gets imported.
|
explicitly to rewrite this module before it gets imported.
|
||||||
|
|
||||||
.. autofunction:: pytest.register_assert_rewrite
|
.. autofunction:: pytest.register_assert_rewrite
|
||||||
|
:noindex:
|
||||||
|
|
||||||
This is especially important when you write a pytest plugin which is
|
This is especially important when you write a pytest plugin which is
|
||||||
created using a package. The import hook only treats ``conftest.py``
|
created using a package. The import hook only treats ``conftest.py``
|
||||||
|
@ -540,6 +543,7 @@ implemented by other plugins in order to alter behaviour or interact with
|
||||||
the new plugin:
|
the new plugin:
|
||||||
|
|
||||||
.. autofunction:: pytest_addhooks
|
.. autofunction:: pytest_addhooks
|
||||||
|
:noindex:
|
||||||
|
|
||||||
Hooks are usually declared as do-nothing functions that contain only
|
Hooks are usually declared as do-nothing functions that contain only
|
||||||
documentation describing when the hook will be called and what return values
|
documentation describing when the hook will be called and what return values
|
||||||
|
@ -577,191 +581,7 @@ declaring the hook functions directly in your plugin module, for example::
|
||||||
This has the added benefit of allowing you to conditionally install hooks
|
This has the added benefit of allowing you to conditionally install hooks
|
||||||
depending on which plugins are installed.
|
depending on which plugins are installed.
|
||||||
|
|
||||||
.. _`well specified hooks`:
|
|
||||||
|
|
||||||
.. currentmodule:: _pytest.hookspec
|
|
||||||
|
|
||||||
pytest hook reference
|
|
||||||
=====================
|
|
||||||
|
|
||||||
|
|
||||||
Initialization, command line and configuration hooks
|
|
||||||
----------------------------------------------------
|
|
||||||
|
|
||||||
Bootstrapping hooks
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Bootstrapping hooks called for plugins registered early enough (internal and setuptools plugins).
|
|
||||||
|
|
||||||
.. autofunction:: pytest_load_initial_conftests
|
|
||||||
.. autofunction:: pytest_cmdline_preparse
|
|
||||||
.. autofunction:: pytest_cmdline_parse
|
|
||||||
.. autofunction:: pytest_cmdline_main
|
|
||||||
|
|
||||||
Initialization hooks
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Initialization hooks called for plugins and ``conftest.py`` files.
|
|
||||||
|
|
||||||
.. autofunction:: pytest_addoption
|
|
||||||
.. autofunction:: pytest_configure
|
|
||||||
.. autofunction:: pytest_unconfigure
|
|
||||||
|
|
||||||
Generic "runtest" hooks
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
All runtest related hooks receive a :py:class:`pytest.Item <_pytest.main.Item>` object.
|
|
||||||
|
|
||||||
.. autofunction:: pytest_runtestloop
|
|
||||||
.. autofunction:: pytest_runtest_protocol
|
|
||||||
.. autofunction:: pytest_runtest_logstart
|
|
||||||
.. autofunction:: pytest_runtest_logfinish
|
|
||||||
.. autofunction:: pytest_runtest_setup
|
|
||||||
.. autofunction:: pytest_runtest_call
|
|
||||||
.. autofunction:: pytest_runtest_teardown
|
|
||||||
.. autofunction:: pytest_runtest_makereport
|
|
||||||
|
|
||||||
For deeper understanding you may look at the default implementation of
|
|
||||||
these hooks in :py:mod:`_pytest.runner` and maybe also
|
|
||||||
in :py:mod:`_pytest.pdb` which interacts with :py:mod:`_pytest.capture`
|
|
||||||
and its input/output capturing in order to immediately drop
|
|
||||||
into interactive debugging when a test failure occurs.
|
|
||||||
|
|
||||||
The :py:mod:`_pytest.terminal` reported specifically uses
|
|
||||||
the reporting hook to print information about a test run.
|
|
||||||
|
|
||||||
Collection hooks
|
|
||||||
----------------
|
|
||||||
|
|
||||||
``pytest`` calls the following hooks for collecting files and directories:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_collection
|
|
||||||
.. autofunction:: pytest_ignore_collect
|
|
||||||
.. autofunction:: pytest_collect_directory
|
|
||||||
.. autofunction:: pytest_collect_file
|
|
||||||
|
|
||||||
For influencing the collection of objects in Python modules
|
|
||||||
you can use the following hook:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_pycollect_makeitem
|
|
||||||
.. autofunction:: pytest_generate_tests
|
|
||||||
.. autofunction:: pytest_make_parametrize_id
|
|
||||||
|
|
||||||
After collection is complete, you can modify the order of
|
|
||||||
items, delete or otherwise amend the test items:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_collection_modifyitems
|
|
||||||
|
|
||||||
Reporting hooks
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Session related reporting hooks:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_collectstart
|
|
||||||
.. autofunction:: pytest_itemcollected
|
|
||||||
.. autofunction:: pytest_collectreport
|
|
||||||
.. autofunction:: pytest_deselected
|
|
||||||
.. autofunction:: pytest_report_header
|
|
||||||
.. autofunction:: pytest_report_collectionfinish
|
|
||||||
.. autofunction:: pytest_report_teststatus
|
|
||||||
.. autofunction:: pytest_terminal_summary
|
|
||||||
.. autofunction:: pytest_fixture_setup
|
|
||||||
.. autofunction:: pytest_fixture_post_finalizer
|
|
||||||
|
|
||||||
And here is the central hook for reporting about
|
|
||||||
test execution:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_runtest_logreport
|
|
||||||
|
|
||||||
You can also use this hook to customize assertion representation for some
|
|
||||||
types:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_assertrepr_compare
|
|
||||||
|
|
||||||
|
|
||||||
Debugging/Interaction hooks
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
There are few hooks which can be used for special
|
|
||||||
reporting or interaction with exceptions:
|
|
||||||
|
|
||||||
.. autofunction:: pytest_internalerror
|
|
||||||
.. autofunction:: pytest_keyboard_interrupt
|
|
||||||
.. autofunction:: pytest_exception_interact
|
|
||||||
.. autofunction:: pytest_enter_pdb
|
|
||||||
|
|
||||||
|
|
||||||
Reference of objects involved in hooks
|
|
||||||
======================================
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.config.Config()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.config.Parser()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.nodes.Node()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.nodes.Collector()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.nodes.FSCollector()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.main.Session()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.nodes.Item()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.python.Module()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.python.Class()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.python.Function()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.fixtures.FixtureDef()
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.runner.CallInfo()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.runner.TestReport()
|
|
||||||
:members:
|
|
||||||
:inherited-members:
|
|
||||||
|
|
||||||
.. autoclass:: pluggy._Result
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autofunction:: _pytest.config.get_plugin_manager()
|
|
||||||
|
|
||||||
.. autoclass:: _pytest.config.PytestPluginManager()
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
||||||
|
|
||||||
.. autoclass:: pluggy.PluginManager()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. currentmodule:: _pytest.pytester
|
|
||||||
|
|
||||||
.. autoclass:: Testdir()
|
|
||||||
:members: runpytest,runpytest_subprocess,runpytest_inprocess,makeconftest,makepyfile
|
|
||||||
|
|
||||||
.. autoclass:: RunResult()
|
|
||||||
:members:
|
|
||||||
|
|
||||||
.. autoclass:: LineMatcher()
|
|
||||||
:members:
|
|
||||||
|
|
|
@ -95,8 +95,10 @@ def test_clear(caplog):
|
||||||
caplog.set_level(logging.INFO)
|
caplog.set_level(logging.INFO)
|
||||||
logger.info(u'bū')
|
logger.info(u'bū')
|
||||||
assert len(caplog.records)
|
assert len(caplog.records)
|
||||||
|
assert caplog.text
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert not len(caplog.records)
|
assert not len(caplog.records)
|
||||||
|
assert not caplog.text
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
|
@ -751,7 +751,8 @@ def test_dontreadfrominput():
|
||||||
assert not f.isatty()
|
assert not f.isatty()
|
||||||
pytest.raises(IOError, f.read)
|
pytest.raises(IOError, f.read)
|
||||||
pytest.raises(IOError, f.readlines)
|
pytest.raises(IOError, f.readlines)
|
||||||
pytest.raises(IOError, iter, f)
|
iter_f = iter(f)
|
||||||
|
pytest.raises(IOError, next, iter_f)
|
||||||
pytest.raises(UnsupportedOperation, f.fileno)
|
pytest.raises(UnsupportedOperation, f.fileno)
|
||||||
f.close() # just for completeness
|
f.close() # just for completeness
|
||||||
|
|
||||||
|
@ -764,7 +765,8 @@ def test_dontreadfrominput_buffer_python3():
|
||||||
assert not fb.isatty()
|
assert not fb.isatty()
|
||||||
pytest.raises(IOError, fb.read)
|
pytest.raises(IOError, fb.read)
|
||||||
pytest.raises(IOError, fb.readlines)
|
pytest.raises(IOError, fb.readlines)
|
||||||
pytest.raises(IOError, iter, fb)
|
iter_f = iter(f)
|
||||||
|
pytest.raises(IOError, next, iter_f)
|
||||||
pytest.raises(ValueError, fb.fileno)
|
pytest.raises(ValueError, fb.fileno)
|
||||||
f.close() # just for completeness
|
f.close() # just for completeness
|
||||||
|
|
||||||
|
@ -1265,6 +1267,30 @@ def test_dontreadfrominput_has_encoding(testdir):
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_crash_on_closing_tmpfile_py27(testdir):
|
||||||
|
testdir.makepyfile('''
|
||||||
|
from __future__ import print_function
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def spam():
|
||||||
|
f = sys.stderr
|
||||||
|
while True:
|
||||||
|
print('.', end='', file=f)
|
||||||
|
|
||||||
|
def test_silly():
|
||||||
|
t = threading.Thread(target=spam)
|
||||||
|
t.daemon = True
|
||||||
|
t.start()
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
''')
|
||||||
|
result = testdir.runpytest_subprocess()
|
||||||
|
assert result.ret == 0
|
||||||
|
assert 'IOError' not in result.stdout.str()
|
||||||
|
|
||||||
|
|
||||||
def test_pickling_and_unpickling_encoded_file():
|
def test_pickling_and_unpickling_encoded_file():
|
||||||
# See https://bitbucket.org/pytest-dev/pytest/pull-request/194
|
# See https://bitbucket.org/pytest-dev/pytest/pull-request/194
|
||||||
# pickle.loads() raises infinite recursion if
|
# pickle.loads() raises infinite recursion if
|
||||||
|
|
7
tox.ini
7
tox.ini
|
@ -125,12 +125,13 @@ deps =
|
||||||
[testenv:docs]
|
[testenv:docs]
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
basepython = python
|
|
||||||
changedir = doc/en
|
changedir = doc/en
|
||||||
deps =
|
deps =
|
||||||
sphinx
|
|
||||||
attrs
|
attrs
|
||||||
|
more_itertools
|
||||||
PyYAML
|
PyYAML
|
||||||
|
sphinx
|
||||||
|
sphinxcontrib-trio
|
||||||
|
|
||||||
commands =
|
commands =
|
||||||
sphinx-build -W -b html . _build
|
sphinx-build -W -b html . _build
|
||||||
|
@ -204,7 +205,7 @@ rsyncdirs = tox.ini pytest.py _pytest testing
|
||||||
python_files = test_*.py *_test.py testing/*/*.py
|
python_files = test_*.py *_test.py testing/*/*.py
|
||||||
python_classes = Test Acceptance
|
python_classes = Test Acceptance
|
||||||
python_functions = test
|
python_functions = test
|
||||||
norecursedirs = .tox ja .hg cx_freeze_source
|
norecursedirs = .tox ja .hg cx_freeze_source doc
|
||||||
xfail_strict=true
|
xfail_strict=true
|
||||||
filterwarnings =
|
filterwarnings =
|
||||||
error
|
error
|
||||||
|
|
Loading…
Reference in New Issue