Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8368e6c2e | ||
|
|
fac8208e8f | ||
|
|
51abdb80db | ||
|
|
65534682aa | ||
|
|
e980fbbe39 | ||
|
|
07e768ab68 | ||
|
|
9a2e0c061d | ||
|
|
056d9e8dc2 | ||
|
|
46f5d7a1bb | ||
|
|
30453057e8 | ||
|
|
3b757b1b8c | ||
|
|
14a9b1ec83 | ||
|
|
9fcbf57163 | ||
|
|
1fb2457018 | ||
|
|
92219e576b | ||
|
|
143ac5af99 | ||
|
|
409b919fc0 | ||
|
|
eadd15fe45 | ||
|
|
3f7223af44 | ||
|
|
20085542e2 | ||
|
|
cfaf3600c1 | ||
|
|
188df8100c | ||
|
|
44fa5a77d4 | ||
|
|
31476c69ab | ||
|
|
6200920dc3 | ||
|
|
46c5d5355e | ||
|
|
39024a7536 | ||
|
|
ae62ced080 | ||
|
|
6166151ee4 | ||
|
|
bedceaacc4 | ||
|
|
1127d519db | ||
|
|
b5ac61657a | ||
|
|
48548767fc | ||
|
|
7536e949b1 | ||
|
|
287c003cfd | ||
|
|
aa53e37fa2 | ||
|
|
dd97c94035 | ||
|
|
264e455410 | ||
|
|
75f11f0b65 | ||
|
|
45d0a21294 | ||
|
|
147b43f832 | ||
|
|
6e14585ca2 | ||
|
|
dae74b674e | ||
|
|
2a99e5dd2a | ||
|
|
9361d48b61 | ||
|
|
ebddac6a5c |
1
AUTHORS
1
AUTHORS
@@ -197,3 +197,4 @@ Xuan Luong
|
||||
Xuecong Liao
|
||||
Zoltán Máté
|
||||
Roland Puntaier
|
||||
Allan Feldman
|
||||
|
||||
@@ -8,6 +8,43 @@
|
||||
|
||||
.. towncrier release notes start
|
||||
|
||||
Pytest 3.4.2 (2018-03-04)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Removed progress information when capture option is ``no``. (`#3203
|
||||
<https://github.com/pytest-dev/pytest/issues/3203>`_)
|
||||
|
||||
- Refactor check of bindir from ``exists`` to ``isdir``. (`#3241
|
||||
<https://github.com/pytest-dev/pytest/issues/3241>`_)
|
||||
|
||||
- Fix ``TypeError`` issue when using ``approx`` with a ``Decimal`` value.
|
||||
(`#3247 <https://github.com/pytest-dev/pytest/issues/3247>`_)
|
||||
|
||||
- Fix reference cycle generated when using the ``request`` fixture. (`#3249
|
||||
<https://github.com/pytest-dev/pytest/issues/3249>`_)
|
||||
|
||||
- ``[tool:pytest]`` sections in ``*.cfg`` files passed by the ``-c`` option are
|
||||
now properly recognized. (`#3260
|
||||
<https://github.com/pytest-dev/pytest/issues/3260>`_)
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Add logging plugin to plugins list. (`#3209
|
||||
<https://github.com/pytest-dev/pytest/issues/3209>`_)
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- Fix minor typo in fixture.rst (`#3259
|
||||
<https://github.com/pytest-dev/pytest/issues/3259>`_)
|
||||
|
||||
|
||||
Pytest 3.4.1 (2018-02-20)
|
||||
=========================
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
.. image:: https://ci.appveyor.com/api/projects/status/mrgbjaua7t33pg6b?svg=true
|
||||
:target: https://ci.appveyor.com/project/pytestbot/pytest
|
||||
|
||||
.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg
|
||||
:target: https://www.codetriage.com/pytest-dev/pytest
|
||||
|
||||
The ``pytest`` framework makes it easy to write small tests, yet
|
||||
scales to support complex functional testing for applications and libraries.
|
||||
|
||||
|
||||
@@ -1327,10 +1327,14 @@ def determine_setup(inifile, args, warnfunc=None):
|
||||
dirs = get_dirs_from_args(args)
|
||||
if inifile:
|
||||
iniconfig = py.iniconfig.IniConfig(inifile)
|
||||
try:
|
||||
inicfg = iniconfig["pytest"]
|
||||
except KeyError:
|
||||
inicfg = None
|
||||
is_cfg_file = str(inifile).endswith('.cfg')
|
||||
sections = ['tool:pytest', 'pytest'] if is_cfg_file else ['pytest']
|
||||
for section in sections:
|
||||
try:
|
||||
inicfg = iniconfig[section]
|
||||
break
|
||||
except KeyError:
|
||||
inicfg = None
|
||||
rootdir = get_common_ancestor(dirs)
|
||||
else:
|
||||
ancestor = get_common_ancestor(dirs)
|
||||
|
||||
@@ -24,6 +24,12 @@ from _pytest.compat import (
|
||||
from _pytest.outcomes import fail, TEST_OUTCOME
|
||||
|
||||
|
||||
@attr.s(frozen=True)
|
||||
class PseudoFixtureDef(object):
|
||||
cached_result = attr.ib()
|
||||
scope = attr.ib()
|
||||
|
||||
|
||||
def pytest_sessionstart(session):
|
||||
import _pytest.python
|
||||
import _pytest.nodes
|
||||
@@ -440,10 +446,9 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||
fixturedef = self._getnextfixturedef(argname)
|
||||
except FixtureLookupError:
|
||||
if argname == "request":
|
||||
class PseudoFixtureDef(object):
|
||||
cached_result = (self, [0], None)
|
||||
scope = "function"
|
||||
return PseudoFixtureDef
|
||||
cached_result = (self, [0], None)
|
||||
scope = "function"
|
||||
return PseudoFixtureDef(cached_result, scope)
|
||||
raise
|
||||
# remove indent to prevent the python3 exception
|
||||
# from leaking into the call
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
""" Access and control log capturing. """
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import logging
|
||||
|
||||
@@ -170,7 +170,7 @@ def _in_venv(path):
|
||||
"""Attempts to detect if ``path`` is the root of a Virtual Environment by
|
||||
checking for the existence of the appropriate activate script"""
|
||||
bindir = path.join('Scripts' if sys.platform.startswith('win') else 'bin')
|
||||
if not bindir.exists():
|
||||
if not bindir.isdir():
|
||||
return False
|
||||
activates = ('activate', 'activate.csh', 'activate.fish',
|
||||
'Activate', 'Activate.bat', 'Activate.ps1')
|
||||
|
||||
@@ -153,6 +153,8 @@ class ApproxScalar(ApproxBase):
|
||||
"""
|
||||
Perform approximate comparisons for single numbers only.
|
||||
"""
|
||||
DEFAULT_ABSOLUTE_TOLERANCE = 1e-12
|
||||
DEFAULT_RELATIVE_TOLERANCE = 1e-6
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
@@ -223,7 +225,7 @@ class ApproxScalar(ApproxBase):
|
||||
|
||||
# Figure out what the absolute tolerance should be. ``self.abs`` is
|
||||
# either None or a value specified by the user.
|
||||
absolute_tolerance = set_default(self.abs, 1e-12)
|
||||
absolute_tolerance = set_default(self.abs, self.DEFAULT_ABSOLUTE_TOLERANCE)
|
||||
|
||||
if absolute_tolerance < 0:
|
||||
raise ValueError("absolute tolerance can't be negative: {}".format(absolute_tolerance))
|
||||
@@ -241,7 +243,7 @@ class ApproxScalar(ApproxBase):
|
||||
# we've made sure the user didn't ask for an absolute tolerance only,
|
||||
# because we don't want to raise errors about the relative tolerance if
|
||||
# we aren't even going to use it.
|
||||
relative_tolerance = set_default(self.rel, 1e-6) * abs(self.expected)
|
||||
relative_tolerance = set_default(self.rel, self.DEFAULT_RELATIVE_TOLERANCE) * abs(self.expected)
|
||||
|
||||
if relative_tolerance < 0:
|
||||
raise ValueError("relative tolerance can't be negative: {}".format(absolute_tolerance))
|
||||
@@ -252,6 +254,13 @@ class ApproxScalar(ApproxBase):
|
||||
return max(relative_tolerance, absolute_tolerance)
|
||||
|
||||
|
||||
class ApproxDecimal(ApproxScalar):
|
||||
from decimal import Decimal
|
||||
|
||||
DEFAULT_ABSOLUTE_TOLERANCE = Decimal('1e-12')
|
||||
DEFAULT_RELATIVE_TOLERANCE = Decimal('1e-6')
|
||||
|
||||
|
||||
def approx(expected, rel=None, abs=None, nan_ok=False):
|
||||
"""
|
||||
Assert that two numbers (or two sets of numbers) are equal to each other
|
||||
@@ -401,6 +410,7 @@ def approx(expected, rel=None, abs=None, nan_ok=False):
|
||||
|
||||
from collections import Mapping, Sequence
|
||||
from _pytest.compat import STRING_TYPES as String
|
||||
from decimal import Decimal
|
||||
|
||||
# Delegate the comparison to a class that knows how to deal with the type
|
||||
# of the expected value (e.g. int, float, list, dict, numpy.array, etc).
|
||||
@@ -422,6 +432,8 @@ def approx(expected, rel=None, abs=None, nan_ok=False):
|
||||
cls = ApproxMapping
|
||||
elif isinstance(expected, Sequence) and not isinstance(expected, String):
|
||||
cls = ApproxSequence
|
||||
elif isinstance(expected, Decimal):
|
||||
cls = ApproxDecimal
|
||||
else:
|
||||
cls = ApproxScalar
|
||||
|
||||
|
||||
@@ -324,6 +324,8 @@ class TerminalReporter(object):
|
||||
_PROGRESS_LENGTH = len(' [100%]')
|
||||
|
||||
def _get_progress_information_message(self):
|
||||
if self.config.getoption('capture') == 'no':
|
||||
return ''
|
||||
collected = self._session.testscollected
|
||||
if collected:
|
||||
progress = len(self._progress_nodeids_reported) * 100 // collected
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Move import of ``doctest.UnexpectedException`` to top-level to avoid possible errors when using ``--pdb``.
|
||||
@@ -1 +0,0 @@
|
||||
Added printing of captured stdout/stderr before entering pdb, and improved a test which was giving false negatives about output capturing.
|
||||
@@ -1 +0,0 @@
|
||||
pytest has changed the publication procedure and is now being published to PyPI directly from Travis.
|
||||
@@ -1 +0,0 @@
|
||||
Fix ordering of tests using parametrized fixtures which can lead to fixtures being created more than necessary.
|
||||
@@ -1 +0,0 @@
|
||||
Rename ``ParameterSet._for_parameterize()`` to ``_for_parametrize()`` in order to comply with the naming convention.
|
||||
@@ -1 +0,0 @@
|
||||
Fix bug where logging happening at hooks outside of "test run" hooks would cause an internal error.
|
||||
@@ -1 +0,0 @@
|
||||
Add Sphinx parameter docs for ``match`` and ``message`` args to ``pytest.raises``.
|
||||
@@ -1 +0,0 @@
|
||||
Detect arguments injected by ``unittest.mock.patch`` decorator correctly when pypi ``mock.patch`` is installed and imported.
|
||||
@@ -1 +0,0 @@
|
||||
Errors shown when a ``pytest.raises()`` with ``match=`` fails are now cleaner on what happened: When no exception was raised, the "matching '...'" part got removed as it falsely implies that an exception was raised but it didn't match. When a wrong exception was raised, it's now thrown (like ``pytest.raised()`` without ``match=`` would) instead of complaining about the unmatched text.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed output capture handling in doctests on macOS.
|
||||
@@ -1 +0,0 @@
|
||||
Skip failing pdb/doctest test on mac.
|
||||
@@ -6,6 +6,7 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-3.4.2
|
||||
release-3.4.1
|
||||
release-3.4.0
|
||||
release-3.3.2
|
||||
|
||||
28
doc/en/announce/release-3.4.2.rst
Normal file
28
doc/en/announce/release-3.4.2.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
pytest-3.4.2
|
||||
=======================================
|
||||
|
||||
pytest 3.4.2 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 http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Allan Feldman
|
||||
* Bruno Oliveira
|
||||
* Florian Bruhin
|
||||
* Jason R. Coombs
|
||||
* Kyle Altendorf
|
||||
* Maik Figura
|
||||
* Ronny Pfannschmidt
|
||||
* codetriage-readme-bot
|
||||
* feuillemorte
|
||||
* joshm91
|
||||
* mike
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -358,7 +358,7 @@ get on the terminal - we are working on that)::
|
||||
> int(s)
|
||||
E ValueError: invalid literal for int() with base 10: 'qwe'
|
||||
|
||||
<0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:583>:1: ValueError
|
||||
<0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:595>:1: ValueError
|
||||
______________________ TestRaises.test_raises_doesnt _______________________
|
||||
|
||||
self = <failure_demo.TestRaises object at 0xdeadbeef>
|
||||
|
||||
@@ -369,7 +369,7 @@ ends, but ``addfinalizer`` has two key differences over ``yield``:
|
||||
Fixtures can introspect the requesting test context
|
||||
-------------------------------------------------------------
|
||||
|
||||
Fixture function can accept the :py:class:`request <FixtureRequest>` object
|
||||
Fixture functions can accept the :py:class:`request <FixtureRequest>` object
|
||||
to introspect the "requesting" test function, class or module context.
|
||||
Further extending the previous ``smtp`` fixture example, let's
|
||||
read an optional server URL from the test module which uses our fixture::
|
||||
|
||||
@@ -160,9 +160,9 @@ List the name ``tmpdir`` in the test function signature and ``pytest`` will look
|
||||
PYTEST_TMPDIR/test_needsfiles0
|
||||
1 failed in 0.12 seconds
|
||||
|
||||
More info on tmpdir handling is available at `Temporary directories and files <tmpdir handling>`_.
|
||||
More info on tmpdir handling is available at :ref:`Temporary directories and files <tmpdir handling>`.
|
||||
|
||||
Find out what kind of builtin ```pytest`` fixtures <fixtures>`_ exist with the command::
|
||||
Find out what kind of builtin :ref:`pytest fixtures <fixtures>` exist with the command::
|
||||
|
||||
pytest --fixtures # shows builtin and custom fixtures
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ in the `pytest repository <https://github.com/pytest-dev/pytest>`_.
|
||||
_pytest.resultlog
|
||||
_pytest.runner
|
||||
_pytest.main
|
||||
_pytest.logging
|
||||
_pytest.skipping
|
||||
_pytest.terminal
|
||||
_pytest.tmpdir
|
||||
|
||||
@@ -278,7 +278,7 @@ the plugin manager like this:
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
plugin = config.pluginmanager.getplugin("name_of_plugin")
|
||||
plugin = config.pluginmanager.get_plugin("name_of_plugin")
|
||||
|
||||
If you want to look at the names of existing plugins, use
|
||||
the ``--trace-config`` option.
|
||||
|
||||
@@ -249,6 +249,7 @@ class TestApprox(object):
|
||||
(Decimal('-1.000001'), Decimal('-1.0')),
|
||||
]
|
||||
for a, x in within_1e6:
|
||||
assert a == approx(x)
|
||||
assert a == approx(x, rel=Decimal('5e-6'), abs=0)
|
||||
assert a != approx(x, rel=Decimal('5e-7'), abs=0)
|
||||
assert approx(x, rel=Decimal('5e-6'), abs=0) == a
|
||||
|
||||
@@ -519,6 +519,41 @@ class TestRequestBasic(object):
|
||||
assert len(arg2fixturedefs) == 1
|
||||
assert arg2fixturedefs['something'][0].argname == "something"
|
||||
|
||||
def test_request_garbage(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import sys
|
||||
import pytest
|
||||
import gc
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def something(request):
|
||||
# this method of test doesn't work on pypy
|
||||
if hasattr(sys, "pypy_version_info"):
|
||||
yield
|
||||
else:
|
||||
original = gc.get_debug()
|
||||
gc.set_debug(gc.DEBUG_SAVEALL)
|
||||
gc.collect()
|
||||
|
||||
yield
|
||||
|
||||
gc.collect()
|
||||
leaked_types = sum(1 for _ in gc.garbage
|
||||
if 'PseudoFixtureDef' in str(_))
|
||||
|
||||
gc.garbage[:] = []
|
||||
|
||||
try:
|
||||
assert leaked_types == 0
|
||||
finally:
|
||||
gc.set_debug(original)
|
||||
|
||||
def test_func():
|
||||
pass
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_getfixturevalue_recursive(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
|
||||
@@ -110,6 +110,13 @@ class TestConfigCmdlineParsing(object):
|
||||
config = testdir.parseconfig("-c", "custom.cfg")
|
||||
assert config.getini("custom") == "1"
|
||||
|
||||
testdir.makefile(".cfg", custom_tool_pytest_section="""
|
||||
[tool:pytest]
|
||||
custom = 1
|
||||
""")
|
||||
config = testdir.parseconfig("-c", "custom_tool_pytest_section.cfg")
|
||||
assert config.getini("custom") == "1"
|
||||
|
||||
def test_absolute_win32_path(self, testdir):
|
||||
temp_cfg_file = testdir.makefile(".cfg", custom="""
|
||||
[pytest]
|
||||
|
||||
@@ -1046,6 +1046,9 @@ class TestProgress(object):
|
||||
r'test_foobar.py \.{5}',
|
||||
])
|
||||
|
||||
output = testdir.runpytest('--capture=no')
|
||||
assert "%]" not in output.stdout.str()
|
||||
|
||||
|
||||
class TestProgressWithTeardown(object):
|
||||
"""Ensure we show the correct percentages for tests that fail during teardown (#3088)"""
|
||||
|
||||
Reference in New Issue
Block a user