Merge branch 'master' of github.com:pytest-dev/pytest
This commit is contained in:
commit
8ff8a82c51
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
---------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
-------------------------------------
|
||||
|
||||
|
|
|
@ -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
|
||||
=========================================
|
||||
|
|
4
setup.py
4
setup.py
|
@ -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=(
|
||||
|
|
|
@ -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*'])
|
||||
|
|
|
@ -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
36
tox.ini
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue