Merge branch 'master' of github.com:pytest-dev/pytest

This commit is contained in:
Rachel Kogan 2018-04-17 16:21:04 -04:00
commit 8ff8a82c51
14 changed files with 81 additions and 39 deletions

View File

@ -48,8 +48,7 @@ fix the bug itself.
Fix bugs
--------
Look through the GitHub issues for bugs. Here is a filter you can use:
https://github.com/pytest-dev/pytest/labels/type%3A%20bug
Look through the `GitHub issues for bugs <https://github.com/pytest-dev/pytest/labels/type:%20bug>`_.
:ref:`Talk <contact>` to developers to find out how you can fix specific bugs.
@ -60,8 +59,7 @@ Don't forget to check the issue trackers of your favourite plugins, too!
Implement features
------------------
Look through the GitHub issues for enhancements. Here is a filter you can use:
https://github.com/pytest-dev/pytest/labels/enhancement
Look through the `GitHub issues for enhancements <https://github.com/pytest-dev/pytest/labels/type:%20enhancement>`_.
:ref:`Talk <contact>` to developers to find out how you can implement specific
features.

View File

@ -138,7 +138,8 @@ def showhelp(config):
tw.line("to see available markers type: pytest --markers")
tw.line("to see available fixtures type: pytest --fixtures")
tw.line("(shown according to specified file_or_dir or current dir "
"if not specified)")
"if not specified; fixtures with leading '_' are only shown "
"with the '-v' option")
for warningreport in reporter.stats.get('warnings', []):
tw.line("warning : " + warningreport.message, red=True)

View File

