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
|
Fix bugs
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Look through the GitHub issues for bugs. Here is a filter you can use:
|
Look through the `GitHub issues for bugs <https://github.com/pytest-dev/pytest/labels/type:%20bug>`_.
|
||||||
https://github.com/pytest-dev/pytest/labels/type%3A%20bug
|
|
||||||
|
|
||||||
:ref:`Talk <contact>` to developers to find out how you can fix specific bugs.
|
: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
|
Implement features
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Look through the GitHub issues for enhancements. Here is a filter you can use:
|
Look through the `GitHub issues for enhancements <https://github.com/pytest-dev/pytest/labels/type:%20enhancement>`_.
|
||||||
https://github.com/pytest-dev/pytest/labels/enhancement
|
|
||||||
|
|
||||||
:ref:`Talk <contact>` to developers to find out how you can implement specific
|
:ref:`Talk <contact>` to developers to find out how you can implement specific
|
||||||
features.
|
features.
|
||||||
|
|
|
@ -138,7 +138,8 @@ def showhelp(config):
|
||||||
tw.line("to see available markers type: pytest --markers")
|
tw.line("to see available markers type: pytest --markers")
|
||||||
tw.line("to see available fixtures type: pytest --fixtures")
|
tw.line("to see available fixtures type: pytest --fixtures")
|
||||||
tw.line("(shown according to specified file_or_dir or current dir "
|
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', []):
|
for warningreport in reporter.stats.get('warnings', []):
|
||||||
tw.line("warning : " + warningreport.message, red=True)
|
tw.line("warning : " + warningreport.message, red=True)
|
||||||
|
|
|
@ -75,7 +75,8 @@ def pytest_addoption(parser):
|
||||||
group = parser.getgroup("general")
|
group = parser.getgroup("general")
|
||||||
group.addoption('--fixtures', '--funcargs',
|
group.addoption('--fixtures', '--funcargs',
|
||||||
action="store_true", dest="showfixtures", default=False,
|
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(
|
group.addoption(
|
||||||
'--fixtures-per-test',
|
'--fixtures-per-test',
|
||||||
action="store_true",
|
action="store_true",
|
||||||
|
|
|
@ -105,6 +105,7 @@ def pytest_runtest_setup(item):
|
||||||
|
|
||||||
def pytest_runtest_call(item):
|
def pytest_runtest_call(item):
|
||||||
_update_current_test_var(item, 'call')
|
_update_current_test_var(item, 'call')
|
||||||
|
sys.last_type, sys.last_value, sys.last_traceback = (None, None, None)
|
||||||
try:
|
try:
|
||||||
item.runtest()
|
item.runtest()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -114,7 +115,7 @@ def pytest_runtest_call(item):
|
||||||
sys.last_type = type
|
sys.last_type = type
|
||||||
sys.last_value = value
|
sys.last_value = value
|
||||||
sys.last_traceback = tb
|
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
|
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 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
|
$ pytest -q --fixtures
|
||||||
cache
|
cache
|
||||||
|
|
|
@ -111,11 +111,11 @@ with a list of available function arguments.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
You can always issue::
|
You can always issue ::
|
||||||
|
|
||||||
pytest --fixtures test_simplefactory.py
|
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
|
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
|
pytest --fixtures # shows builtin and custom fixtures
|
||||||
|
|
||||||
|
Note that this command omits fixtures with leading ``_`` unless the ``-v`` option is added.
|
||||||
|
|
||||||
Continue reading
|
Continue reading
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ command line options
|
||||||
``--full-trace``
|
``--full-trace``
|
||||||
don't cut any tracebacks (default is to cut).
|
don't cut any tracebacks (default is to cut).
|
||||||
``--fixtures``
|
``--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
|
Start improving this plugin in 30 seconds
|
||||||
=========================================
|
=========================================
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -87,6 +87,10 @@ def main():
|
||||||
'write_to': '_pytest/_version.py',
|
'write_to': '_pytest/_version.py',
|
||||||
},
|
},
|
||||||
url='http://pytest.org',
|
url='http://pytest.org',
|
||||||
|
project_urls={
|
||||||
|
'Source': 'https://github.com/pytest-dev/pytest',
|
||||||
|
'Tracker': 'https://github.com/pytest-dev/pytest/issues',
|
||||||
|
},
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
author=(
|
author=(
|
||||||
|
|
|
@ -988,3 +988,33 @@ def test_fixture_order_respects_scope(testdir):
|
||||||
''')
|
''')
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest()
|
||||||
assert result.ret == 0
|
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*"])
|
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
|
""" Test that upon test failure, the exception info is stored on
|
||||||
sys.last_traceback and friends.
|
sys.last_traceback and friends.
|
||||||
"""
|
"""
|
||||||
# Simulate item that raises a specific exception
|
# Simulate item that might raise a specific exception, depending on `raise_error` class var
|
||||||
class ItemThatRaises(object):
|
class ItemMightRaise(object):
|
||||||
nodeid = 'item_that_raises'
|
nodeid = 'item_that_raises'
|
||||||
|
raise_error = True
|
||||||
|
|
||||||
def runtest(self):
|
def runtest(self):
|
||||||
raise IndexError('TEST')
|
if self.raise_error:
|
||||||
|
raise IndexError('TEST')
|
||||||
try:
|
try:
|
||||||
runner.pytest_runtest_call(ItemThatRaises())
|
runner.pytest_runtest_call(ItemMightRaise())
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
# Check that exception info is stored on sys
|
# 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_value.args[0] == 'TEST'
|
||||||
assert sys.last_traceback
|
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):
|
def test_current_test_env_var(testdir, monkeypatch):
|
||||||
pytest_current_test_vars = []
|
pytest_current_test_vars = []
|
||||||
|
|
36
tox.ini
36
tox.ini
|
@ -13,7 +13,7 @@ envlist =
|
||||||
{py27,py36}-{pexpect,xdist,trial,numpy,pluggymaster}
|
{py27,py36}-{pexpect,xdist,trial,numpy,pluggymaster}
|
||||||
py27-nobyte
|
py27-nobyte
|
||||||
doctesting
|
doctesting
|
||||||
py35-freeze
|
py36-freeze
|
||||||
docs
|
docs
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
@ -56,12 +56,11 @@ deps =
|
||||||
hypothesis>=3.5.2
|
hypothesis>=3.5.2
|
||||||
changedir=testing
|
changedir=testing
|
||||||
commands =
|
commands =
|
||||||
pytest -n1 -ra {posargs:.}
|
pytest -n8 -ra {posargs:.}
|
||||||
|
|
||||||
[testenv:py36-xdist]
|
[testenv:py36-xdist]
|
||||||
deps = {[testenv:py27-xdist]deps}
|
deps = {[testenv:py27-xdist]deps}
|
||||||
commands =
|
commands = {[testenv:py27-xdist]commands}
|
||||||
pytest -n3 -ra {posargs:testing}
|
|
||||||
|
|
||||||
[testenv:py27-pexpect]
|
[testenv:py27-pexpect]
|
||||||
changedir = testing
|
changedir = testing
|
||||||
|
@ -71,11 +70,10 @@ commands =
|
||||||
pytest -ra test_pdb.py test_terminal.py test_unittest.py
|
pytest -ra test_pdb.py test_terminal.py test_unittest.py
|
||||||
|
|
||||||
[testenv:py36-pexpect]
|
[testenv:py36-pexpect]
|
||||||
changedir = testing
|
changedir = {[testenv:py27-pexpect]changedir}
|
||||||
platform = linux|darwin
|
platform = {[testenv:py27-pexpect]platform}
|
||||||
deps = {[testenv:py27-pexpect]deps}
|
deps = {[testenv:py27-pexpect]deps}
|
||||||
commands =
|
commands = {[testenv:py27-pexpect]commands}
|
||||||
pytest -ra test_pdb.py test_terminal.py test_unittest.py
|
|
||||||
|
|
||||||
[testenv:py27-nobyte]
|
[testenv:py27-nobyte]
|
||||||
deps =
|
deps =
|
||||||
|
@ -95,18 +93,16 @@ commands =
|
||||||
|
|
||||||
[testenv:py36-trial]
|
[testenv:py36-trial]
|
||||||
deps = {[testenv:py27-trial]deps}
|
deps = {[testenv:py27-trial]deps}
|
||||||
commands =
|
commands = {[testenv:py27-trial]commands}
|
||||||
pytest -ra {posargs:testing/test_unittest.py}
|
|
||||||
|
|
||||||
[testenv:py27-numpy]
|
[testenv:py27-numpy]
|
||||||
deps=numpy
|
deps = numpy
|
||||||
commands=
|
commands=
|
||||||
pytest -ra {posargs:testing/python/approx.py}
|
pytest -ra {posargs:testing/python/approx.py}
|
||||||
|
|
||||||
[testenv:py36-numpy]
|
[testenv:py36-numpy]
|
||||||
deps=numpy
|
deps = {[testenv:py27-numpy]deps}
|
||||||
commands=
|
commands = {[testenv:py27-numpy]commands}
|
||||||
pytest -ra {posargs:testing/python/approx.py}
|
|
||||||
|
|
||||||
[testenv:py27-pluggymaster]
|
[testenv:py27-pluggymaster]
|
||||||
setenv=
|
setenv=
|
||||||
|
@ -115,12 +111,9 @@ deps =
|
||||||
{[testenv]deps}
|
{[testenv]deps}
|
||||||
git+https://github.com/pytest-dev/pluggy.git@master
|
git+https://github.com/pytest-dev/pluggy.git@master
|
||||||
|
|
||||||
[testenv:py35-pluggymaster]
|
[testenv:py36-pluggymaster]
|
||||||
setenv=
|
setenv = {[testenv:py27-pluggymaster]setenv}
|
||||||
_PYTEST_SETUP_SKIP_PLUGGY_DEP=1
|
deps = {[testenv:py27-pluggymaster]deps}
|
||||||
deps =
|
|
||||||
{[testenv:py27-pluggymaster]deps}
|
|
||||||
git+https://github.com/pytest-dev/pluggy.git@master
|
|
||||||
|
|
||||||
[testenv:docs]
|
[testenv:docs]
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
@ -176,7 +169,7 @@ changedir = testing
|
||||||
commands =
|
commands =
|
||||||
{envpython} {envbindir}/py.test-jython -ra {posargs}
|
{envpython} {envbindir}/py.test-jython -ra {posargs}
|
||||||
|
|
||||||
[testenv:py35-freeze]
|
[testenv:py36-freeze]
|
||||||
changedir = testing/freeze
|
changedir = testing/freeze
|
||||||
deps = pyinstaller
|
deps = pyinstaller
|
||||||
commands =
|
commands =
|
||||||
|
@ -199,7 +192,6 @@ commands =
|
||||||
[pytest]
|
[pytest]
|
||||||
minversion = 2.0
|
minversion = 2.0
|
||||||
plugins = pytester
|
plugins = pytester
|
||||||
#--pyargs --doctest-modules --ignore=.tox
|
|
||||||
addopts = -ra -p pytester --ignore=testing/cx_freeze
|
addopts = -ra -p pytester --ignore=testing/cx_freeze
|
||||||
rsyncdirs = tox.ini pytest.py _pytest testing
|
rsyncdirs = tox.ini pytest.py _pytest testing
|
||||||
python_files = test_*.py *_test.py testing/*/*.py
|
python_files = test_*.py *_test.py testing/*/*.py
|
||||||
|
|
Loading…
Reference in New Issue