Merge remote-tracking branch 'upstream/master' into merge-master-into-features

This commit is contained in:
Bruno Oliveira 2018-11-23 23:27:41 -02:00
commit 33b877cc01
53 changed files with 406 additions and 195 deletions

View File

@ -159,6 +159,7 @@ Michael Droettboom
Michael Seifert Michael Seifert
Michal Wajszczuk Michal Wajszczuk
Mihai Capotă Mihai Capotă
Mike Hoyle (hoylemd)
Mike Lundy Mike Lundy
Miro Hrončok Miro Hrončok
Nathaniel Waisbrot Nathaniel Waisbrot

View File

@ -18,6 +18,43 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start .. towncrier release notes start
pytest 4.0.1 (2018-11-23)
=========================
Bug Fixes
---------
- `#3952 <https://github.com/pytest-dev/pytest/issues/3952>`_: Display warnings before "short test summary info" again, but still later warnings in the end.
- `#4386 <https://github.com/pytest-dev/pytest/issues/4386>`_: Handle uninitialized exceptioninfo in repr/str.
- `#4393 <https://github.com/pytest-dev/pytest/issues/4393>`_: Do not create ``.gitignore``/``README.md`` files in existing cache directories.
- `#4400 <https://github.com/pytest-dev/pytest/issues/4400>`_: Rearrange warning handling for the yield test errors so the opt-out in 4.0.x correctly works.
- `#4405 <https://github.com/pytest-dev/pytest/issues/4405>`_: Fix collection of testpaths with ``--pyargs``.
- `#4412 <https://github.com/pytest-dev/pytest/issues/4412>`_: Fix assertion rewriting involving ``Starred`` + side-effects.
- `#4425 <https://github.com/pytest-dev/pytest/issues/4425>`_: Ensure we resolve the absolute path when the given ``--basetemp`` is a relative path.
Trivial/Internal Changes
------------------------
- `#4315 <https://github.com/pytest-dev/pytest/issues/4315>`_: Use ``pkg_resources.parse_version`` instead of ``LooseVersion`` in minversion check.
- `#4440 <https://github.com/pytest-dev/pytest/issues/4440>`_: Adjust the stack level of some internal pytest warnings.
pytest 4.0.0 (2018-11-13) pytest 4.0.0 (2018-11-13)
========================= =========================

View File

@ -1 +0,0 @@
Rearrange warning handling for the yield test errors so the opt-out in 4.0.x correctly works.

View File

@ -1 +0,0 @@
Fix collection of testpaths with ``--pyargs``.

View File

@ -1 +0,0 @@
Fix assertion rewriting involving ``Starred`` + side-effects.

View File

@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2 :maxdepth: 2
release-4.0.1
release-4.0.0 release-4.0.0
release-3.10.1 release-3.10.1
release-3.10.0 release-3.10.0

View File

@ -0,0 +1,23 @@
pytest-4.0.1
=======================================
pytest 4.0.1 has just been released to PyPI.
This is a bug-fix release, being a drop-in replacement. To upgrade::
pip install --upgrade pytest
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
Thanks to all who contributed to this release, among them:
* Anthony Sottile
* Bruno Oliveira
* Daniel Hahler
* Michael D. Hoyle
* Ronny Pfannschmidt
* Slam
Happy testing,
The pytest Development Team

View File

@ -26,7 +26,7 @@ you will see the return value of the function call::
$ pytest test_assert1.py $ pytest test_assert1.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
@ -169,7 +169,7 @@ if you run this module::
$ pytest test_assert2.py $ pytest test_assert2.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item

View File

@ -76,7 +76,7 @@ If you then run it with ``--lf``::
$ pytest --lf $ pytest --lf
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items / 48 deselected collected 50 items / 48 deselected
run-last-failure: rerun previous 2 failures run-last-failure: rerun previous 2 failures
@ -117,7 +117,7 @@ of ``FF`` and dots)::
$ pytest --ff $ pytest --ff
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items collected 50 items
run-last-failure: rerun previous 2 failures first run-last-failure: rerun previous 2 failures first
@ -236,7 +236,7 @@ You can always peek at the content of the cache using the
$ pytest --cache-show $ pytest --cache-show
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
cachedir: $REGENDOC_TMPDIR/.pytest_cache cachedir: $REGENDOC_TMPDIR/.pytest_cache
------------------------------- cache values ------------------------------- ------------------------------- cache values -------------------------------

View File

@ -52,7 +52,7 @@ is that you can use print statements for debugging::
# content of test_module.py # content of test_module.py
def setup_function(function): def setup_function(function):
print ("setting up %s" % function) print("setting up %s" % function)
def test_func1(): def test_func1():
assert True assert True
@ -65,7 +65,7 @@ of the failing function and hide the other one::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items

View File

@ -62,7 +62,7 @@ then you can just invoke ``pytest`` without command line options::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 item collected 1 item

View File

@ -31,7 +31,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
$ pytest -v -m webtest $ pytest -v -m webtest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items / 3 deselected collecting ... collected 4 items / 3 deselected
@ -44,7 +44,7 @@ Or the inverse, running all tests except the webtest ones::
$ pytest -v -m "not webtest" $ pytest -v -m "not webtest"
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items / 1 deselected collecting ... collected 4 items / 1 deselected
@ -64,7 +64,7 @@ tests based on their module, class, method, or function name::
$ pytest -v test_server.py::TestClass::test_method $ pytest -v test_server.py::TestClass::test_method
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 1 item collecting ... collected 1 item
@ -77,7 +77,7 @@ You can also select on the class::
$ pytest -v test_server.py::TestClass $ pytest -v test_server.py::TestClass
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 1 item collecting ... collected 1 item
@ -90,7 +90,7 @@ Or select multiple nodes::
$ pytest -v test_server.py::TestClass test_server.py::test_send_http $ pytest -v test_server.py::TestClass test_server.py::test_send_http
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 2 items collecting ... collected 2 items
@ -128,7 +128,7 @@ select tests based on their names::
$ pytest -v -k http # running with the above defined example module $ pytest -v -k http # running with the above defined example module
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items / 3 deselected collecting ... collected 4 items / 3 deselected
@ -141,7 +141,7 @@ And you can also run all tests except the ones that match the keyword::
$ pytest -k "not send_http" -v $ pytest -k "not send_http" -v
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items / 1 deselected collecting ... collected 4 items / 1 deselected
@ -156,7 +156,7 @@ Or to select "http" and "quick" tests::
$ pytest -k "http or quick" -v $ pytest -k "http or quick" -v
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items / 2 deselected collecting ... collected 4 items / 2 deselected
@ -271,8 +271,12 @@ You can also set a module level marker::
import pytest import pytest
pytestmark = pytest.mark.webtest pytestmark = pytest.mark.webtest
in which case it will be applied to all functions and or multiple markers::
methods defined in the module.
pytestmark = [pytest.mark.webtest, pytest.mark.slowtest]
in which case markers will be applied (in left-to-right order) to
all functions and methods defined in the module.
.. _`marking individual tests when using parametrize`: .. _`marking individual tests when using parametrize`:
@ -351,7 +355,7 @@ the test needs::
$ pytest -E stage2 $ pytest -E stage2
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
@ -363,7 +367,7 @@ and here is one that specifies exactly the environment needed::
$ pytest -E stage1 $ pytest -E stage1
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
@ -462,7 +466,7 @@ test function. From a conftest file we can read it like this::
def pytest_runtest_setup(item): def pytest_runtest_setup(item):
for mark in item.iter_markers(name='glob'): for mark in item.iter_markers(name='glob'):
print ("glob args=%s kwargs=%s" %(mark.args, mark.kwargs)) print("glob args=%s kwargs=%s" % (mark.args, mark.kwargs))
sys.stdout.flush() sys.stdout.flush()
Let's run this without capturing output and see what we get:: Let's run this without capturing output and see what we get::
@ -524,7 +528,7 @@ then you will see two tests skipped and two executed tests as expected::
$ pytest -rs # this option reports skip reasons $ pytest -rs # this option reports skip reasons
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -538,7 +542,7 @@ Note that if you specify a platform via the marker-command line option like this
$ pytest -m linux $ pytest -m linux
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items / 3 deselected collected 4 items / 3 deselected
@ -589,7 +593,7 @@ We can now use the ``-m option`` to select one set::
$ pytest -m interface --tb=short $ pytest -m interface --tb=short
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items / 2 deselected collected 4 items / 2 deselected
@ -610,7 +614,7 @@ or to select both "event" and "interface" tests::
$ pytest -m "interface or event" --tb=short $ pytest -m "interface or event" --tb=short
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items / 1 deselected collected 4 items / 1 deselected

View File

@ -27,7 +27,7 @@ now execute the test specification::
nonpython $ pytest test_simple.yml nonpython $ pytest test_simple.yml
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
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 $ pytest -v nonpython $ pytest -v
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_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 $ pytest --collect-only nonpython $ pytest --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR/nonpython, inifile: rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items collected 2 items
<Package '$REGENDOC_TMPDIR/nonpython'> <Package '$REGENDOC_TMPDIR/nonpython'>

View File

@ -139,7 +139,7 @@ objects, they are still using the default pytest representation::
$ pytest test_time.py --collect-only $ pytest test_time.py --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 8 items collected 8 items
<Module 'test_time.py'> <Module 'test_time.py'>
@ -195,7 +195,7 @@ this is a fully self-contained example which you can run with::
$ pytest test_scenarios.py $ pytest test_scenarios.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -208,7 +208,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
$ pytest --collect-only test_scenarios.py $ pytest --collect-only test_scenarios.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
<Module 'test_scenarios.py'> <Module 'test_scenarios.py'>
@ -272,7 +272,7 @@ Let's first see how it looks like at collection time::
$ pytest test_backends.py --collect-only $ pytest test_backends.py --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
<Module 'test_backends.py'> <Module 'test_backends.py'>
@ -333,7 +333,7 @@ The result of this test will be successful::
$ pytest test_indirect_list.py --collect-only $ pytest test_indirect_list.py --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
<Module 'test_indirect_list.py'> <Module 'test_indirect_list.py'>
@ -460,7 +460,7 @@ If you run this with reporting for skips enabled::
$ pytest -rs test_module.py $ pytest -rs test_module.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items

View File

@ -127,7 +127,7 @@ The test collection would look like this::
$ pytest --collect-only $ pytest --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 2 items collected 2 items
<Module 'check_myapp.py'> <Module 'check_myapp.py'>
@ -180,7 +180,7 @@ You can always peek at the collection tree without running tests like this::
. $ pytest --collect-only pythoncollection.py . $ pytest --collect-only pythoncollection.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
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'>
@ -248,7 +248,7 @@ file will be left out::
$ pytest --collect-only $ pytest --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 0 items collected 0 items

View File

@ -11,7 +11,7 @@ get on the terminal - we are working on that)::
assertion $ pytest failure_demo.py assertion $ pytest failure_demo.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR/assertion, inifile: rootdir: $REGENDOC_TMPDIR/assertion, inifile:
collected 42 items collected 42 items

View File

@ -121,7 +121,7 @@ directory with the above conftest.py::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -179,7 +179,7 @@ and when running it will see a skipped "slow" test::
$ pytest -rs # "-rs" means report details on the little 's' $ pytest -rs # "-rs" means report details on the little 's'
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -193,7 +193,7 @@ Or run it including the ``slow`` marked test::
$ pytest --runslow $ pytest --runslow
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -331,7 +331,7 @@ which will add the string to the test header accordingly::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
project deps: mylib-1.1 project deps: mylib-1.1
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -357,7 +357,7 @@ which will add info only when run with "--v"::
$ pytest -v $ pytest -v
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
info1: did you know that ... info1: did you know that ...
did you? did you?
@ -370,7 +370,7 @@ and nothing when run plainly::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -407,7 +407,7 @@ Now we can profile which test functions execute the slowest::
$ pytest --durations=3 $ pytest --durations=3
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items
@ -479,7 +479,7 @@ If we run this::
$ pytest -rx $ pytest -rx
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items collected 4 items
@ -560,7 +560,7 @@ We can run this::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 7 items collected 7 items
@ -671,7 +671,7 @@ and run them::
$ pytest test_module.py $ pytest test_module.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -770,7 +770,7 @@ and run it::
$ pytest -s test_module.py $ pytest -s test_module.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items

View File

@ -13,7 +13,7 @@ calls it::
@pytest.fixture(scope="session", autouse=True) @pytest.fixture(scope="session", autouse=True)
def callattr_ahead_of_alltests(request): def callattr_ahead_of_alltests(request):
print ("callattr_ahead_of_alltests called") print("callattr_ahead_of_alltests called")
seen = set([None]) seen = set([None])
session = request.node session = request.node
for item in session.items: for item in session.items:
@ -31,20 +31,20 @@ will be called ahead of running any tests::
class TestHello(object): class TestHello(object):
@classmethod @classmethod
def callme(cls): def callme(cls):
print ("callme called!") print("callme called!")
def test_method1(self): def test_method1(self):
print ("test_method1 called") print("test_method1 called")
def test_method2(self): def test_method2(self):
print ("test_method1 called") print("test_method1 called")
class TestOther(object): class TestOther(object):
@classmethod @classmethod
def callme(cls): def callme(cls):
print ("callme other called") print("callme other called")
def test_other(self): def test_other(self):
print ("test other") print("test other")
# works with unittest as well ... # works with unittest as well ...
import unittest import unittest
@ -52,10 +52,10 @@ will be called ahead of running any tests::
class SomeTest(unittest.TestCase): class SomeTest(unittest.TestCase):
@classmethod @classmethod
def callme(self): def callme(self):
print ("SomeTest callme called") print("SomeTest callme called")
def test_unit1(self): def test_unit1(self):
print ("test_unit1 method called") print("test_unit1 method called")
If you run this without output capturing:: If you run this without output capturing::

View File

@ -70,7 +70,7 @@ marked ``smtp_connection`` fixture function. Running the test looks like this::
$ pytest test_smtpsimple.py $ pytest test_smtpsimple.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
@ -208,7 +208,7 @@ inspect what is going on and can now run the tests::
$ pytest test_module.py $ pytest test_module.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items
@ -460,7 +460,7 @@ read an optional server URL from the test module which uses our fixture::
server = getattr(request.module, "smtpserver", "smtp.gmail.com") server = getattr(request.module, "smtpserver", "smtp.gmail.com")
smtp_connection = smtplib.SMTP(server, 587, timeout=5) smtp_connection = smtplib.SMTP(server, 587, timeout=5)
yield smtp_connection yield smtp_connection
print ("finalizing %s (%s)" % (smtp_connection, server)) print("finalizing %s (%s)" % (smtp_connection, server))
smtp_connection.close() smtp_connection.close()
We use the ``request.module`` attribute to optionally obtain an We use the ``request.module`` attribute to optionally obtain an
@ -690,7 +690,7 @@ Running the above tests results in the following test IDs being used::
$ pytest --collect-only $ pytest --collect-only
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 10 items collected 10 items
<Module 'test_anothersmtp.py'> <Module 'test_anothersmtp.py'>
@ -732,7 +732,7 @@ Running this test will *skip* the invocation of ``data_set`` with value ``2``::
$ pytest test_fixture_marks.py -v $ pytest test_fixture_marks.py -v
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 3 items collecting ... collected 3 items
@ -775,7 +775,7 @@ Here we declare an ``app`` fixture which receives the previously defined
$ pytest -v test_appsetup.py $ pytest -v test_appsetup.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 2 items collecting ... collected 2 items
@ -821,30 +821,30 @@ to show the setup/teardown flow::
@pytest.fixture(scope="module", params=["mod1", "mod2"]) @pytest.fixture(scope="module", params=["mod1", "mod2"])
def modarg(request): def modarg(request):
param = request.param param = request.param
print (" SETUP modarg %s" % param) print(" SETUP modarg %s" % param)
yield param yield param
print (" TEARDOWN modarg %s" % param) print(" TEARDOWN modarg %s" % param)
@pytest.fixture(scope="function", params=[1,2]) @pytest.fixture(scope="function", params=[1,2])
def otherarg(request): def otherarg(request):
param = request.param param = request.param
print (" SETUP otherarg %s" % param) print(" SETUP otherarg %s" % param)
yield param yield param
print (" TEARDOWN otherarg %s" % param) print(" TEARDOWN otherarg %s" % param)
def test_0(otherarg): def test_0(otherarg):
print (" RUN test0 with otherarg %s" % otherarg) print(" RUN test0 with otherarg %s" % otherarg)
def test_1(modarg): def test_1(modarg):
print (" RUN test1 with modarg %s" % modarg) print(" RUN test1 with modarg %s" % modarg)
def test_2(otherarg, modarg): def test_2(otherarg, modarg):
print (" RUN test2 with otherarg %s and modarg %s" % (otherarg, modarg)) print(" RUN test2 with otherarg %s and modarg %s" % (otherarg, modarg))
Let's run the tests in verbose mode and with looking at the print-output:: Let's run the tests in verbose mode and with looking at the print-output::
$ pytest -v -s test_module.py $ pytest -v -s test_module.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items collecting ... collected 8 items

View File

