Merge pull request #1466 from nicoddemus/merge-master-into-features

Merge master into features after 2.9.1 release
This commit is contained in:
Bruno Oliveira 2016-03-18 23:45:14 -03:00
commit 2cfcf12d09
40 changed files with 367 additions and 103 deletions

View File

@ -2,7 +2,7 @@ Thanks for submitting an issue!
Here's a quick checklist in what to include: Here's a quick checklist in what to include:
[ ] Include a detailed description of the bug or suggestion - [ ] Include a detailed description of the bug or suggestion
[ ] `pip list` of the virtual environment you are using - [ ] `pip list` of the virtual environment you are using
[ ] py.test and operating system versions - [ ] py.test and operating system versions
[ ] Minimal example if possible - [ ] Minimal example if possible

View File

@ -2,7 +2,7 @@ Thanks for submitting a PR, your contribution is really appreciated!
Here's a quick checklist that should be present in PRs: Here's a quick checklist that should be present in PRs:
[ ] Target: for bug or doc fixes, target `master`; for new features, target `features` - [ ] Target: for bug or doc fixes, target `master`; for new features, target `features`
[ ] Make sure to include one or more tests for your change - [ ] Make sure to include one or more tests for your change
[ ] Add yourself to `AUTHORS` - [ ] Add yourself to `AUTHORS`
[ ] Add a new entry to the `CHANGELOG` (choose any open position to avoid merge conflicts with other PRs) - [ ] Add a new entry to the `CHANGELOG` (choose any open position to avoid merge conflicts with other PRs)

View File

@ -10,6 +10,7 @@ Andy Freeland
Anthon van der Neut Anthon van der Neut
Armin Rigo Armin Rigo
Aron Curzon Aron Curzon
Aviv Palivoda
Benjamin Peterson Benjamin Peterson
Bob Ippolito Bob Ippolito
Brian Dorsey Brian Dorsey
@ -23,6 +24,7 @@ Christian Theunert
Christian Tismer Christian Tismer
Christopher Gilling Christopher Gilling
Daniel Grana Daniel Grana
Daniel Hahler
Daniel Nuri Daniel Nuri
Dave Hunt Dave Hunt
David Mohr David Mohr
@ -60,6 +62,7 @@ Marc Schlaich
Mark Abramowitz Mark Abramowitz
Markus Unterwaditzer Markus Unterwaditzer
Martijn Faassen Martijn Faassen
Matt Bachmann
Matt Williams Matt Williams
Michael Aquilina Michael Aquilina
Michael Birtwell Michael Birtwell

View File

@ -40,7 +40,7 @@
.. _#1454: https://github.com/pytest-dev/pytest/pull/1454 .. _#1454: https://github.com/pytest-dev/pytest/pull/1454
2.9.1.dev1 2.9.2.dev1
========== ==========
**Bug Fixes** **Bug Fixes**
@ -51,6 +51,43 @@
* *
*
2.9.1
=====
**Bug Fixes**
* Improve error message when a plugin fails to load.
Thanks `@nicoddemus`_ for the PR.
* Fix (`#1178 <https://github.com/pytest-dev/pytest/issues/1178>`_):
``pytest.fail`` with non-ascii characters raises an internal pytest error.
Thanks `@nicoddemus`_ for the PR.
* Fix (`#469`_): junit parses report.nodeid incorrectly, when params IDs
contain ``::``. Thanks `@tomviner`_ for the PR (`#1431`_).
* Fix (`#578 <https://github.com/pytest-dev/pytest/issues/578>`_): SyntaxErrors
containing non-ascii lines at the point of failure generated an internal
py.test error.
Thanks `@asottile`_ for the report and `@nicoddemus`_ for the PR.
* Fix (`#1437`_): When passing in a bytestring regex pattern to parameterize
attempt to decode it as utf-8 ignoring errors.
* Fix (`#649`_): parametrized test nodes cannot be specified to run on the command line.
.. _#1437: https://github.com/pytest-dev/pytest/issues/1437
.. _#469: https://github.com/pytest-dev/pytest/issues/469
.. _#1431: https://github.com/pytest-dev/pytest/pull/1431
.. _#649: https://github.com/pytest-dev/pytest/issues/649
.. _@asottile: https://github.com/asottile
2.9.0 2.9.0
===== =====

View File

@ -1,2 +1,3 @@
# #
__version__ = '2.10.0.dev1' __version__ = '2.10.0.dev1'

View File

