Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d398d8706 | ||
|
|
9ab4032f74 | ||
|
|
53b08730e4 | ||
|
|
1deb60f02f | ||
|
|
fb8395d93f | ||
|
|
b08c599bad | ||
|
|
51fd451dc9 | ||
|
|
1d021540a3 | ||
|
|
8bfe434f75 | ||
|
|
f9ebe3c607 | ||
|
|
bd54116d03 | ||
|
|
8b9482e39c | ||
|
|
943f4ac236 | ||
|
|
6f43eee106 | ||
|
|
e1f3c0f9c3 | ||
|
|
192f6992d2 | ||
|
|
6465244269 | ||
|
|
097acaf11b | ||
|
|
3d8649b206 | ||
|
|
a8c16d9b75 | ||
|
|
3edf417969 | ||
|
|
0084fd9783 | ||
|
|
e89efa8325 | ||
|
|
3edcc71c41 | ||
|
|
866daf57fe |
@@ -1,7 +1,7 @@
|
||||
exclude: doc/en/example/py2py3/test_py2.py
|
||||
repos:
|
||||
- repo: https://github.com/python/black
|
||||
rev: 19.3b0
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 19.10b0
|
||||
hooks:
|
||||
- id: black
|
||||
args: [--safe, --quiet]
|
||||
|
||||
1
AUTHORS
1
AUTHORS
@@ -58,6 +58,7 @@ Christian Theunert
|
||||
Christian Tismer
|
||||
Christopher Gilling
|
||||
Christopher Dignam
|
||||
Claudio Madotto
|
||||
CrazyMerlyn
|
||||
Cyrus Maden
|
||||
Damian Skrzypczak
|
||||
|
||||
@@ -18,6 +18,43 @@ with advance notice in the **Deprecations** section of releases.
|
||||
|
||||
.. towncrier release notes start
|
||||
|
||||
pytest 4.6.8 (2019-12-19)
|
||||
=========================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- `#5471 <https://github.com/pytest-dev/pytest/issues/5471>`_: JUnit XML now includes a timestamp and hostname in the testsuite tag.
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#5430 <https://github.com/pytest-dev/pytest/issues/5430>`_: junitxml: Logs for failed test are now passed to junit report in case the test fails during call phase.
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#6345 <https://github.com/pytest-dev/pytest/issues/6345>`_: Pin ``colorama`` to ``0.4.1`` only for Python 3.4 so newer Python versions can still receive colorama updates.
|
||||
|
||||
|
||||
pytest 4.6.7 (2019-12-05)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#5477 <https://github.com/pytest-dev/pytest/issues/5477>`_: The XML file produced by ``--junitxml`` now correctly contain a ``<testsuites>`` root element.
|
||||
|
||||
|
||||
- `#6044 <https://github.com/pytest-dev/pytest/issues/6044>`_: Properly ignore ``FileNotFoundError`` (``OSError.errno == NOENT`` in Python 2) exceptions when trying to remove old temporary directories,
|
||||
for instance when multiple processes try to remove the same directory (common with ``pytest-xdist``
|
||||
for example).
|
||||
|
||||
|
||||
pytest 4.6.6 (2019-10-11)
|
||||
=========================
|
||||
|
||||
|
||||
@@ -48,12 +48,6 @@ jobs:
|
||||
# pypy3:
|
||||
# python.version: 'pypy3'
|
||||
# tox.env: 'pypy3'
|
||||
py34-xdist:
|
||||
python.version: '3.4'
|
||||
tox.env: 'py34-xdist'
|
||||
# Coverage for:
|
||||
# - _pytest.compat._bytes_to_ascii
|
||||
PYTEST_COVERAGE: '1'
|
||||
py35-xdist:
|
||||
python.version: '3.5'
|
||||
tox.env: 'py35-xdist'
|
||||
|
||||
7
codecov.yml
Normal file
7
codecov.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
coverage:
|
||||
status:
|
||||
project: true
|
||||
patch: true
|
||||
changes: true
|
||||
|
||||
comment: off
|
||||
@@ -6,6 +6,8 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-4.6.8
|
||||
release-4.6.7
|
||||
release-4.6.6
|
||||
release-4.6.5
|
||||
release-4.6.4
|
||||
|
||||
19
doc/en/announce/release-4.6.7.rst
Normal file
19
doc/en/announce/release-4.6.7.rst
Normal file
@@ -0,0 +1,19 @@
|
||||
pytest-4.6.7
|
||||
=======================================
|
||||
|
||||
pytest 4.6.7 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:
|
||||
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
20
doc/en/announce/release-4.6.8.rst
Normal file
20
doc/en/announce/release-4.6.8.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
pytest-4.6.8
|
||||
=======================================
|
||||
|
||||
pytest 4.6.8 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
|
||||
* Ryan Mast
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -434,11 +434,10 @@ Running it results in some skips if we don't have all the python interpreters in
|
||||
.. code-block:: pytest
|
||||
|
||||
. $ pytest -rs -q multipython.py
|
||||
...ssssssssssssssssssssssss [100%]
|
||||
......sss......ssssssssssss [100%]
|
||||
========================= short test summary info ==========================
|
||||
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:31: 'python3.4' not found
|
||||
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:31: 'python3.5' not found
|
||||
3 passed, 24 skipped in 0.12 seconds
|
||||
SKIPPED [15] $REGENDOC_TMPDIR/CWD/multipython.py:31: 'python3.5' not found
|
||||
12 passed, 15 skipped in 0.12 seconds
|
||||
|
||||
Indirect parametrization of optional implementations/imports
|
||||
--------------------------------------------------------------------
|
||||
|
||||
@@ -436,7 +436,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
|
||||
items = [1, 2, 3]
|
||||
print("items is %r" % items)
|
||||
> a, b = items.pop()
|
||||
E TypeError: cannot unpack non-iterable int object
|
||||
E TypeError: 'int' object is not iterable
|
||||
|
||||
failure_demo.py:182: TypeError
|
||||
--------------------------- Captured stdout call ---------------------------
|
||||
@@ -515,7 +515,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
|
||||
def test_z2_type_error(self):
|
||||
items = 3
|
||||
> a, b = items
|
||||
E TypeError: cannot unpack non-iterable int object
|
||||
E TypeError: 'int' object is not iterable
|
||||
|
||||
failure_demo.py:222: TypeError
|
||||
______________________ TestMoreErrors.test_startswith ______________________
|
||||
|
||||
@@ -28,7 +28,7 @@ Install ``pytest``
|
||||
.. code-block:: bash
|
||||
|
||||
$ pytest --version
|
||||
This is pytest version 4.x.y, imported from $PYTHON_PREFIX/lib/python3.7/site-packages/pytest.py
|
||||
This is pytest version 4.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py
|
||||
|
||||
.. _`simpletest`:
|
||||
|
||||
|
||||
3
setup.py
3
setup.py
@@ -13,7 +13,8 @@ INSTALL_REQUIRES = [
|
||||
"atomicwrites>=1.0",
|
||||
'funcsigs>=1.0;python_version<"3.0"',
|
||||
'pathlib2>=2.2.0;python_version<"3.6"',
|
||||
'colorama;sys_platform=="win32"',
|
||||
'colorama<=0.4.1;sys_platform=="win32" and python_version=="3.4"',
|
||||
'colorama;sys_platform=="win32" and python_version!="3.4"',
|
||||
"pluggy>=0.12,<1.0",
|
||||
'importlib-metadata>=0.12;python_version<"3.8"',
|
||||
"wcwidth",
|
||||
|
||||
@@ -116,13 +116,13 @@ def directory_arg(path, optname):
|
||||
|
||||
|
||||
# Plugins that cannot be disabled via "-p no:X" currently.
|
||||
essential_plugins = ( # fmt: off
|
||||
essential_plugins = (
|
||||
"mark",
|
||||
"main",
|
||||
"runner",
|
||||
"fixtures",
|
||||
"helpconfig", # Provides -p.
|
||||
) # fmt: on
|
||||
)
|
||||
|
||||
default_plugins = essential_plugins + (
|
||||
"python",
|
||||
|
||||
@@ -15,9 +15,11 @@ from __future__ import print_function
|
||||
|
||||
import functools
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
import py
|
||||
import six
|
||||
@@ -595,6 +597,8 @@ class LogXML(object):
|
||||
if report.when == "call":
|
||||
reporter.append_failure(report)
|
||||
self.open_reports.append(report)
|
||||
if not self.log_passing_tests:
|
||||
reporter.write_captured_output(report)
|
||||
else:
|
||||
reporter.append_error(report)
|
||||
elif report.skipped:
|
||||
@@ -667,18 +671,19 @@ class LogXML(object):
|
||||
)
|
||||
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
|
||||
|
||||
logfile.write(
|
||||
Junit.testsuite(
|
||||
self._get_global_properties_node(),
|
||||
[x.to_xml() for x in self.node_reporters_ordered],
|
||||
name=self.suite_name,
|
||||
errors=self.stats["error"],
|
||||
failures=self.stats["failure"],
|
||||
skipped=self.stats["skipped"],
|
||||
tests=numtests,
|
||||
time="%.3f" % suite_time_delta,
|
||||
).unicode(indent=0)
|
||||
suite_node = Junit.testsuite(
|
||||
self._get_global_properties_node(),
|
||||
[x.to_xml() for x in self.node_reporters_ordered],
|
||||
name=self.suite_name,
|
||||
errors=self.stats["error"],
|
||||
failures=self.stats["failure"],
|
||||
skipped=self.stats["skipped"],
|
||||
tests=numtests,
|
||||
time="%.3f" % suite_time_delta,
|
||||
timestamp=datetime.fromtimestamp(self.suite_start_time).isoformat(),
|
||||
hostname=platform.node(),
|
||||
)
|
||||
logfile.write(Junit.testsuites([suite_node]).unicode(indent=0))
|
||||
logfile.close()
|
||||
|
||||
def pytest_terminal_summary(self, terminalreporter):
|
||||
|
||||
@@ -48,24 +48,38 @@ def ensure_reset_dir(path):
|
||||
|
||||
|
||||
def on_rm_rf_error(func, path, exc, **kwargs):
|
||||
"""Handles known read-only errors during rmtree."""
|
||||
"""Handles known read-only errors during rmtree.
|
||||
|
||||
The returned value is used only by our own tests.
|
||||
"""
|
||||
start_path = kwargs["start_path"]
|
||||
excvalue = exc[1]
|
||||
exctype, excvalue = exc[:2]
|
||||
|
||||
# another process removed the file in the middle of the "rm_rf" (xdist for example)
|
||||
# more context: https://github.com/pytest-dev/pytest/issues/5974#issuecomment-543799018
|
||||
if isinstance(excvalue, OSError) and excvalue.errno == errno.ENOENT:
|
||||
return False
|
||||
|
||||
if not isinstance(excvalue, OSError) or excvalue.errno not in (
|
||||
errno.EACCES,
|
||||
errno.EPERM,
|
||||
):
|
||||
warnings.warn(
|
||||
PytestWarning("(rm_rf) error removing {}: {}".format(path, excvalue))
|
||||
PytestWarning(
|
||||
"(rm_rf) error removing {}\n{}: {}".format(path, exctype, excvalue)
|
||||
)
|
||||
)
|
||||
return
|
||||
return False
|
||||
|
||||
if func not in (os.rmdir, os.remove, os.unlink):
|
||||
warnings.warn(
|
||||
PytestWarning("(rm_rf) error removing {}: {}".format(path, excvalue))
|
||||
PytestWarning(
|
||||
"(rm_rf) unknown function {} when removing {}:\n{}: {}".format(
|
||||
path, func, exctype, excvalue
|
||||
)
|
||||
)
|
||||
)
|
||||
return
|
||||
return False
|
||||
|
||||
# Chmod + retry.
|
||||
import stat
|
||||
@@ -86,6 +100,7 @@ def on_rm_rf_error(func, path, exc, **kwargs):
|
||||
chmod_rw(str(path))
|
||||
|
||||
func(path)
|
||||
return True
|
||||
|
||||
|
||||
def rm_rf(path):
|
||||
|
||||
@@ -694,7 +694,7 @@ def raises(expected_exception, *args, **kwargs):
|
||||
return RaisesContext(expected_exception, message, match_expr)
|
||||
elif isinstance(args[0], str):
|
||||
warnings.warn(deprecated.RAISES_EXEC, stacklevel=2)
|
||||
code, = args
|
||||
(code,) = args
|
||||
assert isinstance(code, str)
|
||||
frame = sys._getframe(1)
|
||||
loc = frame.f_locals.copy()
|
||||
|
||||
@@ -95,7 +95,7 @@ def warns(expected_warning, *args, **kwargs):
|
||||
return WarningsChecker(expected_warning, match_expr=match_expr)
|
||||
elif isinstance(args[0], str):
|
||||
warnings.warn(WARNS_EXEC, stacklevel=2)
|
||||
code, = args
|
||||
(code,) = args
|
||||
assert isinstance(code, str)
|
||||
frame = sys._getframe(1)
|
||||
loc = frame.f_locals.copy()
|
||||
|
||||
@@ -152,7 +152,7 @@ def test_pytest_plugins_in_non_top_level_conftest_unsupported_pyargs(
|
||||
|
||||
|
||||
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_top_level_conftest(
|
||||
testdir
|
||||
testdir,
|
||||
):
|
||||
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
|
||||
|
||||
@@ -181,7 +181,7 @@ def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_top_level_conft
|
||||
|
||||
|
||||
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives(
|
||||
testdir
|
||||
testdir,
|
||||
):
|
||||
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
|
||||
|
||||
|
||||
@@ -464,7 +464,7 @@ class TestRequestBasic(object):
|
||||
assert repr(req).find(req.function.__name__) != -1
|
||||
|
||||
def test_request_attributes_method(self, testdir):
|
||||
item, = testdir.getitems(
|
||||
(item,) = testdir.getitems(
|
||||
"""
|
||||
import pytest
|
||||
class TestB(object):
|
||||
@@ -492,7 +492,7 @@ class TestRequestBasic(object):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
item1, = testdir.genitems([modcol])
|
||||
(item1,) = testdir.genitems([modcol])
|
||||
assert item1.name == "test_method"
|
||||
arg2fixturedefs = fixtures.FixtureRequest(item1)._arg2fixturedefs
|
||||
assert len(arg2fixturedefs) == 1
|
||||
@@ -756,7 +756,7 @@ class TestRequestBasic(object):
|
||||
|
||||
def test_request_getmodulepath(self, testdir):
|
||||
modcol = testdir.getmodulecol("def test_somefunc(): pass")
|
||||
item, = testdir.genitems([modcol])
|
||||
(item,) = testdir.genitems([modcol])
|
||||
req = fixtures.FixtureRequest(item)
|
||||
assert req.fspath == modcol.fspath
|
||||
|
||||
|
||||
@@ -494,7 +494,7 @@ class TestSession(object):
|
||||
p = testdir.makepyfile("def test_func(): pass")
|
||||
id = "::".join([p.basename, "test_func"])
|
||||
items, hookrec = testdir.inline_genitems(id)
|
||||
item, = items
|
||||
(item,) = items
|
||||
assert item.name == "test_func"
|
||||
newid = item.nodeid
|
||||
assert newid == id
|
||||
@@ -613,9 +613,9 @@ class TestSession(object):
|
||||
testdir.makepyfile("def test_func(): pass")
|
||||
items, hookrec = testdir.inline_genitems()
|
||||
assert len(items) == 1
|
||||
item, = items
|
||||
(item,) = items
|
||||
items2, hookrec = testdir.inline_genitems(item.nodeid)
|
||||
item2, = items2
|
||||
(item2,) = items2
|
||||
assert item2.name == item.name
|
||||
assert item2.fspath == item.fspath
|
||||
|
||||
@@ -630,7 +630,7 @@ class TestSession(object):
|
||||
arg = p.basename + "::TestClass::test_method"
|
||||
items, hookrec = testdir.inline_genitems(arg)
|
||||
assert len(items) == 1
|
||||
item, = items
|
||||
(item,) = items
|
||||
assert item.nodeid.endswith("TestClass::test_method")
|
||||
# ensure we are reporting the collection of the single test item (#2464)
|
||||
assert [x.name for x in self.get_reported_items(hookrec)] == ["test_method"]
|
||||
|
||||
@@ -4,7 +4,9 @@ from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from xml.dom import minidom
|
||||
|
||||
import py
|
||||
@@ -47,6 +49,16 @@ class DomNode(object):
|
||||
def _by_tag(self, tag):
|
||||
return self.__node.getElementsByTagName(tag)
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
return [type(self)(x) for x in self.__node.childNodes]
|
||||
|
||||
@property
|
||||
def get_unique_child(self):
|
||||
children = self.children
|
||||
assert len(children) == 1
|
||||
return children[0]
|
||||
|
||||
def find_nth_by_tag(self, tag, n):
|
||||
items = self._by_tag(tag)
|
||||
try:
|
||||
@@ -81,7 +93,7 @@ class DomNode(object):
|
||||
return self.__node.tagName
|
||||
|
||||
@property
|
||||
def next_siebling(self):
|
||||
def next_sibling(self):
|
||||
return type(self)(self.__node.nextSibling)
|
||||
|
||||
|
||||
@@ -135,6 +147,30 @@ class TestPython(object):
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
node.assert_attr(name="pytest", errors=1, failures=2, skipped=1, tests=5)
|
||||
|
||||
def test_hostname_in_xml(self, testdir):
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
result, dom = runandparse(testdir)
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
node.assert_attr(hostname=platform.node())
|
||||
|
||||
def test_timestamp_in_xml(self, testdir):
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
def test_pass():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
start_time = datetime.now()
|
||||
result, dom = runandparse(testdir)
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
timestamp = datetime.strptime(node["timestamp"], "%Y-%m-%dT%H:%M:%S.%f")
|
||||
assert start_time <= timestamp < datetime.now()
|
||||
|
||||
def test_timing_function(self, testdir):
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
@@ -390,11 +426,11 @@ class TestPython(object):
|
||||
fnode = tnode.find_first_by_tag("failure")
|
||||
fnode.assert_attr(message="ValueError: 42")
|
||||
assert "ValueError" in fnode.toxml()
|
||||
systemout = fnode.next_siebling
|
||||
systemout = fnode.next_sibling
|
||||
assert systemout.tag == "system-out"
|
||||
assert "hello-stdout" in systemout.toxml()
|
||||
assert "info msg" not in systemout.toxml()
|
||||
systemerr = systemout.next_siebling
|
||||
systemerr = systemout.next_sibling
|
||||
assert systemerr.tag == "system-err"
|
||||
assert "hello-stderr" in systemerr.toxml()
|
||||
assert "info msg" not in systemerr.toxml()
|
||||
@@ -1101,6 +1137,20 @@ def test_random_report_log_xdist(testdir, monkeypatch):
|
||||
assert failed == ["test_x[22]"]
|
||||
|
||||
|
||||
def test_root_testsuites_tag(testdir):
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
def test_x():
|
||||
pass
|
||||
"""
|
||||
)
|
||||
_, dom = runandparse(testdir)
|
||||
root = dom.get_unique_child
|
||||
assert root.tag == "testsuites"
|
||||
suite_node = root.get_unique_child
|
||||
assert suite_node.tag == "testsuite"
|
||||
|
||||
|
||||
def test_runs_twice(testdir):
|
||||
f = testdir.makepyfile(
|
||||
"""
|
||||
@@ -1359,3 +1409,39 @@ def test_logging_passing_tests_disabled_does_not_log_test_output(testdir):
|
||||
node = dom.find_first_by_tag("testcase")
|
||||
assert len(node.find_by_tag("system-err")) == 0
|
||||
assert len(node.find_by_tag("system-out")) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("junit_logging", ["no", "system-out", "system-err"])
|
||||
def test_logging_passing_tests_disabled_logs_output_for_failing_test_issue5430(
|
||||
testdir, junit_logging
|
||||
):
|
||||
testdir.makeini(
|
||||
"""
|
||||
[pytest]
|
||||
junit_log_passing_tests=False
|
||||
"""
|
||||
)
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
import pytest
|
||||
import logging
|
||||
import sys
|
||||
|
||||
def test_func():
|
||||
logging.warning('hello')
|
||||
assert 0
|
||||
"""
|
||||
)
|
||||
result, dom = runandparse(testdir, "-o", "junit_logging=%s" % junit_logging)
|
||||
assert result.ret == 1
|
||||
node = dom.find_first_by_tag("testcase")
|
||||
if junit_logging == "system-out":
|
||||
assert len(node.find_by_tag("system-err")) == 0
|
||||
assert len(node.find_by_tag("system-out")) == 1
|
||||
elif junit_logging == "system-err":
|
||||
assert len(node.find_by_tag("system-err")) == 1
|
||||
assert len(node.find_by_tag("system-out")) == 0
|
||||
else:
|
||||
assert junit_logging == "no"
|
||||
assert len(node.find_by_tag("system-err")) == 0
|
||||
assert len(node.find_by_tag("system-out")) == 0
|
||||
|
||||
@@ -1008,7 +1008,7 @@ def test_markers_from_parametrize(testdir):
|
||||
def test_pytest_param_id_requires_string():
|
||||
with pytest.raises(TypeError) as excinfo:
|
||||
pytest.param(id=True)
|
||||
msg, = excinfo.value.args
|
||||
(msg,) = excinfo.value.args
|
||||
if six.PY2:
|
||||
assert msg == "Expected id to be a string, got <type 'bool'>: True"
|
||||
else:
|
||||
@@ -1025,7 +1025,7 @@ def test_pytest_param_warning_on_unknown_kwargs():
|
||||
# typo, should be marks=
|
||||
pytest.param(1, 2, mark=pytest.mark.xfail())
|
||||
assert warninfo[0].filename == __file__
|
||||
msg, = warninfo[0].message.args
|
||||
(msg,) = warninfo[0].message.args
|
||||
assert msg == (
|
||||
"pytest.param() got unexpected keyword arguments: ['mark'].\n"
|
||||
"This will be an error in future versions."
|
||||
|
||||
@@ -225,7 +225,7 @@ class TestWarns(object):
|
||||
assert len(warninfo) == 3
|
||||
for w in warninfo:
|
||||
assert w.filename == __file__
|
||||
msg, = w.message.args
|
||||
(msg,) = w.message.args
|
||||
assert msg.startswith("warns(..., 'code(as_a_string)') is deprecated")
|
||||
|
||||
def test_function(self):
|
||||
|
||||
@@ -136,7 +136,7 @@ class TestEvaluator(object):
|
||||
)
|
||||
|
||||
def test_skipif_class(self, testdir):
|
||||
item, = testdir.getitems(
|
||||
(item,) = testdir.getitems(
|
||||
"""
|
||||
import pytest
|
||||
class TestClass(object):
|
||||
|
||||
@@ -273,7 +273,7 @@ class TestNumberedDir(object):
|
||||
registry = []
|
||||
register_cleanup_lock_removal(lock, register=registry.append)
|
||||
|
||||
cleanup_func, = registry
|
||||
(cleanup_func,) = registry
|
||||
|
||||
assert lock.is_file()
|
||||
|
||||
@@ -398,9 +398,14 @@ class TestRmRf:
|
||||
on_rm_rf_error(os.unlink, str(fn), exc_info, start_path=tmp_path)
|
||||
assert fn.is_file()
|
||||
|
||||
# we ignore FileNotFoundError
|
||||
file_not_found = OSError()
|
||||
file_not_found.errno = errno.ENOENT
|
||||
exc_info = (None, file_not_found, None)
|
||||
assert not on_rm_rf_error(None, str(fn), exc_info, start_path=tmp_path)
|
||||
|
||||
permission_error = OSError()
|
||||
permission_error.errno = errno.EACCES
|
||||
|
||||
# unknown function
|
||||
with pytest.warns(pytest.PytestWarning):
|
||||
exc_info = (None, permission_error, None)
|
||||
|
||||
@@ -388,7 +388,7 @@ def test_testcase_custom_exception_info(testdir, type):
|
||||
|
||||
|
||||
def test_testcase_totally_incompatible_exception_info(testdir):
|
||||
item, = testdir.getitems(
|
||||
(item,) = testdir.getitems(
|
||||
"""
|
||||
from unittest import TestCase
|
||||
class MyTestCase(TestCase):
|
||||
|
||||
Reference in New Issue
Block a user