@ -75,7 +75,8 @@ def pytest_addoption(parser):
group = parser.getgroup("general")
group.addoption('--fixtures', '--funcargs',
action="store_true", dest="showfixtures", default=False,
help="show available fixtures, sorted by plugin appearance")
help="show available fixtures, sorted by plugin appearance "
"(fixtures with leading '_' are only shown with '-v')")
group.addoption(
'--fixtures-per-test',
action="store_true",

View File

@ -105,6 +105,7 @@ def pytest_runtest_setup(item):
def pytest_runtest_call(item):
_update_current_test_var(item, 'call')
sys.last_type, sys.last_value, sys.last_traceback = (None, None, None)
try:
item.runtest()
except Exception:
@ -114,7 +115,7 @@ def pytest_runtest_call(item):
sys.last_type = type
sys.last_value = value
sys.last_traceback = tb
del tb # Get rid of it in this namespace
del type, value, tb # Get rid of these in this frame
raise

View File

@ -0,0 +1,3 @@
Reset ``sys.last_type``, ``sys.last_value`` and ``sys.last_traceback`` before each test executes. Those attributes
are added by pytest during the test run to aid debugging, but were never reset so they would create a leaking
reference to the last failing test's frame which in turn could never be reclaimed by the garbage collector.

View File

@ -0,0 +1 @@
Mention in documentation and CLI help that fixtures with leading ``_`` are printed by ``pytest --fixtures`` only if the ``-v`` option is added.

View File

@ -12,7 +12,7 @@ For information on plugin hooks and objects, see :ref:`plugins`.
For information on the ``pytest.mark`` mechanism, see :ref:`mark`.
For information about fixtures, see :ref:`fixtures`. To see a complete list of available fixtures, type::
For information about fixtures, see :ref:`fixtures`. To see a complete list of available fixtures (add ``-v`` to also see fixtures with leading ``_``), type ::
$ pytest -q --fixtures
cache

View File

@ -111,11 +111,11 @@ with a list of available function arguments.
.. note::
You can always issue::
You can always issue ::
pytest --fixtures test_simplefactory.py
to see available fixtures.
to see available fixtures (fixtures with leading ``_`` are only shown if you add the ``-v`` option).
Fixtures: a prime example of dependency injection
---------------------------------------------------
@ -141,7 +141,7 @@ automatically gets discovered by pytest. The discovery of
fixture functions starts at test classes, then test modules, then
``conftest.py`` files and finally builtin and third party plugins.
You can also use the ``conftest.py`` file to implement
You can also use the ``conftest.py`` file to implement
:ref:`local per-directory plugins <conftest.py plugins>`.
Sharing test data

View File

@ -166,6 +166,8 @@ Find out what kind of builtin :ref:`pytest fixtures <fixtures>` exist with the c
pytest --fixtures # shows builtin and custom fixtures
Note that this command omits fixtures with leading ``_`` unless the ``-v`` option is added.
Continue reading
-------------------------------------

View File

@ -23,7 +23,7 @@ command line options
``--full-trace``
don't cut any tracebacks (default is to cut).
``--fixtures``
show available function arguments, sorted by plugin
show available fixtures, sorted by plugin appearance (fixtures with leading ``_`` are only shown with '-v')
Start improving this plugin in 30 seconds
=========================================

View File

@ -87,6 +87,10 @@ def main():
'write_to': '_pytest/_version.py',
},
url='http://pytest.org',
project_urls={
'Source': 'https://github.com/pytest-dev/pytest',
'Tracker': 'https://github.com/pytest-dev/pytest/issues',
},
license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
author=(

View File

@ -988,3 +988,33 @@ def test_fixture_order_respects_scope(testdir):
''')
result = testdir.runpytest()
assert result.ret == 0
def test_frame_leak_on_failing_test(testdir):
"""pytest would leak garbage referencing the frames of tests that failed that could never be reclaimed (#2798)
Unfortunately it was not possible to remove the actual circles because most of them
are made of traceback objects which cannot be weakly referenced. Those objects at least
can be eventually claimed by the garbage collector.
"""
testdir.makepyfile('''
import gc
import weakref
class Obj:
pass
ref = None
def test1():
obj = Obj()
global ref
ref = weakref.ref(obj)
assert 0
def test2():
gc.collect()
assert ref() is None
''')
result = testdir.runpytest_subprocess()
result.stdout.fnmatch_lines(['*1 failed, 1 passed in*'])

View File

@ -719,18 +719,20 @@ def test_makereport_getsource_dynamic_code(testdir, monkeypatch):
result.stdout.fnmatch_lines(["*test_fix*", "*fixture*'missing'*not found*"])
def test_store_except_info_on_eror():
def test_store_except_info_on_error():
""" Test that upon test failure, the exception info is stored on
sys.last_traceback and friends.
"""
# Simulate item that raises a specific exception
class ItemThatRaises(object):
# Simulate item that might raise a specific exception, depending on `raise_error` class var
class ItemMightRaise(object):
nodeid = 'item_that_raises'
raise_error = True
def runtest(self):
raise IndexError('TEST')
if self.raise_error:
raise IndexError('TEST')
try:
runner.pytest_runtest_call(ItemThatRaises())
runner.pytest_runtest_call(ItemMightRaise())
except IndexError:
pass
# Check that exception info is stored on sys
@ -738,6 +740,13 @@ def test_store_except_info_on_eror():
assert sys.last_value.args[0] == 'TEST'
assert sys.last_traceback
# The next run should clear the exception info stored by the previous run
ItemMightRaise.raise_error = False
runner.pytest_runtest_call(ItemMightRaise())
assert sys.last_type is None
assert sys.last_value is None
assert sys.last_traceback is None
def test_current_test_env_var(testdir, monkeypatch):
pytest_current_test_vars = []

36
tox.ini
View File

@ -13,7 +13,7 @@ envlist =
{py27,py36}-{pexpect,xdist,trial,numpy,pluggymaster}
py27-nobyte
doctesting
py35-freeze
py36-freeze
docs
[testenv]
@ -56,12 +56,11 @@ deps =
hypothesis>=3.5.2
changedir=testing
commands =
pytest -n1 -ra {posargs:.}
pytest -n8 -ra {posargs:.}
[testenv:py36-xdist]
deps = {[testenv:py27-xdist]deps}
commands =
pytest -n3 -ra {posargs:testing}
commands = {[testenv:py27-xdist]commands}
[testenv:py27-pexpect]
changedir = testing
@ -71,11 +70,10 @@ commands =
pytest -ra test_pdb.py test_terminal.py test_unittest.py
[testenv:py36-pexpect]
changedir = testing
platform = linux|darwin
changedir = {[testenv:py27-pexpect]changedir}
platform = {[testenv:py27-pexpect]platform}
deps = {[testenv:py27-pexpect]deps}
commands =
pytest -ra test_pdb.py test_terminal.py test_unittest.py
commands = {[testenv:py27-pexpect]commands}
[testenv:py27-nobyte]
deps =
@ -95,18 +93,16 @@ commands =
[testenv:py36-trial]
deps = {[testenv:py27-trial]deps}
commands =
pytest -ra {posargs:testing/test_unittest.py}
commands = {[testenv:py27-trial]commands}
[testenv:py27-numpy]
deps=numpy
deps = numpy
commands=
pytest -ra {posargs:testing/python/approx.py}
[testenv:py36-numpy]
deps=numpy
commands=
pytest -ra {posargs:testing/python/approx.py}
deps = {[testenv:py27-numpy]deps}
commands = {[testenv:py27-numpy]commands}
[testenv:py27-pluggymaster]
setenv=
@ -115,12 +111,9 @@ deps =
{[testenv]deps}
git+https://github.com/pytest-dev/pluggy.git@master
[testenv:py35-pluggymaster]
setenv=
_PYTEST_SETUP_SKIP_PLUGGY_DEP=1
deps =
{[testenv:py27-pluggymaster]deps}
git+https://github.com/pytest-dev/pluggy.git@master
[testenv:py36-pluggymaster]
setenv = {[testenv:py27-pluggymaster]setenv}
deps = {[testenv:py27-pluggymaster]deps}
[testenv:docs]
skipsdist = True
@ -176,7 +169,7 @@ changedir = testing
commands =
{envpython} {envbindir}/py.test-jython -ra {posargs}
[testenv:py35-freeze]
[testenv:py36-freeze]
changedir = testing/freeze
deps = pyinstaller
commands =
@ -199,7 +192,6 @@ commands =
[pytest]
minversion = 2.0
plugins = pytester
#--pyargs --doctest-modules --ignore=.tox
addopts = -ra -p pytester --ignore=testing/cx_freeze
rsyncdirs = tox.ini pytest.py _pytest testing
python_files = test_*.py *_test.py testing/*/*.py