@ -47,7 +47,9 @@ def format_exception_only(etype, value):
filename = filename or "<string>" filename = filename or "<string>"
lines.append(' File "%s", line %d\n' % (filename, lineno)) lines.append(' File "%s", line %d\n' % (filename, lineno))
if badline is not None: if badline is not None:
lines.append(' %s\n' % badline.strip()) if isinstance(badline, bytes): # python 2 only
badline = badline.decode('utf-8', 'replace')
lines.append(u' %s\n' % badline.strip())
if offset is not None: if offset is not None:
caretspace = badline.rstrip('\n')[:offset].lstrip() caretspace = badline.rstrip('\n')[:offset].lstrip()
# non-space whitespace (likes tabs) must be kept for alignment # non-space whitespace (likes tabs) must be kept for alignment

View File

@ -149,6 +149,8 @@ class LFPlugin:
config = self.config config = self.config
if config.getvalue("cacheshow") or hasattr(config, "slaveinput"): if config.getvalue("cacheshow") or hasattr(config, "slaveinput"):
return return
prev_failed = config.cache.get("cache/lastfailed", None) is not None
if (session.testscollected and prev_failed) or self.lastfailed:
config.cache.set("cache/lastfailed", self.lastfailed) config.cache.set("cache/lastfailed", self.lastfailed)

View File

@ -383,8 +383,13 @@ class PytestPluginManager(PluginManager):
importspec = modname importspec = modname
try: try:
__import__(importspec) __import__(importspec)
except ImportError: except ImportError as e:
raise new_exc = ImportError('Error importing plugin "%s": %s' % (modname, e))
# copy over name and path attributes
for attr in ('name', 'path'):
if hasattr(e, attr):
setattr(new_exc, attr, getattr(e, attr))
raise new_exc
except Exception as e: except Exception as e:
import pytest import pytest
if not hasattr(pytest, 'skip') or not isinstance(e, pytest.skip.Exception): if not hasattr(pytest, 'skip') or not isinstance(e, pytest.skip.Exception):

View File

@ -28,17 +28,14 @@ def pytest_plugin_registered(plugin, manager):
@hookspec(historic=True) @hookspec(historic=True)
def pytest_addoption(parser): def pytest_addoption(parser):
"""register argparse-style options and ini-style config values. """register argparse-style options and ini-style config values,
called once at the beginning of a test run.
.. warning:: .. note::
This function must be implemented in a :ref:`plugin <pluginorder>` This function should be implemented only in plugins or ``conftest.py``
and is called once at the beginning of a test run. files situated at the tests root directory due to how py.test
:ref:`discovers plugins during startup <pluginorder>`.
Implementing this hook from ``conftest.py`` files is **strongly**
discouraged because ``conftest.py`` files are lazily loaded and
may give strange *unknown option* errors depending on the directory
``py.test`` is invoked from.
:arg parser: To add command line options, call :arg parser: To add command line options, call
:py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`. :py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`.
@ -84,7 +81,7 @@ def pytest_cmdline_main(config):
""" called for performing the main command line action. The default """ called for performing the main command line action. The default
implementation will invoke the configure hooks and runtest_mainloop. """ implementation will invoke the configure hooks and runtest_mainloop. """
def pytest_load_initial_conftests(args, early_config, parser): def pytest_load_initial_conftests(early_config, parser, args):
""" implements the loading of initial conftest files ahead """ implements the loading of initial conftest files ahead
of command line option parsing. """ of command line option parsing. """

View File

@ -46,6 +46,8 @@ del _legal_chars
del _legal_ranges del _legal_ranges
del _legal_xml_re del _legal_xml_re
_py_ext_re = re.compile(r"\.py$")
def bin_xml_escape(arg): def bin_xml_escape(arg):
def repl(matchobj): def repl(matchobj):
@ -89,7 +91,7 @@ class _NodeReporter(object):
def record_testreport(self, testreport): def record_testreport(self, testreport):
assert not self.testcase assert not self.testcase
names = mangle_testnames(testreport.nodeid.split("::")) names = mangle_test_address(testreport.nodeid)
classnames = names[:-1] classnames = names[:-1]
if self.xml.prefix: if self.xml.prefix:
classnames.insert(0, self.xml.prefix) classnames.insert(0, self.xml.prefix)
@ -235,9 +237,18 @@ def pytest_unconfigure(config):
config.pluginmanager.unregister(xml) config.pluginmanager.unregister(xml)
def mangle_testnames(names): def mangle_test_address(address):
names = [x.replace(".py", "") for x in names if x != '()'] path, possible_open_bracket, params = address.partition('[')
names = path.split("::")
try:
names.remove('()')
except ValueError:
pass
# convert file path to dotted path
names[0] = names[0].replace("/", '.') names[0] = names[0].replace("/", '.')
names[0] = _py_ext_re.sub("", names[0])
# put any params back
names[-1] += possible_open_bracket + params
return names return names

View File