@ -26,9 +26,9 @@ a per-session Database object::
# content of conftest.py # content of conftest.py
class Database(object): class Database(object):
def __init__(self): def __init__(self):
print ("database instance created") print("database instance created")
def destroy(self): def destroy(self):
print ("database instance destroyed") print("database instance destroyed")
def pytest_funcarg__db(request): def pytest_funcarg__db(request):
return request.cached_setup(setup=DataBase, return request.cached_setup(setup=DataBase,

View File

@ -27,7 +27,7 @@ Install ``pytest``
2. Check that you installed the correct version:: 2. Check that you installed the correct version::
$ pytest --version $ pytest --version
This is pytest version 3.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py This is pytest version 4.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py
.. _`simpletest`: .. _`simpletest`:
@ -47,7 +47,7 @@ Thats it. You can now execute the test function::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
@ -138,7 +138,7 @@ Request a unique temporary directory for functional tests
# content of test_tmpdir.py # content of test_tmpdir.py
def test_needsfiles(tmpdir): def test_needsfiles(tmpdir):
print (tmpdir) print(tmpdir)
assert 0 assert 0
List the name ``tmpdir`` in the test function signature and ``pytest`` will lookup and call a fixture factory to create the resource before performing the test function call. Before the test runs, ``pytest`` creates a unique-per-test-invocation temporary directory:: List the name ``tmpdir`` in the test function signature and ``pytest`` will lookup and call a fixture factory to create the resource before performing the test function call. Before the test runs, ``pytest`` creates a unique-per-test-invocation temporary directory::
@ -151,7 +151,7 @@ List the name ``tmpdir`` in the test function signature and ``pytest`` will look
tmpdir = local('PYTEST_TMPDIR/test_needsfiles0') tmpdir = local('PYTEST_TMPDIR/test_needsfiles0')
def test_needsfiles(tmpdir): def test_needsfiles(tmpdir):
print (tmpdir) print(tmpdir)
> assert 0 > assert 0
E assert 0 E assert 0

View File

@ -26,7 +26,7 @@ To execute it::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item

View File

@ -54,7 +54,7 @@ them in turn::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items
@ -103,7 +103,7 @@ Let's run this::
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items collected 3 items

View File

@ -327,7 +327,7 @@ Running it with the report-on-xfail option gives this output::
example $ pytest -rx xfail_demo.py example $ pytest -rx xfail_demo.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR/example, inifile: rootdir: $REGENDOC_TMPDIR/example, inifile:
collected 7 items collected 7 items

View File

@ -39,7 +39,7 @@ Running this would result in a passed test except for the last
$ pytest test_tmp_path.py $ pytest test_tmp_path.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item
@ -99,7 +99,7 @@ Running this would result in a passed test except for the last
$ pytest test_tmpdir.py $ pytest test_tmpdir.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item

View File

@ -126,7 +126,7 @@ the ``self.db`` values in the traceback::
$ pytest test_unittest_db.py $ pytest test_unittest_db.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items collected 2 items

View File

@ -154,7 +154,7 @@ Example::
$ pytest -ra $ pytest -ra
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items
@ -177,7 +177,7 @@ More than one character can be used, so for example to only see failed and skipp
$ pytest -rfs $ pytest -rfs
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items collected 0 items

View File

@ -22,7 +22,7 @@ Running pytest now produces this output::
$ pytest test_show_warnings.py $ pytest test_show_warnings.py
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 item collected 1 item

View File

@ -73,7 +73,7 @@ sub directory but not for other directories::
a/conftest.py: a/conftest.py:
def pytest_runtest_setup(item): def pytest_runtest_setup(item):
# called for running each test in 'a' directory # called for running each test in 'a' directory
print ("setting up", item) print("setting up", item)
a/test_sub.py: a/test_sub.py:
def test_sub(): def test_sub():
@ -411,7 +411,7 @@ additionally it is possible to copy examples for an example folder before runnin
$ pytest $ pytest
=========================== test session starts ============================ =========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 2 items collected 2 items

View File

@ -65,9 +65,9 @@ def report(issues):
print(title) print(title)
# print() # print()
# lines = body.split("\n") # lines = body.split("\n")
# print ("\n".join(lines[:3])) # print("\n".join(lines[:3]))
# if len(lines) > 3 or len(body) > 240: # if len(lines) > 3 or len(body) > 240:
# print ("...") # print("...")
print("\n\nFound %s open issues" % len(issues)) print("\n\nFound %s open issues" % len(issues))

View File

@ -270,6 +270,7 @@ class AssertionRewritingHook(object):
_issue_config_warning( _issue_config_warning(
PytestWarning("Module already imported so cannot be rewritten: %s" % name), PytestWarning("Module already imported so cannot be rewritten: %s" % name),
self.config, self.config,
stacklevel=5,
) )
def load_module(self, name): def load_module(self, name):

View File

@ -56,7 +56,9 @@ class Cache(object):
from _pytest.warning_types import PytestWarning from _pytest.warning_types import PytestWarning
_issue_config_warning( _issue_config_warning(
PytestWarning(fmt.format(**args) if args else fmt), self._config PytestWarning(fmt.format(**args) if args else fmt),
self._config,
stacklevel=3,
) )
def makedir(self, name): def makedir(self, name):
@ -108,6 +110,10 @@ class Cache(object):
""" """
path = self._getvaluepath(key) path = self._getvaluepath(key)
try: try:
if path.parent.is_dir():
cache_dir_exists_already = True
else:
cache_dir_exists_already = self._cachedir.exists()
path.parent.mkdir(exist_ok=True, parents=True) path.parent.mkdir(exist_ok=True, parents=True)
except (IOError, OSError): except (IOError, OSError):
self.warn("could not create cache path {path}", path=path) self.warn("could not create cache path {path}", path=path)
@ -119,6 +125,7 @@ class Cache(object):
else: else:
with f: with f:
json.dump(value, f, indent=2, sort_keys=True) json.dump(value, f, indent=2, sort_keys=True)
if not cache_dir_exists_already:
self._ensure_supporting_files() self._ensure_supporting_files()
def _ensure_supporting_files(self): def _ensure_supporting_files(self):
@ -128,8 +135,10 @@ class Cache(object):
if not readme_path.is_file(): if not readme_path.is_file():
readme_path.write_text(README_CONTENT) readme_path.write_text(README_CONTENT)
msg = u"# created by pytest automatically, do not change\n*" gitignore_path = self._cachedir.joinpath(".gitignore")
self._cachedir.joinpath(".gitignore").write_text(msg, encoding="UTF-8") if not gitignore_path.is_file():
msg = u"# Created by pytest automatically.\n*"
gitignore_path.write_text(msg, encoding="UTF-8")
class LFPlugin(object): class LFPlugin(object):

View File

@ -11,10 +11,10 @@ import shlex
import sys import sys
import types import types
import warnings import warnings
from distutils.version import LooseVersion
import py import py
import six import six
from pkg_resources import parse_version
from pluggy import HookimplMarker from pluggy import HookimplMarker
from pluggy import HookspecMarker from pluggy import HookspecMarker
from pluggy import PluginManager from pluggy import PluginManager
@ -191,7 +191,7 @@ def _prepareconfig(args=None, plugins=None):
if warning: if warning:
from _pytest.warnings import _issue_config_warning from _pytest.warnings import _issue_config_warning
_issue_config_warning(warning, config=config) _issue_config_warning(warning, config=config, stacklevel=4)
return pluginmanager.hook.pytest_cmdline_parse( return pluginmanager.hook.pytest_cmdline_parse(
pluginmanager=pluginmanager, args=args pluginmanager=pluginmanager, args=args
) )
@ -815,7 +815,7 @@ class Config(object):
minver = self.inicfg.get("minversion", None) minver = self.inicfg.get("minversion", None)
if minver: if minver:
if LooseVersion(minver) > LooseVersion(pytest.__version__): if parse_version(minver) > parse_version(pytest.__version__):
raise pytest.UsageError( raise pytest.UsageError(
"%s:%d: requires pytest-%s, actual pytest-%s'" "%s:%d: requires pytest-%s, actual pytest-%s'"
% ( % (

View File

@ -42,6 +42,7 @@ def getcfg(args, config=None):
CFG_PYTEST_SECTION.format(filename=inibasename) CFG_PYTEST_SECTION.format(filename=inibasename)
), ),
config=config, config=config,
stacklevel=2,
) )
return base, p, iniconfig["pytest"] return base, p, iniconfig["pytest"]
if ( if (
@ -116,7 +117,9 @@ def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None):
# TODO: [pytest] section in *.cfg files is deprecated. Need refactoring once # TODO: [pytest] section in *.cfg files is deprecated. Need refactoring once
# the deprecation expires. # the deprecation expires.
_issue_config_warning( _issue_config_warning(
CFG_PYTEST_SECTION.format(filename=str(inifile)), config CFG_PYTEST_SECTION.format(filename=str(inifile)),
config,
stacklevel=2,
) )
break break
except KeyError: except KeyError:

View File

@ -13,8 +13,9 @@ import six
import pytest import pytest
from _pytest.fixtures import fixture from _pytest.fixtures import fixture
from _pytest.pathlib import Path
RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$") RE_IMPORT_ERROR_NAME = re.compile(r"^No module named (.*)$")
@fixture @fixture
@ -267,6 +268,9 @@ class MonkeyPatch(object):
self._cwd = os.getcwd() self._cwd = os.getcwd()
if hasattr(path, "chdir"): if hasattr(path, "chdir"):
path.chdir() path.chdir()
elif isinstance(path, Path):
# modern python uses the fspath protocol here LEGACY
os.chdir(str(path))
else: else:
os.chdir(path) os.chdir(path)

View File

@ -36,7 +36,7 @@ def pytest_configure(config):
from _pytest.deprecated import RESULT_LOG from _pytest.deprecated import RESULT_LOG
from _pytest.warnings import _issue_config_warning from _pytest.warnings import _issue_config_warning
_issue_config_warning(RESULT_LOG, config) _issue_config_warning(RESULT_LOG, config, stacklevel=2)
def pytest_unconfigure(config): def pytest_unconfigure(config):

View File

@ -647,9 +647,11 @@ class TerminalReporter(object):
def pytest_terminal_summary(self): def pytest_terminal_summary(self):
self.summary_errors() self.summary_errors()
self.summary_failures() self.summary_failures()
yield
self.summary_warnings() self.summary_warnings()
yield
self.summary_passes() self.summary_passes()
# Display any extra warnings from teardown here (if any).
self.summary_warnings()
def pytest_keyboard_interrupt(self, excinfo): def pytest_keyboard_interrupt(self, excinfo):
self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True) self._keyboardinterrupt_memo = excinfo.getrepr(funcargs=True)
@ -726,11 +728,21 @@ class TerminalReporter(object):
if not all_warnings: if not all_warnings:
return return
final = hasattr(self, "_already_displayed_warnings")
if final:
warnings = all_warnings[self._already_displayed_warnings :]
else:
warnings = all_warnings
self._already_displayed_warnings = len(warnings)
if not warnings:
return
grouped = itertools.groupby( grouped = itertools.groupby(
all_warnings, key=lambda wr: wr.get_location(self.config) warnings, key=lambda wr: wr.get_location(self.config)
) )
self.write_sep("=", "warnings summary", yellow=True, bold=False) title = "warnings summary (final)" if final else "warnings summary"
self.write_sep("=", title, yellow=True, bold=False)
for location, warning_records in grouped: for location, warning_records in grouped:
# legacy warnings show their location explicitly, while standard warnings look better without # legacy warnings show their location explicitly, while standard warnings look better without
# it because the location is already formatted into the message # it because the location is already formatted into the message
@ -786,8 +798,7 @@ class TerminalReporter(object):
self.write_line(line) self.write_line(line)
else: else:
msg = self._getfailureheadline(rep) msg = self._getfailureheadline(rep)
markup = {"red": True, "bold": True} self.write_sep("_", msg, red=True, bold=True)
self.write_sep("_", msg, **markup)
self._outrep_summary(rep) self._outrep_summary(rep)
for report in self.getreports(""): for report in self.getreports(""):
if report.nodeid == rep.nodeid and report.when == "teardown": if report.nodeid == rep.nodeid and report.when == "teardown":
@ -808,7 +819,7 @@ class TerminalReporter(object):
msg = "ERROR at setup of " + msg msg = "ERROR at setup of " + msg
elif rep.when == "teardown": elif rep.when == "teardown":
msg = "ERROR at teardown of " + msg msg = "ERROR at teardown of " + msg
self.write_sep("_", msg) self.write_sep("_", msg, red=True, bold=True)
self._outrep_summary(rep) self._outrep_summary(rep)
def _outrep_summary(self, rep): def _outrep_summary(self, rep):

View File

@ -10,6 +10,7 @@ import warnings
import attr import attr
import py import py
import six
import pytest import pytest
from .pathlib import ensure_reset_dir from .pathlib import ensure_reset_dir
@ -26,7 +27,14 @@ class TempPathFactory(object):
The base directory can be configured using the ``--basetemp`` option.""" The base directory can be configured using the ``--basetemp`` option."""
_given_basetemp = attr.ib() _given_basetemp = attr.ib(
# using os.path.abspath() to get absolute path instead of resolve() as it
# does not work the same in all platforms (see #4427)
# Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012)
convert=attr.converters.optional(
lambda p: Path(os.path.abspath(six.text_type(p)))
)
)
_trace = attr.ib() _trace = attr.ib()
_basetemp = attr.ib(default=None) _basetemp = attr.ib(default=None)
@ -53,7 +61,7 @@ class TempPathFactory(object):
""" return base temporary directory. """ """ return base temporary directory. """
if self._basetemp is None: if self._basetemp is None:
if self._given_basetemp is not None: if self._given_basetemp is not None:
basetemp = Path(self._given_basetemp) basetemp = self._given_basetemp
ensure_reset_dir(basetemp) ensure_reset_dir(basetemp)
else: else:
from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT") from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")

View File

@ -160,7 +160,7 @@ def pytest_terminal_summary(terminalreporter):
yield yield
def _issue_config_warning(warning, config): def _issue_config_warning(warning, config, stacklevel):
""" """
This function should be used instead of calling ``warnings.warn`` directly when we are in the "configure" stage: This function should be used instead of calling ``warnings.warn`` directly when we are in the "configure" stage:
at this point the actual options might not have been set, so we manually trigger the pytest_warning_captured at this point the actual options might not have been set, so we manually trigger the pytest_warning_captured
@ -168,10 +168,11 @@ def _issue_config_warning(warning, config):
:param warning: the warning instance. :param warning: the warning instance.
:param config: :param config:
:param stacklevel: stacklevel forwarded to warnings.warn
""" """
with warnings.catch_warnings(record=True) as records: with warnings.catch_warnings(record=True) as records:
warnings.simplefilter("always", type(warning)) warnings.simplefilter("always", type(warning))
warnings.warn(warning, stacklevel=2) warnings.warn(warning, stacklevel=stacklevel)
config.hook.pytest_warning_captured.call_historic( config.hook.pytest_warning_captured.call_historic(
kwargs=dict(warning_message=records[0], when="config", item=None) kwargs=dict(warning_message=records[0], when="config", item=None)
) )

View File

@ -206,7 +206,7 @@ class TestGeneralUsage(object):
testdir.makeconftest( testdir.makeconftest(
""" """
import sys import sys
print ("should not be seen") print("should not be seen")
sys.stderr.write("stder42\\n") sys.stderr.write("stder42\\n")
""" """
) )
@ -218,7 +218,7 @@ class TestGeneralUsage(object):
def test_conftest_printing_shows_if_error(self, testdir): def test_conftest_printing_shows_if_error(self, testdir):
testdir.makeconftest( testdir.makeconftest(
""" """
print ("should be seen") print("should be seen")
assert 0 assert 0
""" """
) )
@ -301,7 +301,7 @@ class TestGeneralUsage(object):
def pytest_generate_tests(metafunc): def pytest_generate_tests(metafunc):
metafunc.addcall({'x': 3}, id='hello-123') metafunc.addcall({'x': 3}, id='hello-123')
def pytest_runtest_setup(item): def pytest_runtest_setup(item):
print (item.keywords) print(item.keywords)
if 'hello-123' in item.keywords: if 'hello-123' in item.keywords:
pytest.skip("hello") pytest.skip("hello")
assert 0 assert 0

View File

@ -1495,7 +1495,7 @@ class TestFixtureManagerParseFactories(object):
return "class" return "class"
def test_hello(self, item, fm): def test_hello(self, item, fm):
faclist = fm.getfixturedefs("hello", item.nodeid) faclist = fm.getfixturedefs("hello", item.nodeid)
print (faclist) print(faclist)
assert len(faclist) == 3 assert len(faclist) == 3
assert faclist[0].func(item._request) == "conftest" assert faclist[0].func(item._request) == "conftest"
@ -2040,7 +2040,7 @@ class TestAutouseManagement(object):
values.append("step2-%d" % item) values.append("step2-%d" % item)
def test_finish(): def test_finish():
print (values) print(values)
assert values == ["setup-1", "step1-1", "step2-1", "teardown-1", assert values == ["setup-1", "step1-1", "step2-1", "teardown-1",
"setup-2", "step1-2", "step2-2", "teardown-2",] "setup-2", "step1-2", "step2-2", "teardown-2",]
""" """
@ -2880,7 +2880,7 @@ class TestFixtureMarker(object):
def base(request, fix1): def base(request, fix1):
def cleanup_base(): def cleanup_base():
values.append("fin_base") values.append("fin_base")
print ("finalizing base") print("finalizing base")
request.addfinalizer(cleanup_base) request.addfinalizer(cleanup_base)
def test_begin(): def test_begin():
@ -3480,13 +3480,13 @@ class TestContextManagerFixtureFuncs(object):
from test_context import fixture from test_context import fixture
@fixture @fixture
def arg1(): def arg1():
print ("setup") print("setup")
yield 1 yield 1
print ("teardown") print("teardown")
def test_1(arg1): def test_1(arg1):
print ("test1", arg1) print("test1", arg1)
def test_2(arg1): def test_2(arg1):
print ("test2", arg1) print("test2", arg1)
assert 0 assert 0
""" """
) )
@ -3509,13 +3509,13 @@ class TestContextManagerFixtureFuncs(object):
from test_context import fixture from test_context import fixture
@fixture(scope="module") @fixture(scope="module")
def arg1(): def arg1():
print ("setup") print("setup")
yield 1 yield 1
print ("teardown") print("teardown")
def test_1(arg1): def test_1(arg1):
print ("test1", arg1) print("test1", arg1)
def test_2(arg1): def test_2(arg1):
print ("test2", arg1) print("test2", arg1)
""" """
) )
result = testdir.runpytest("-s") result = testdir.runpytest("-s")