@ -718,7 +718,8 @@ class Session(FSCollector):
if rep.passed: if rep.passed:
has_matched = False has_matched = False
for x in rep.result: for x in rep.result:
if x.name == name: # TODO: remove parametrized workaround once collection structure contains parametrization
if x.name == name or x.name.split("[")[0] == name:
resultnodes.extend(self.matchnodes([x], nextnames)) resultnodes.extend(self.matchnodes([x], nextnames))
has_matched = True has_matched = True
# XXX accept IDs that don't have "()" for class instances # XXX accept IDs that don't have "()" for class instances

View File

@ -751,7 +751,7 @@ class FunctionMixin(PyobjMixin):
def _repr_failure_py(self, excinfo, style="long"): def _repr_failure_py(self, excinfo, style="long"):
if excinfo.errisinstance(pytest.fail.Exception): if excinfo.errisinstance(pytest.fail.Exception):
if not excinfo.value.pytrace: if not excinfo.value.pytrace:
return str(excinfo.value) return py._builtin._totext(excinfo.value)
return super(FunctionMixin, self)._repr_failure_py(excinfo, return super(FunctionMixin, self)._repr_failure_py(excinfo,
style=style) style=style)
@ -1126,7 +1126,7 @@ def _idval(val, argname, idx, idfn):
elif isinstance(val, (float, int, str, bool, NoneType)): elif isinstance(val, (float, int, str, bool, NoneType)):
return str(val) return str(val)
elif isinstance(val, REGEX_TYPE): elif isinstance(val, REGEX_TYPE):
return val.pattern return _escape_bytes(val.pattern) if isinstance(val.pattern, bytes) else val.pattern
elif enum is not None and isinstance(val, enum.Enum): elif enum is not None and isinstance(val, enum.Enum):
return str(val) return str(val)
elif isclass(val) and hasattr(val, '__name__'): elif isclass(val) and hasattr(val, '__name__'):

View File

@ -435,7 +435,10 @@ class OutcomeException(Exception):
def __repr__(self): def __repr__(self):
if self.msg: if self.msg:
return str(self.msg) val = self.msg
if isinstance(val, bytes):
val = py._builtin._totext(val, errors='replace')
return val
return "<%s instance>" %(self.__class__.__name__,) return "<%s instance>" %(self.__class__.__name__,)
__str__ = __repr__ __str__ = __repr__

View File

@ -0,0 +1,65 @@
pytest-2.9.1
============
pytest is a mature Python testing tool with more than a 1100 tests
against itself, passing on many different interpreters and platforms.
See below for the changes and see docs at:
http://pytest.org
As usual, you can upgrade from pypi via::
pip install -U pytest
Thanks to all who contributed to this release, among them:
Bruno Oliveira
Daniel Hahler
Dmitry Malinovsky
Florian Bruhin
Floris Bruynooghe
Matt Bachmann
Ronny Pfannschmidt
TomV
Vladimir Bolshakov
Zearin
palaviv
Happy testing,
The py.test Development Team
2.9.1 (compared to 2.9.0)
-------------------------
**Bug Fixes**
* Improve error message when a plugin fails to load.
Thanks `@nicoddemus`_ for the PR.
* Fix (`#1178 <https://github.com/pytest-dev/pytest/issues/1178>`_):
``pytest.fail`` with non-ascii characters raises an internal pytest error.
Thanks `@nicoddemus`_ for the PR.
* Fix (`#469`_): junit parses report.nodeid incorrectly, when params IDs
contain ``::``. Thanks `@tomviner`_ for the PR (`#1431`_).
* Fix (`#578 <https://github.com/pytest-dev/pytest/issues/578>`_): SyntaxErrors
containing non-ascii lines at the point of failure generated an internal
py.test error.
Thanks `@asottile`_ for the report and `@nicoddemus`_ for the PR.
* Fix (`#1437`_): When passing in a bytestring regex pattern to parameterize
attempt to decode it as utf-8 ignoring errors.
* Fix (`#649`_): parametrized test nodes cannot be specified to run on the command line.
.. _#1437: https://github.com/pytest-dev/pytest/issues/1437
.. _#469: https://github.com/pytest-dev/pytest/issues/469
.. _#1431: https://github.com/pytest-dev/pytest/pull/1431
.. _#649: https://github.com/pytest-dev/pytest/issues/649
.. _@asottile: https://github.com/asottile

View File

@ -26,7 +26,7 @@ you will see the return value of the function call::
$ py.test test_assert1.py $ py.test test_assert1.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items
@ -143,7 +143,7 @@ if you run this module::
$ py.test test_assert2.py $ py.test test_assert2.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items

View File

@ -80,7 +80,7 @@ If you then run it with ``--lf``::
$ py.test --lf $ py.test --lf
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
run-last-failure: rerun last 2 failures run-last-failure: rerun last 2 failures
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items collected 50 items
@ -121,7 +121,7 @@ of ``FF`` and dots)::
$ py.test --ff $ py.test --ff
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
run-last-failure: rerun last 2 failures first run-last-failure: rerun last 2 failures first
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items collected 50 items
@ -226,7 +226,7 @@ You can always peek at the content of the cache using the
$ py.test --cache-clear $ py.test --cache-clear
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items

View File

@ -64,7 +64,7 @@ of the failing function and hide the other one::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items

View File

@ -49,7 +49,7 @@ then you can just invoke ``py.test`` without command line options::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 items collected 1 items

View File

@ -31,7 +31,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
$ py.test -v -m webtest $ py.test -v -m webtest
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items collecting ... collected 4 items
@ -45,7 +45,7 @@ Or the inverse, running all tests except the webtest ones::
$ py.test -v -m "not webtest" $ py.test -v -m "not webtest"
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items collecting ... collected 4 items
@ -66,7 +66,7 @@ tests based on their module, class, method, or function name::
$ py.test -v test_server.py::TestClass::test_method $ py.test -v test_server.py::TestClass::test_method
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 5 items collecting ... collected 5 items
@ -79,7 +79,7 @@ You can also select on the class::
$ py.test -v test_server.py::TestClass $ py.test -v test_server.py::TestClass
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items collecting ... collected 4 items
@ -92,7 +92,7 @@ Or select multiple nodes::
$ py.test -v test_server.py::TestClass test_server.py::test_send_http $ py.test -v test_server.py::TestClass test_server.py::test_send_http
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items collecting ... collected 8 items
@ -130,7 +130,7 @@ select tests based on their names::
$ py.test -v -k http # running with the above defined example module $ py.test -v -k http # running with the above defined example module
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items collecting ... collected 4 items
@ -144,7 +144,7 @@ And you can also run all tests except the ones that match the keyword::
$ py.test -k "not send_http" -v $ py.test -k "not send_http" -v
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items collecting ... collected 4 items
@ -160,7 +160,7 @@ Or to select "http" and "quick" tests::
$ py.test -k "http or quick" -v $ py.test -k "http or quick" -v
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items collecting ... collected 4 items
@ -350,7 +350,7 @@ the test needs::
$ py.test -E stage2 $ py.test -E stage2
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items
@ -362,7 +362,7 @@ and here is one that specifies exactly the environment needed::
$ py.test -E stage1 $ py.test -E stage1
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items
@ -481,7 +481,7 @@ then you will see two test skipped and two executed tests as expected::
$ py.test -rs # this option reports skip reasons $ py.test -rs # this option reports skip reasons
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -495,7 +495,7 @@ Note that if you specify a platform via the marker-command line option like this
$ py.test -m linux2 $ py.test -m linux2
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -547,7 +547,7 @@ We can now use the ``-m option`` to select one set::
$ py.test -m interface --tb=short $ py.test -m interface --tb=short
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -569,7 +569,7 @@ or to select both "event" and "interface" tests::
$ py.test -m "interface or event" --tb=short $ py.test -m "interface or event" --tb=short
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items

View File

@ -27,7 +27,7 @@ now execute the test specification::
nonpython $ py.test test_simple.yml nonpython $ py.test test_simple.yml
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/nonpython, inifile: rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items collected 2 items
@ -59,7 +59,7 @@ consulted when reporting in ``verbose`` mode::
nonpython $ py.test -v nonpython $ py.test -v
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR/nonpython, inifile: rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collecting ... collected 2 items collecting ... collected 2 items
@ -81,7 +81,7 @@ interesting to just look at the collection tree::
nonpython $ py.test --collect-only nonpython $ py.test --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/nonpython, inifile: rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items collected 2 items
<YamlFile 'test_simple.yml'> <YamlFile 'test_simple.yml'>

View File

@ -130,7 +130,7 @@ objects, they are still using the default pytest representation::
$ py.test test_time.py --collect-only $ py.test test_time.py --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 6 items collected 6 items
<Module 'test_time.py'> <Module 'test_time.py'>
@ -181,7 +181,7 @@ this is a fully self-contained example which you can run with::
$ py.test test_scenarios.py $ py.test test_scenarios.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -194,7 +194,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
$ py.test --collect-only test_scenarios.py $ py.test --collect-only test_scenarios.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
<Module 'test_scenarios.py'> <Module 'test_scenarios.py'>
@ -259,7 +259,7 @@ Let's first see how it looks like at collection time::
$ py.test test_backends.py --collect-only $ py.test test_backends.py --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
<Module 'test_backends.py'> <Module 'test_backends.py'>
@ -320,7 +320,7 @@ The result of this test will be successful::
$ py.test test_indirect_list.py --collect-only $ py.test test_indirect_list.py --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items
<Module 'test_indirect_list.py'> <Module 'test_indirect_list.py'>
@ -399,8 +399,8 @@ Running it results in some skips if we don't have all the python interpreters in
. $ py.test -rs -q multipython.py . $ py.test -rs -q multipython.py
ssssssssssss...ssssssssssss ssssssssssss...ssssssssssss
======= short test summary info ======== ======= short test summary info ========
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python2.6' not found
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python3.3' not found SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python3.3' not found
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python2.6' not found
3 passed, 24 skipped in 0.12 seconds 3 passed, 24 skipped in 0.12 seconds
Indirect parametrization of optional implementations/imports Indirect parametrization of optional implementations/imports
@ -448,7 +448,7 @@ If you run this with reporting for skips enabled::
$ py.test -rs test_module.py $ py.test -rs test_module.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items