View File

@ -283,7 +283,7 @@ class TestReRunTests(object):
global count, req global count, req
assert request != req assert request != req
req = request req = request
print ("fix count %s" % count) print("fix count %s" % count)
count += 1 count += 1
def test_fix(fix): def test_fix(fix):
pass pass

View File

@ -33,6 +33,23 @@ class TestRaises(object):
except pytest.raises.Exception: except pytest.raises.Exception:
pass pass
def test_raises_repr_inflight(self):
"""Ensure repr() on an exception info inside a pytest.raises with block works (#4386)"""
class E(Exception):
pass
with pytest.raises(E) as excinfo:
# this test prints the inflight uninitialized object
# using repr and str as well as pprint to demonstrate
# it works
print(str(excinfo))
print(repr(excinfo))
import pprint
pprint.pprint(excinfo)
raise E()
def test_raises_as_contextmanager(self, testdir): def test_raises_as_contextmanager(self, testdir):
testdir.makepyfile( testdir.makepyfile(
""" """
@ -43,7 +60,7 @@ class TestRaises(object):
with pytest.raises(ZeroDivisionError) as excinfo: with pytest.raises(ZeroDivisionError) as excinfo:
assert isinstance(excinfo, _pytest._code.ExceptionInfo) assert isinstance(excinfo, _pytest._code.ExceptionInfo)
1/0 1/0
print (excinfo) print(excinfo)
assert excinfo.type == ZeroDivisionError assert excinfo.type == ZeroDivisionError
assert isinstance(excinfo.value, ZeroDivisionError) assert isinstance(excinfo.value, ZeroDivisionError)

View File

@ -899,5 +899,29 @@ def test_gitignore(testdir):
config = testdir.parseconfig() config = testdir.parseconfig()
cache = Cache.for_config(config) cache = Cache.for_config(config)
cache.set("foo", "bar") cache.set("foo", "bar")
msg = "# created by pytest automatically, do not change\n*" msg = "# Created by pytest automatically.\n*"
assert cache._cachedir.joinpath(".gitignore").read_text(encoding="UTF-8") == msg gitignore_path = cache._cachedir.joinpath(".gitignore")
assert gitignore_path.read_text(encoding="UTF-8") == msg
# Does not overwrite existing/custom one.
gitignore_path.write_text(u"custom")
cache.set("something", "else")
assert gitignore_path.read_text(encoding="UTF-8") == "custom"
def test_does_not_create_boilerplate_in_existing_dirs(testdir):
from _pytest.cacheprovider import Cache
testdir.makeini(
"""
[pytest]
cache_dir = .
"""
)
config = testdir.parseconfig()
cache = Cache.for_config(config)
cache.set("foo", "bar")
assert os.path.isdir("v") # cache contents
assert not os.path.exists(".gitignore")
assert not os.path.exists("README.md")

View File

@ -107,8 +107,8 @@ def test_capturing_unicode(testdir, method):
# taken from issue 227 from nosetests # taken from issue 227 from nosetests
def test_unicode(): def test_unicode():
import sys import sys
print (sys.stdout) print(sys.stdout)
print (%s) print(%s)
""" """
% obj % obj
) )
@ -121,7 +121,7 @@ def test_capturing_bytes_in_utf8_encoding(testdir, method):
testdir.makepyfile( testdir.makepyfile(
""" """
def test_unicode(): def test_unicode():
print ('b\\u00f6y') print('b\\u00f6y')
""" """
) )
result = testdir.runpytest("--capture=%s" % method) result = testdir.runpytest("--capture=%s" % method)
@ -131,7 +131,7 @@ def test_capturing_bytes_in_utf8_encoding(testdir, method):
def test_collect_capturing(testdir): def test_collect_capturing(testdir):
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
print ("collect %s failure" % 13) print("collect %s failure" % 13)
import xyz42123 import xyz42123
""" """
) )
@ -144,14 +144,14 @@ class TestPerTestCapturing(object):
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
def setup_module(mod): def setup_module(mod):
print ("setup module") print("setup module")
def setup_function(function): def setup_function(function):
print ("setup " + function.__name__) print("setup " + function.__name__)
def test_func1(): def test_func1():
print ("in func1") print("in func1")
assert 0 assert 0
def test_func2(): def test_func2():
print ("in func2") print("in func2")
assert 0 assert 0
""" """
) )
@ -172,14 +172,14 @@ class TestPerTestCapturing(object):
""" """
import sys import sys
def setup_module(func): def setup_module(func):
print ("module-setup") print("module-setup")
def setup_function(func): def setup_function(func):
print ("function-setup") print("function-setup")
def test_func(): def test_func():
print ("in function") print("in function")
assert 0 assert 0
def teardown_function(func): def teardown_function(func):
print ("in teardown") print("in teardown")
""" """
) )
result = testdir.runpytest(p) result = testdir.runpytest(p)
@ -198,9 +198,9 @@ class TestPerTestCapturing(object):
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
def test_func1(): def test_func1():
print ("in func1") print("in func1")
def test_func2(): def test_func2():
print ("in func2") print("in func2")
assert 0 assert 0
""" """
) )
@ -213,12 +213,12 @@ class TestPerTestCapturing(object):
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
def setup_function(function): def setup_function(function):
print ("setup func1") print("setup func1")
def teardown_function(function): def teardown_function(function):
print ("teardown func1") print("teardown func1")
assert 0 assert 0
def test_func1(): def test_func1():
print ("in func1") print("in func1")
pass pass
""" """
) )
@ -238,7 +238,7 @@ class TestPerTestCapturing(object):
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
def teardown_module(mod): def teardown_module(mod):
print ("teardown module") print("teardown module")
assert 0 assert 0
def test_func(): def test_func():
pass pass
@ -259,10 +259,10 @@ class TestPerTestCapturing(object):
"""\ """\
import sys import sys
def test_capturing(): def test_capturing():
print (42) print(42)
sys.stderr.write(str(23)) sys.stderr.write(str(23))
def test_capturing_error(): def test_capturing_error():
print (1) print(1)
sys.stderr.write(str(2)) sys.stderr.write(str(2))
raise ValueError raise ValueError
""" """
@ -392,7 +392,7 @@ class TestCaptureFixture(object):
reprec = testdir.inline_runsource( reprec = testdir.inline_runsource(
"""\ """\
def test_hello(capsys): def test_hello(capsys):
print (42) print(42)
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out.startswith("42") assert out.startswith("42")
""", """,
@ -460,7 +460,7 @@ class TestCaptureFixture(object):
p = testdir.makepyfile( p = testdir.makepyfile(
"""\ """\
def test_hello(cap{}): def test_hello(cap{}):
print ("xxx42xxx") print("xxx42xxx")
assert 0 assert 0
""".format( """.format(
method method
@ -702,7 +702,7 @@ def test_capture_conftest_runtest_setup(testdir):
testdir.makeconftest( testdir.makeconftest(
""" """
def pytest_runtest_setup(): def pytest_runtest_setup():
print ("hello19") print("hello19")
""" """
) )
testdir.makepyfile("def test_func(): pass") testdir.makepyfile("def test_func(): pass")
@ -737,7 +737,7 @@ def test_capture_early_option_parsing(testdir):
testdir.makeconftest( testdir.makeconftest(
""" """
def pytest_runtest_setup(): def pytest_runtest_setup():
print ("hello19") print("hello19")
""" """
) )
testdir.makepyfile("def test_func(): pass") testdir.makepyfile("def test_func(): pass")
@ -1302,14 +1302,14 @@ def test_capturing_and_logging_fundamentals(testdir, method):
logging.warn("hello1") logging.warn("hello1")
outerr = cap.readouterr() outerr = cap.readouterr()
print ("suspend, captured %%s" %%(outerr,)) print("suspend, captured %%s" %%(outerr,))
logging.warn("hello2") logging.warn("hello2")
cap.pop_outerr_to_orig() cap.pop_outerr_to_orig()
logging.warn("hello3") logging.warn("hello3")
outerr = cap.readouterr() outerr = cap.readouterr()
print ("suspend2, captured %%s" %% (outerr,)) print("suspend2, captured %%s" %% (outerr,))
""" """
% (method,) % (method,)
) )

View File

@ -371,7 +371,7 @@ class TestPython(object):
import sys import sys
def test_fail(): def test_fail():
print ("hello-stdout") print("hello-stdout")
sys.stderr.write("hello-stderr\\n") sys.stderr.write("hello-stderr\\n")
logging.info('info msg') logging.info('info msg')
logging.warning('warning msg') logging.warning('warning msg')
@ -589,7 +589,7 @@ class TestPython(object):
""" """
# coding: latin1 # coding: latin1
def test_hello(): def test_hello():
print (%r) print(%r)
assert 0 assert 0
""" """
% value % value

View File

@ -190,7 +190,7 @@ def test_ini_markers(testdir):
""" """
def test_markers(pytestconfig): def test_markers(pytestconfig):
markers = pytestconfig.getini("markers") markers = pytestconfig.getini("markers")
print (markers) print(markers)
assert len(markers) >= 2 assert len(markers) >= 2
assert markers[0].startswith("a1:") assert markers[0].startswith("a1:")
assert markers[1].startswith("a2:") assert markers[1].startswith("a2:")

View File

@ -71,11 +71,11 @@ def test_nose_setup_func(testdir):
@with_setup(my_setup, my_teardown) @with_setup(my_setup, my_teardown)
def test_hello(): def test_hello():
print (values) print(values)
assert values == [1] assert values == [1]
def test_world(): def test_world():
print (values) print(values)
assert values == [1,2] assert values == [1,2]
""" """
@ -95,11 +95,11 @@ def test_nose_setup_func_failure(testdir):
@with_setup(my_setup, my_teardown) @with_setup(my_setup, my_teardown)
def test_hello(): def test_hello():
print (values) print(values)
assert values == [1] assert values == [1]
def test_world(): def test_world():
print (values) print(values)
assert values == [1,2] assert values == [1,2]
""" """
@ -147,11 +147,11 @@ def test_nose_setup_partial(testdir):
my_teardown_partial = partial(my_teardown, 2) my_teardown_partial = partial(my_teardown, 2)
def test_hello(): def test_hello():
print (values) print(values)
assert values == [1] assert values == [1]
def test_world(): def test_world():
print (values) print(values)
assert values == [1,2] assert values == [1,2]
test_hello.setup = my_setup_partial test_hello.setup = my_setup_partial
@ -202,21 +202,21 @@ def test_nose_test_generator_fixtures(testdir):
class TestClass(object): class TestClass(object):
def setup(self): def setup(self):
print ("setup called in %s" % self) print("setup called in %s" % self)
self.called = ['setup'] self.called = ['setup']
def teardown(self): def teardown(self):
print ("teardown called in %s" % self) print("teardown called in %s" % self)
eq_(self.called, ['setup']) eq_(self.called, ['setup'])
self.called.append('teardown') self.called.append('teardown')
def test(self): def test(self):
print ("test called in %s" % self) print("test called in %s" % self)
for i in range(0, 5): for i in range(0, 5):
yield self.check, i yield self.check, i
def check(self, i): def check(self, i):
print ("check called in %s" % self) print("check called in %s" % self)
expect = ['setup'] expect = ['setup']
#for x in range(0, i): #for x in range(0, i):
# expect.append('setup') # expect.append('setup')

View File

@ -202,21 +202,21 @@ def test_func_generator_setup(testdir):
import sys import sys
def setup_module(mod): def setup_module(mod):
print ("setup_module") print("setup_module")
mod.x = [] mod.x = []
def setup_function(fun): def setup_function(fun):
print ("setup_function") print("setup_function")
x.append(1) x.append(1)
def teardown_function(fun): def teardown_function(fun):
print ("teardown_function") print("teardown_function")
x.pop() x.pop()
def test_one(): def test_one():
assert x == [1] assert x == [1]
def check(): def check():
print ("check") print("check")
sys.stderr.write("e\\n") sys.stderr.write("e\\n")
assert x == [1] assert x == [1]
yield check yield check

View File

@ -365,7 +365,7 @@ class TestFixtureReporting(object):
testdir.makepyfile( testdir.makepyfile(
""" """
def setup_function(function): def setup_function(function):
print ("setup func") print("setup func")
assert 0 assert 0
def test_nada(): def test_nada():
pass pass
@ -389,7 +389,7 @@ class TestFixtureReporting(object):
def test_nada(): def test_nada():
pass pass
def teardown_function(function): def teardown_function(function):
print ("teardown func") print("teardown func")
assert 0 assert 0
""" """
) )
@ -412,7 +412,7 @@ class TestFixtureReporting(object):
assert 0, "failingfunc" assert 0, "failingfunc"
def teardown_function(function): def teardown_function(function):
print ("teardown func") print("teardown func")
assert False assert False
""" """
) )
@ -436,13 +436,13 @@ class TestFixtureReporting(object):
testdir.makepyfile( testdir.makepyfile(
""" """
def setup_function(function): def setup_function(function):
print ("setup func") print("setup func")
def test_fail(): def test_fail():
assert 0, "failingfunc" assert 0, "failingfunc"
def teardown_function(function): def teardown_function(function):
print ("teardown func") print("teardown func")
""" """
) )
result = testdir.runpytest() result = testdir.runpytest()
@ -854,7 +854,7 @@ class TestGenericReporting(object):
def g(): def g():
raise IndexError raise IndexError
def test_func(): def test_func():
print (6*7) print(6*7)
g() # --calling-- g() # --calling--
""" """
) )
@ -863,9 +863,9 @@ class TestGenericReporting(object):
result = testdir.runpytest("--tb=%s" % tbopt) result = testdir.runpytest("--tb=%s" % tbopt)
s = result.stdout.str() s = result.stdout.str()
if tbopt == "long": if tbopt == "long":
assert "print (6*7)" in s assert "print(6*7)" in s
else: else:
assert "print (6*7)" not in s assert "print(6*7)" not in s
if tbopt != "no": if tbopt != "no":
assert "--calling--" in s assert "--calling--" in s
assert "IndexError" in s assert "IndexError" in s
@ -881,7 +881,7 @@ class TestGenericReporting(object):
def g(): def g():
raise IndexError raise IndexError
def test_func1(): def test_func1():
print (6*7) print(6*7)
g() # --calling-- g() # --calling--
def test_func2(): def test_func2():
assert 0, "hello" assert 0, "hello"
@ -1074,11 +1074,54 @@ def test_terminal_summary_warnings_are_displayed(testdir):
warnings.warn(UserWarning('internal warning')) warnings.warn(UserWarning('internal warning'))
""" """
) )
result = testdir.runpytest() testdir.makepyfile(
"""
def test_failure():
import warnings
warnings.warn("warning_from_" + "test")
assert 0
"""
)
result = testdir.runpytest("-ra")
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
["*conftest.py:3:*internal warning", "*== 1 warnings in *"] [
"*= warnings summary =*",
"*warning_from_test*",
"*= short test summary info =*",
"*= warnings summary (final) =*",
"*conftest.py:3:*internal warning",
"*== 1 failed, 2 warnings in *",
]
) )
assert "None" not in result.stdout.str() assert "None" not in result.stdout.str()
stdout = result.stdout.str()
assert stdout.count("warning_from_test") == 1
assert stdout.count("=== warnings summary ") == 2
@pytest.mark.filterwarnings("default")
def test_terminal_summary_warnings_header_once(testdir):
testdir.makepyfile(
"""
def test_failure():
import warnings
warnings.warn("warning_from_" + "test")
assert 0
"""
)
result = testdir.runpytest("-ra")
result.stdout.fnmatch_lines(
[
"*= warnings summary =*",
"*warning_from_test*",
"*= short test summary info =*",
"*== 1 failed, 1 warnings in *",
]
)
assert "None" not in result.stdout.str()
stdout = result.stdout.str()
assert stdout.count("warning_from_test") == 1
assert stdout.count("=== warnings summary ") == 1
@pytest.mark.parametrize( @pytest.mark.parametrize(

View File

@ -4,6 +4,7 @@ from __future__ import print_function
import sys import sys
import attr
import six import six
import pytest import pytest
@ -25,12 +26,29 @@ def test_ensuretemp(recwarn):
assert d1.check(dir=1) assert d1.check(dir=1)
@attr.s
class FakeConfig(object):
basetemp = attr.ib()
trace = attr.ib(default=None)
@property
def trace(self):
return self
def get(self, key):
return lambda *k: None
@property
def option(self):
return self
class TestTempdirHandler(object): class TestTempdirHandler(object):
def test_mktemp(self, testdir): def test_mktemp(self, tmp_path):
from _pytest.tmpdir import TempdirFactory, TempPathFactory from _pytest.tmpdir import TempdirFactory, TempPathFactory
config = testdir.parseconfig() config = FakeConfig(tmp_path)
config.option.basetemp = testdir.mkdir("hello")
t = TempdirFactory(TempPathFactory.from_config(config)) t = TempdirFactory(TempPathFactory.from_config(config))
tmp = t.mktemp("world") tmp = t.mktemp("world")
assert tmp.relto(t.getbasetemp()) == "world0" assert tmp.relto(t.getbasetemp()) == "world0"
@ -40,6 +58,15 @@ class TestTempdirHandler(object):
assert tmp2.relto(t.getbasetemp()).startswith("this") assert tmp2.relto(t.getbasetemp()).startswith("this")
assert tmp2 != tmp assert tmp2 != tmp
@pytest.mark.issue(4425)
def test_tmppath_relative_basetemp_absolute(self, tmp_path, monkeypatch):
from _pytest.tmpdir import TempPathFactory
monkeypatch.chdir(tmp_path)
config = FakeConfig("hello")
t = TempPathFactory.from_config(config)
assert t.getbasetemp().resolve() == (tmp_path / "hello").resolve()
class TestConfigTmpdir(object): class TestConfigTmpdir(object):
def test_getbasetemp_custom_removes_old(self, testdir): def test_getbasetemp_custom_removes_old(self, testdir):

View File

@ -244,7 +244,7 @@ def test_setup_failure_is_shown(testdir):
def setUp(self): def setUp(self):
assert 0, "down1" assert 0, "down1"
def test_method(self): def test_method(self):
print ("never42") print("never42")
xyz xyz
""" """
) )
@ -610,14 +610,14 @@ def test_djangolike_testcase(testdir):
class DjangoLikeTestCase(TestCase): class DjangoLikeTestCase(TestCase):
def setUp(self): def setUp(self):
print ("setUp()") print("setUp()")
def test_presetup_has_been_run(self): def test_presetup_has_been_run(self):
print ("test_thing()") print("test_thing()")
self.assertTrue(hasattr(self, 'was_presetup')) self.assertTrue(hasattr(self, 'was_presetup'))
def tearDown(self): def tearDown(self):
print ("tearDown()") print("tearDown()")
def __call__(self, result=None): def __call__(self, result=None):
try: try:
@ -639,11 +639,11 @@ def test_djangolike_testcase(testdir):
return return
def _pre_setup(self): def _pre_setup(self):
print ("_pre_setup()") print("_pre_setup()")
self.was_presetup = True self.was_presetup = True
def _post_teardown(self): def _post_teardown(self):
print ("_post_teardown()") print("_post_teardown()")
""" """
) )
result = testdir.runpytest("-s") result = testdir.runpytest("-s")

View File

@ -310,7 +310,7 @@ def test_warning_captured_hook(testdir):
""" """
from _pytest.warnings import _issue_config_warning from _pytest.warnings import _issue_config_warning
def pytest_configure(config): def pytest_configure(config):
_issue_config_warning(UserWarning("config warning"), config) _issue_config_warning(UserWarning("config warning"), config, stacklevel=2)
""" """
) )
testdir.makepyfile( testdir.makepyfile(