View File

@ -82,7 +82,7 @@ then the test collection looks like this::
$ py.test --collect-only $ py.test --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: setup.cfg rootdir: $REGENDOC_TMPDIR, inifile: setup.cfg
collected 2 items collected 2 items
<Module 'check_myapp.py'> <Module 'check_myapp.py'>
@ -128,7 +128,7 @@ You can always peek at the collection tree without running tests like this::
. $ py.test --collect-only pythoncollection.py . $ py.test --collect-only pythoncollection.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 3 items collected 3 items
<Module 'CWD/pythoncollection.py'> <Module 'CWD/pythoncollection.py'>
@ -182,7 +182,7 @@ interpreters and will leave out the setup.py file::
$ py.test --collect-only $ py.test --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 0 items collected 0 items

View File

@ -13,7 +13,7 @@ get on the terminal - we are working on that):
assertion $ py.test failure_demo.py assertion $ py.test failure_demo.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/assertion, inifile: rootdir: $REGENDOC_TMPDIR/assertion, inifile:
collected 42 items collected 42 items

View File

@ -108,7 +108,7 @@ directory with the above conftest.py::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -156,7 +156,7 @@ and when running it will see a skipped "slow" test::
$ py.test -rs # "-rs" means report details on the little 's' $ py.test -rs # "-rs" means report details on the little 's'
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -170,7 +170,7 @@ Or run it including the ``slow`` marked test::
$ py.test --runslow $ py.test --runslow
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -262,7 +262,7 @@ which will add the string to the test header accordingly::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
project deps: mylib-1.1 project deps: mylib-1.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -286,7 +286,7 @@ which will add info only when run with "--v"::
$ py.test -v $ py.test -v
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
info1: did you know that ... info1: did you know that ...
did you? did you?
@ -299,7 +299,7 @@ and nothing when run plainly::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -332,7 +332,7 @@ Now we can profile which test functions execute the slowest::
$ py.test --durations=3 $ py.test --durations=3
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items
@ -394,7 +394,7 @@ If we run this::
$ py.test -rx $ py.test -rx
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -465,7 +465,7 @@ We can run this::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 7 items collected 7 items
@ -479,7 +479,7 @@ We can run this::
file $REGENDOC_TMPDIR/b/test_error.py, line 1 file $REGENDOC_TMPDIR/b/test_error.py, line 1
def test_root(db): # no db here, will error out def test_root(db): # no db here, will error out
fixture 'db' not found fixture 'db' not found
available fixtures: cache, tmpdir_factory, capsys, pytestconfig, capfd, record_xml_property, recwarn, tmpdir, monkeypatch available fixtures: record_xml_property, recwarn, cache, capsys, pytestconfig, tmpdir_factory, capfd, monkeypatch, tmpdir
use 'py.test --fixtures [testpath]' for help on them. use 'py.test --fixtures [testpath]' for help on them.
$REGENDOC_TMPDIR/b/test_error.py:1 $REGENDOC_TMPDIR/b/test_error.py:1
@ -569,7 +569,7 @@ and run them::
$ py.test test_module.py $ py.test test_module.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -660,7 +660,7 @@ and run it::
$ py.test -s test_module.py $ py.test -s test_module.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items

View File

@ -75,7 +75,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
$ py.test test_smtpsimple.py $ py.test test_smtpsimple.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items
@ -193,7 +193,7 @@ inspect what is going on and can now run the tests::
$ py.test test_module.py $ py.test test_module.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -480,7 +480,7 @@ Running the above tests results in the following test IDs being used::
$ py.test --collect-only $ py.test --collect-only
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 10 items collected 10 items
<Module 'test_anothersmtp.py'> <Module 'test_anothersmtp.py'>
@ -531,7 +531,7 @@ Here we declare an ``app`` fixture which receives the previously defined
$ py.test -v test_appsetup.py $ py.test -v test_appsetup.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 2 items collecting ... collected 2 items
@ -597,7 +597,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
$ py.test -v -s test_module.py $ py.test -v -s test_module.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items collecting ... collected 8 items

View File

@ -27,7 +27,7 @@ Installation options::
To check your installation has installed the correct version:: To check your installation has installed the correct version::
$ py.test --version $ py.test --version
This is pytest version 2.9.0, imported from $PYTHON_PREFIX/lib/python3.4/site-packages/pytest.py This is pytest version 2.9.1, imported from $PYTHON_PREFIX/lib/python3.4/site-packages/pytest.py
If you get an error checkout :ref:`installation issues`. If you get an error checkout :ref:`installation issues`.
@ -49,7 +49,7 @@ That's it. You can execute the test function now::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items

View File

@ -55,7 +55,7 @@ them in turn::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items
@ -103,7 +103,7 @@ Let's run this::
$ py.test $ py.test
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items

View File

@ -224,7 +224,7 @@ Running it with the report-on-xfail option gives this output::
example $ py.test -rx xfail_demo.py example $ py.test -rx xfail_demo.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/example, inifile: rootdir: $REGENDOC_TMPDIR/example, inifile:
collected 7 items collected 7 items

View File

@ -4,7 +4,7 @@ Talks and Tutorials
.. sidebar:: Next Open Trainings .. sidebar:: Next Open Trainings
`professional testing with pytest and tox <http://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, 24-26th November 2014, Freiburg, Germany `professional testing with pytest and tox <http://www.python-academy.com/courses/specialtopics/python_course_testing.html>`_, 27-29th June 2016, Freiburg, Germany
.. _`funcargs`: funcargs.html .. _`funcargs`: funcargs.html
@ -14,6 +14,9 @@ Talks and blog postings
.. _`tutorial1 repository`: http://bitbucket.org/pytest-dev/pytest-tutorial1/ .. _`tutorial1 repository`: http://bitbucket.org/pytest-dev/pytest-tutorial1/
.. _`pycon 2010 tutorial PDF`: http://bitbucket.org/pytest-dev/pytest-tutorial1/raw/tip/pytest-basic.pdf .. _`pycon 2010 tutorial PDF`: http://bitbucket.org/pytest-dev/pytest-tutorial1/raw/tip/pytest-basic.pdf
- `pytest - Rapid Simple Testing, Florian Bruhin, Swiss Python Summit 2016
<https://www.youtube.com/watch?v=rCBHkQ_LVIs>`_.
- `Improve your testing with Pytest and Mock, Gabe Hollombe, PyCon SG 2015 - `Improve your testing with Pytest and Mock, Gabe Hollombe, PyCon SG 2015
<https://www.youtube.com/watch?v=RcN26hznmk4>`_. <https://www.youtube.com/watch?v=RcN26hznmk4>`_.

View File

@ -29,7 +29,7 @@ Running this would result in a passed test except for the last
$ py.test test_tmpdir.py $ py.test test_tmpdir.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items collected 1 items

View File

@ -88,7 +88,7 @@ the ``self.db`` values in the traceback::
$ py.test test_unittest_db.py $ py.test test_unittest_db.py
======= test session starts ======== ======= test session starts ========
platform linux -- Python 3.4.0, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 platform linux -- Python 3.4.0, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items

View File

@ -392,6 +392,20 @@ class TestGeneralUsage:
monkeypatch.setitem(sys.modules, 'myplugin', mod) monkeypatch.setitem(sys.modules, 'myplugin', mod)
assert pytest.main(args=[str(tmpdir)], plugins=['myplugin']) == 0 assert pytest.main(args=[str(tmpdir)], plugins=['myplugin']) == 0
def test_parameterized_with_bytes_regex(self, testdir):
p = testdir.makepyfile("""
import re
import pytest
@pytest.mark.parametrize('r', [re.compile(b'foo')])
def test_stuff(r):
pass
"""
)
res = testdir.runpytest(p)
res.stdout.fnmatch_lines([
'*1 passed*'
])
class TestInvocationVariants: class TestInvocationVariants:
def test_earlyinit(self, testdir): def test_earlyinit(self, testdir):

View File

@ -93,6 +93,17 @@ def test_unicode_handling():
if sys.version_info[0] < 3: if sys.version_info[0] < 3:
unicode(excinfo) unicode(excinfo)
@pytest.mark.skipif(sys.version_info[0] >= 3, reason='python 2 only issue')
def test_unicode_handling_syntax_error():
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
def f():
raise SyntaxError('invalid syntax', (None, 1, 3, value))
excinfo = pytest.raises(Exception, f)
str(excinfo)
if sys.version_info[0] < 3:
unicode(excinfo)
def test_code_getargs(): def test_code_getargs():
def f1(x): def f1(x):
pass pass

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
import sys import sys
from textwrap import dedent from textwrap import dedent
@ -1181,3 +1182,19 @@ def test_class_injection_does_not_break_collection(testdir):
result = testdir.runpytest() result = testdir.runpytest()
assert "RuntimeError: dictionary changed size during iteration" not in result.stdout.str() assert "RuntimeError: dictionary changed size during iteration" not in result.stdout.str()
result.stdout.fnmatch_lines(['*1 passed*']) result.stdout.fnmatch_lines(['*1 passed*'])
def test_syntax_error_with_non_ascii_chars(testdir):
"""Fix decoding issue while formatting SyntaxErrors during collection (#578)
"""
testdir.makepyfile(u"""
# -*- coding: UTF-8 -*-
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines([
'*ERROR collecting*',
'*SyntaxError*',
'*1 error in*',
])

View File

@ -170,6 +170,11 @@ class TestMetafunc:
result = idmaker((py.builtin._totext("a"), "b"), [({}, b'\xc3\xb4')]) result = idmaker((py.builtin._totext("a"), "b"), [({}, b'\xc3\xb4')])
assert result == ['a0-\\xc3\\xb4'] assert result == ['a0-\\xc3\\xb4']
def test_idmaker_with_bytes_regex(self):
from _pytest.python import idmaker
result = idmaker(("a"), [(re.compile(b'foo'), 1.0)])
assert result == ["foo"]
def test_idmaker_native_strings(self): def test_idmaker_native_strings(self):
from _pytest.python import idmaker from _pytest.python import idmaker
totext = py.builtin._totext totext = py.builtin._totext

View File

@ -46,12 +46,12 @@ class TestNewAPI:
def test_cache_failure_warns(self, testdir): def test_cache_failure_warns(self, testdir):
testdir.tmpdir.ensure_dir('.cache').chmod(0) testdir.tmpdir.ensure_dir('.cache').chmod(0)
testdir.makepyfile(""" testdir.makepyfile("""
def test_pass(): def test_error():
pass raise Exception
""") """)
result = testdir.runpytest('-rw') result = testdir.runpytest('-rw')
assert result.ret == 0 assert result.ret == 1
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"*could not create cache path*", "*could not create cache path*",
"*1 pytest-warnings*", "*1 pytest-warnings*",
@ -266,7 +266,7 @@ class TestLastFailed:
""") """)
config = testdir.parseconfigure() config = testdir.parseconfigure()
lastfailed = config.cache.get("cache/lastfailed", -1) lastfailed = config.cache.get("cache/lastfailed", -1)
assert not lastfailed assert lastfailed == -1
def test_non_serializable_parametrize(self, testdir): def test_non_serializable_parametrize(self, testdir):
"""Test that failed parametrized tests with unmarshable parameters """Test that failed parametrized tests with unmarshable parameters
@ -305,7 +305,7 @@ class TestLastFailed:
return lastfailed return lastfailed
lastfailed = rlf(fail_import=0, fail_run=0) lastfailed = rlf(fail_import=0, fail_run=0)
assert not lastfailed assert lastfailed == -1
lastfailed = rlf(fail_import=1, fail_run=0) lastfailed = rlf(fail_import=1, fail_run=0)
assert list(lastfailed) == ['test_maybe.py'] assert list(lastfailed) == ['test_maybe.py']
@ -347,7 +347,7 @@ class TestLastFailed:
return result, lastfailed return result, lastfailed
result, lastfailed = rlf(fail_import=0, fail_run=0) result, lastfailed = rlf(fail_import=0, fail_run=0)
assert not lastfailed assert lastfailed == -1
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
'*3 passed*', '*3 passed*',
]) ])
@ -370,3 +370,17 @@ class TestLastFailed:
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
'*2 passed*', '*2 passed*',
]) ])
def test_lastfailed_creates_cache_when_needed(self, testdir):
# Issue #1342
testdir.makepyfile(test_empty='')
testdir.runpytest('-q', '--lf')
assert not os.path.exists('.cache')
testdir.makepyfile(test_successful='def test_success():\n assert True')
testdir.runpytest('-q', '--lf')
assert not os.path.exists('.cache')
testdir.makepyfile(test_errored='def test_error():\n assert False')
testdir.runpytest('-q', '--lf')
assert os.path.exists('.cache')

View File

@ -449,11 +449,12 @@ class TestPython:
assert "hello-stderr" in systemout.toxml() assert "hello-stderr" in systemout.toxml()
def test_mangle_testnames(): def test_mangle_test_address():
from _pytest.junitxml import mangle_testnames from _pytest.junitxml import mangle_test_address
names = ["a/pything.py", "Class", "()", "method"] address = '::'.join(
newnames = mangle_testnames(names) ["a/my.py.thing.py", "Class", "()", "method", "[a-1-::]"])
assert newnames == ["a.pything", "Class", "method"] newnames = mangle_test_address(address)
assert newnames == ["a.my.py.thing", "Class", "method", "[a-1-::]"]
def test_dont_configure_on_slaves(tmpdir): def test_dont_configure_on_slaves(tmpdir):
@ -619,6 +620,36 @@ def test_escaped_parametrized_names_xml(testdir):
node.assert_attr(name="test_func[#x00]") node.assert_attr(name="test_func[#x00]")
def test_double_colon_split_function_issue469(testdir):
testdir.makepyfile("""
import pytest
@pytest.mark.parametrize('param', ["double::colon"])
def test_func(param):
pass
""")
result, dom = runandparse(testdir)
assert result.ret == 0
node = dom.find_first_by_tag("testcase")
node.assert_attr(classname="test_double_colon_split_function_issue469")
node.assert_attr(name='test_func[double::colon]')
def test_double_colon_split_method_issue469(testdir):
testdir.makepyfile("""
import pytest
class TestClass:
@pytest.mark.parametrize('param', ["double::colon"])
def test_func(self, param):
pass
""")
result, dom = runandparse(testdir)
assert result.ret == 0
node = dom.find_first_by_tag("testcase")
node.assert_attr(
classname="test_double_colon_split_method_issue469.TestClass")
node.assert_attr(name='test_func[double::colon]')
def test_unicode_issue368(testdir): def test_unicode_issue368(testdir):
path = testdir.tmpdir.join("test.xml") path = testdir.tmpdir.join("test.xml")
log = LogXML(str(path), None) log = LogXML(str(path), None)

View File

@ -269,6 +269,22 @@ def test_keyword_option_parametrize(spec, testdir):
assert len(passed) == len(passed_result) assert len(passed) == len(passed_result)
assert list(passed) == list(passed_result) assert list(passed) == list(passed_result)
def test_parametrized_collected_from_command_line(testdir):
"""Parametrized test not collected if test named specified
in command line issue#649.
"""
py_file = testdir.makepyfile("""
import pytest
@pytest.mark.parametrize("arg", [None, 1.3, "2-3"])
def test_func(arg):
pass
""")
file_name = os.path.basename(py_file.strpath)
rec = testdir.inline_run(file_name + "::" + "test_func")
rec.assertoutcome(passed=3)
class TestFunctional: class TestFunctional:
def test_mark_per_function(self, testdir): def test_mark_per_function(self, testdir):

View File

@ -178,13 +178,17 @@ def test_default_markers(testdir):
"*trylast*last*", "*trylast*last*",
]) ])
def test_importplugin_issue375(testdir, pytestpm): def test_importplugin_issue375(testdir, pytestpm):
"""Don't hide import errors when importing plugins and provide
an easy to debug message.
"""
testdir.syspathinsert(testdir.tmpdir) testdir.syspathinsert(testdir.tmpdir)
testdir.makepyfile(qwe="import aaaa") testdir.makepyfile(qwe="import aaaa")
with pytest.raises(ImportError) as excinfo: with pytest.raises(ImportError) as excinfo:
pytestpm.import_plugin("qwe") pytestpm.import_plugin("qwe")
assert "qwe" not in str(excinfo.value) expected = '.*Error importing plugin "qwe": No module named \'?aaaa\'?'
assert "aaaa" in str(excinfo.value) assert py.std.re.match(expected, str(excinfo.value))
class TestPytestPluginManager: class TestPytestPluginManager:

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement from __future__ import with_statement
import _pytest._code import _pytest._code
@ -439,6 +440,27 @@ def test_pytest_fail_notrace(testdir):
assert 'def teardown_function' not in result.stdout.str() assert 'def teardown_function' not in result.stdout.str()
@pytest.mark.parametrize('str_prefix', ['u', ''])
def test_pytest_fail_notrace_non_ascii(testdir, str_prefix):
"""Fix pytest.fail with pytrace=False with non-ascii characters (#1178).
This tests with native and unicode strings containing non-ascii chars.
"""
testdir.makepyfile(u"""
# coding: utf-8
import pytest
def test_hello():
pytest.fail(%s'oh oh: ☺', pytrace=False)
""" % str_prefix)
result = testdir.runpytest()
if sys.version_info[0] >= 3:
result.stdout.fnmatch_lines(['*test_hello*', "oh oh: ☺"])
else:
result.stdout.fnmatch_lines(['*test_hello*', "oh oh: *"])
assert 'def test_hello' not in result.stdout.str()
def test_pytest_no_tests_collected_exit_status(testdir): def test_pytest_no_tests_collected_exit_status(testdir):
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines('*collected 0 items*') result.stdout.fnmatch_lines('*collected 0 items*')