Merge pull request #4808 from nicoddemus/merge-master-into-features
Merge master into features
This commit is contained in:
commit
b9561e29ff
20
.travis.yml
20
.travis.yml
|
@ -1,4 +1,3 @@
|
||||||
sudo: false
|
|
||||||
language: python
|
language: python
|
||||||
dist: xenial
|
dist: xenial
|
||||||
stages:
|
stages:
|
||||||
|
@ -26,7 +25,7 @@ env:
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- python: '3.8-dev'
|
- python: '3.8-dev'
|
||||||
env: TOXENV=py38
|
env: TOXENV=py38-xdist
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
|
@ -34,14 +33,12 @@ jobs:
|
||||||
- env: TOXENV=pypy PYTEST_NO_COVERAGE=1
|
- env: TOXENV=pypy PYTEST_NO_COVERAGE=1
|
||||||
python: 'pypy-5.4'
|
python: 'pypy-5.4'
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- env: TOXENV=py34
|
- env: TOXENV=py34-xdist
|
||||||
python: '3.4'
|
python: '3.4'
|
||||||
- env: TOXENV=py35
|
- env: TOXENV=py35-xdist
|
||||||
python: '3.5'
|
python: '3.5'
|
||||||
- env: TOXENV=py36
|
- env: TOXENV=py36-xdist
|
||||||
python: '3.6'
|
python: '3.6'
|
||||||
- env: TOXENV=py38
|
|
||||||
python: '3.8-dev'
|
|
||||||
- env: TOXENV=py37
|
- env: TOXENV=py37
|
||||||
- &test-macos
|
- &test-macos
|
||||||
language: generic
|
language: generic
|
||||||
|
@ -50,15 +47,20 @@ jobs:
|
||||||
sudo: required
|
sudo: required
|
||||||
install:
|
install:
|
||||||
- python -m pip install --pre tox
|
- python -m pip install --pre tox
|
||||||
env: TOXENV=py27
|
env: TOXENV=py27-xdist
|
||||||
- <<: *test-macos
|
- <<: *test-macos
|
||||||
env: TOXENV=py37
|
env: TOXENV=py37-xdist
|
||||||
before_install:
|
before_install:
|
||||||
- brew update
|
- brew update
|
||||||
- brew upgrade python
|
- brew upgrade python
|
||||||
- brew unlink python
|
- brew unlink python
|
||||||
- brew link python
|
- brew link python
|
||||||
|
|
||||||
|
# Jobs only run via Travis cron jobs (currently daily).
|
||||||
|
- env: TOXENV=py38-xdist
|
||||||
|
python: '3.8-dev'
|
||||||
|
if: type = cron
|
||||||
|
|
||||||
- stage: baseline
|
- stage: baseline
|
||||||
env: TOXENV=py27-pexpect,py27-trial,py27-numpy
|
env: TOXENV=py27-pexpect,py27-trial,py27-numpy
|
||||||
- env: TOXENV=py37-xdist
|
- env: TOXENV=py37-xdist
|
||||||
|
|
|
@ -18,6 +18,48 @@ with advance notice in the **Deprecations** section of releases.
|
||||||
|
|
||||||
.. towncrier release notes start
|
.. towncrier release notes start
|
||||||
|
|
||||||
|
pytest 4.3.0 (2019-02-16)
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Deprecations
|
||||||
|
------------
|
||||||
|
|
||||||
|
- `#4724 <https://github.com/pytest-dev/pytest/issues/4724>`_: ``pytest.warns()`` now emits a warning when it receives unknown keyword arguments.
|
||||||
|
|
||||||
|
This will be changed into an error in the future.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- `#2753 <https://github.com/pytest-dev/pytest/issues/2753>`_: Usage errors from argparse are mapped to pytest's ``UsageError``.
|
||||||
|
|
||||||
|
|
||||||
|
- `#3711 <https://github.com/pytest-dev/pytest/issues/3711>`_: Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards.
|
||||||
|
Add the ``collect_ignore_glob`` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards.
|
||||||
|
|
||||||
|
|
||||||
|
- `#4698 <https://github.com/pytest-dev/pytest/issues/4698>`_: The warning about Python 2.7 and 3.4 not being supported in pytest 5.0 has been removed.
|
||||||
|
|
||||||
|
In the end it was considered to be more
|
||||||
|
of a nuisance than actual utility and users of those Python versions shouldn't have problems as ``pip`` will not
|
||||||
|
install pytest 5.0 on those interpreters.
|
||||||
|
|
||||||
|
|
||||||
|
- `#4707 <https://github.com/pytest-dev/pytest/issues/4707>`_: With the help of new ``set_log_path()`` method there is a way to set ``log_file`` paths from hooks.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- `#4651 <https://github.com/pytest-dev/pytest/issues/4651>`_: ``--help`` and ``--version`` are handled with ``UsageError``.
|
||||||
|
|
||||||
|
|
||||||
|
- `#4782 <https://github.com/pytest-dev/pytest/issues/4782>`_: Fix ``AssertionError`` with collection of broken symlinks with packages.
|
||||||
|
|
||||||
|
|
||||||
pytest 4.2.1 (2019-02-12)
|
pytest 4.2.1 (2019-02-12)
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Usage errors from argparse are mapped to pytest's ``UsageError``.
|
|
|
@ -1,2 +0,0 @@
|
||||||
Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards.
|
|
||||||
Add the ``collect_ignore_glob`` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards.
|
|
|
@ -1 +0,0 @@
|
||||||
``--help`` and ``--version`` are handled with ``UsageError``.
|
|
|
@ -1,5 +0,0 @@
|
||||||
The warning about Python 2.7 and 3.4 not being supported in pytest 5.0 has been removed.
|
|
||||||
|
|
||||||
In the end it was considered to be more
|
|
||||||
of a nuisance than actual utility and users of those Python versions shouldn't have problems as ``pip`` will not
|
|
||||||
install pytest 5.0 on those interpreters.
|
|
|
@ -1 +0,0 @@
|
||||||
With the help of new ``set_log_path()`` method there is a way to set ``log_file`` paths from hooks.
|
|
|
@ -1,3 +0,0 @@
|
||||||
``pytest.warns()`` now emits a warning when it receives unknown keyword arguments.
|
|
||||||
|
|
||||||
This will be changed into an error in the future.
|
|
|
@ -6,6 +6,7 @@ Release announcements
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
|
||||||
|
release-4.3.0
|
||||||
release-4.2.1
|
release-4.2.1
|
||||||
release-4.2.0
|
release-4.2.0
|
||||||
release-4.1.1
|
release-4.1.1
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
pytest-4.3.0
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
The pytest team is proud to announce the 4.3.0 release!
|
||||||
|
|
||||||
|
pytest is a mature Python testing tool with more than a 2000 tests
|
||||||
|
against itself, passing on many different interpreters and platforms.
|
||||||
|
|
||||||
|
This release contains a number of bugs fixes and improvements, so users are encouraged
|
||||||
|
to take a look at the CHANGELOG:
|
||||||
|
|
||||||
|
https://docs.pytest.org/en/latest/changelog.html
|
||||||
|
|
||||||
|
For complete documentation, please visit:
|
||||||
|
|
||||||
|
https://docs.pytest.org/en/latest/
|
||||||
|
|
||||||
|
As usual, you can upgrade from pypi via:
|
||||||
|
|
||||||
|
pip install -U pytest
|
||||||
|
|
||||||
|
Thanks to all who contributed to this release, among them:
|
||||||
|
|
||||||
|
* Andras Mitzki
|
||||||
|
* Anthony Sottile
|
||||||
|
* Bruno Oliveira
|
||||||
|
* Christian Fetzer
|
||||||
|
* Daniel Hahler
|
||||||
|
* Grygorii Iermolenko
|
||||||
|
* R. Alex Matevish
|
||||||
|
* Ronny Pfannschmidt
|
||||||
|
* cclauss
|
||||||
|
|
||||||
|
|
||||||
|
Happy testing,
|
||||||
|
The Pytest Development Team
|
|
@ -88,23 +88,30 @@ and if you need to have access to the actual exception info you may use::
|
||||||
the actual exception raised. The main attributes of interest are
|
the actual exception raised. The main attributes of interest are
|
||||||
``.type``, ``.value`` and ``.traceback``.
|
``.type``, ``.value`` and ``.traceback``.
|
||||||
|
|
||||||
.. versionchanged:: 3.0
|
You can pass a ``match`` keyword parameter to the context-manager to test
|
||||||
|
that a regular expression matches on the string representation of an exception
|
||||||
|
(similar to the ``TestCase.assertRaisesRegexp`` method from ``unittest``)::
|
||||||
|
|
||||||
In the context manager form you may use the keyword argument
|
import pytest
|
||||||
``message`` to specify a custom failure message::
|
|
||||||
|
|
||||||
>>> with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"):
|
def myfunc():
|
||||||
... pass
|
raise ValueError("Exception 123 raised")
|
||||||
... Failed: Expecting ZeroDivisionError
|
|
||||||
|
|
||||||
If you want to write test code that works on Python 2.4 as well,
|
def test_match():
|
||||||
you may also use two other ways to test for an expected exception::
|
with pytest.raises(ValueError, match=r'.* 123 .*'):
|
||||||
|
myfunc()
|
||||||
|
|
||||||
|
The regexp parameter of the ``match`` method is matched with the ``re.search``
|
||||||
|
function, so in the above example ``match='123'`` would have worked as
|
||||||
|
well.
|
||||||
|
|
||||||
|
There's an alternate form of the ``pytest.raises`` function where you pass
|
||||||
|
a function that will be executed with the given ``*args`` and ``**kwargs`` and
|
||||||
|
assert that the given exception is raised::
|
||||||
|
|
||||||
pytest.raises(ExpectedException, func, *args, **kwargs)
|
pytest.raises(ExpectedException, func, *args, **kwargs)
|
||||||
|
|
||||||
which will execute the specified function with args and kwargs and
|
The reporter will provide you with helpful output in case of failures such as *no
|
||||||
assert that the given ``ExpectedException`` is raised. The reporter will
|
|
||||||
provide you with helpful output in case of failures such as *no
|
|
||||||
exception* or *wrong exception*.
|
exception* or *wrong exception*.
|
||||||
|
|
||||||
Note that it is also possible to specify a "raises" argument to
|
Note that it is also possible to specify a "raises" argument to
|
||||||
|
@ -121,23 +128,6 @@ exceptions your own code is deliberately raising, whereas using
|
||||||
like documenting unfixed bugs (where the test describes what "should" happen)
|
like documenting unfixed bugs (where the test describes what "should" happen)
|
||||||
or bugs in dependencies.
|
or bugs in dependencies.
|
||||||
|
|
||||||
Also, the context manager form accepts a ``match`` keyword parameter to test
|
|
||||||
that a regular expression matches on the string representation of an exception
|
|
||||||
(like the ``TestCase.assertRaisesRegexp`` method from ``unittest``)::
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def myfunc():
|
|
||||||
raise ValueError("Exception 123 raised")
|
|
||||||
|
|
||||||
def test_match():
|
|
||||||
with pytest.raises(ValueError, match=r'.* 123 .*'):
|
|
||||||
myfunc()
|
|
||||||
|
|
||||||
The regexp parameter of the ``match`` method is matched with the ``re.search``
|
|
||||||
function. So in the above example ``match='123'`` would have worked as
|
|
||||||
well.
|
|
||||||
|
|
||||||
|
|
||||||
.. _`assertwarns`:
|
.. _`assertwarns`:
|
||||||
|
|
||||||
|
|
|
@ -436,10 +436,8 @@ Running it results in some skips if we don't have all the python interpreters in
|
||||||
.. code-block:: pytest
|
.. code-block:: pytest
|
||||||
|
|
||||||
. $ pytest -rs -q multipython.py
|
. $ pytest -rs -q multipython.py
|
||||||
...sss...sssssssss...sss... [100%]
|
........................... [100%]
|
||||||
========================= short test summary info ==========================
|
27 passed in 0.12 seconds
|
||||||
SKIPPED [15] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.4' not found
|
|
||||||
12 passed, 15 skipped in 0.12 seconds
|
|
||||||
|
|
||||||
Indirect parametrization of optional implementations/imports
|
Indirect parametrization of optional implementations/imports
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
|
|
|
@ -25,6 +25,9 @@ Talks and blog postings
|
||||||
|
|
||||||
- pytest: recommendations, basic packages for testing in Python and Django, Andreu Vallbona, PyconES 2017 (`slides in english <http://talks.apsl.io/testing-pycones-2017/>`_, `video in spanish <https://www.youtube.com/watch?v=K20GeR-lXDk>`_)
|
- pytest: recommendations, basic packages for testing in Python and Django, Andreu Vallbona, PyconES 2017 (`slides in english <http://talks.apsl.io/testing-pycones-2017/>`_, `video in spanish <https://www.youtube.com/watch?v=K20GeR-lXDk>`_)
|
||||||
|
|
||||||
|
- `pytest advanced, Andrew Svetlov (Russian, PyCon Russia, 2016)
|
||||||
|
<https://www.youtube.com/watch?v=7KgihdKTWY4>`_.
|
||||||
|
|
||||||
- `Pythonic testing, Igor Starikov (Russian, PyNsk, November 2016)
|
- `Pythonic testing, Igor Starikov (Russian, PyNsk, November 2016)
|
||||||
<https://www.youtube.com/watch?v=_92nfdd5nK8>`_.
|
<https://www.youtube.com/watch?v=_92nfdd5nK8>`_.
|
||||||
|
|
||||||
|
|
|
@ -618,7 +618,12 @@ class Session(nodes.FSCollector):
|
||||||
yield y
|
yield y
|
||||||
|
|
||||||
def _collectfile(self, path, handle_dupes=True):
|
def _collectfile(self, path, handle_dupes=True):
|
||||||
assert path.isfile()
|
assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % (
|
||||||
|
path,
|
||||||
|
path.isdir(),
|
||||||
|
path.exists(),
|
||||||
|
path.islink(),
|
||||||
|
)
|
||||||
ihook = self.gethookproxy(path)
|
ihook = self.gethookproxy(path)
|
||||||
if not self.isinitpath(path):
|
if not self.isinitpath(path):
|
||||||
if ihook.pytest_ignore_collect(path=path, config=self.config):
|
if ihook.pytest_ignore_collect(path=path, config=self.config):
|
||||||
|
|
|
@ -113,11 +113,12 @@ class Node(object):
|
||||||
|
|
||||||
:raise ValueError: if ``warning`` instance is not a subclass of PytestWarning.
|
:raise ValueError: if ``warning`` instance is not a subclass of PytestWarning.
|
||||||
|
|
||||||
Example usage::
|
Example usage:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
node.warn(PytestWarning("some message"))
|
node.warn(PytestWarning("some message"))
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from _pytest.warning_types import PytestWarning
|
from _pytest.warning_types import PytestWarning
|
||||||
|
|
||||||
|
|
|
@ -599,7 +599,12 @@ class Package(Module):
|
||||||
return proxy
|
return proxy
|
||||||
|
|
||||||
def _collectfile(self, path, handle_dupes=True):
|
def _collectfile(self, path, handle_dupes=True):
|
||||||
assert path.isfile()
|
assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % (
|
||||||
|
path,
|
||||||
|
path.isdir(),
|
||||||
|
path.exists(),
|
||||||
|
path.islink(),
|
||||||
|
)
|
||||||
ihook = self.gethookproxy(path)
|
ihook = self.gethookproxy(path)
|
||||||
if not self.isinitpath(path):
|
if not self.isinitpath(path):
|
||||||
if ihook.pytest_ignore_collect(path=path, config=self.config):
|
if ihook.pytest_ignore_collect(path=path, config=self.config):
|
||||||
|
@ -632,7 +637,8 @@ class Package(Module):
|
||||||
pkg_prefixes = set()
|
pkg_prefixes = set()
|
||||||
for path in this_path.visit(rec=self._recurse, bf=True, sort=True):
|
for path in this_path.visit(rec=self._recurse, bf=True, sort=True):
|
||||||
# We will visit our own __init__.py file, in which case we skip it.
|
# We will visit our own __init__.py file, in which case we skip it.
|
||||||
if path.isfile():
|
is_file = path.isfile()
|
||||||
|
if is_file:
|
||||||
if path.basename == "__init__.py" and path.dirpath() == this_path:
|
if path.basename == "__init__.py" and path.dirpath() == this_path:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -643,12 +649,14 @@ class Package(Module):
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if path.isdir():
|
if is_file:
|
||||||
if path.join("__init__.py").check(file=1):
|
|
||||||
pkg_prefixes.add(path)
|
|
||||||
else:
|
|
||||||
for x in self._collectfile(path):
|
for x in self._collectfile(path):
|
||||||
yield x
|
yield x
|
||||||
|
elif not path.isdir():
|
||||||
|
# Broken symlink or invalid/missing file.
|
||||||
|
continue
|
||||||
|
elif path.join("__init__.py").check(file=1):
|
||||||
|
pkg_prefixes.add(path)
|
||||||
|
|
||||||
|
|
||||||
def _get_xunit_setup_teardown(holder, attr_name, param_obj=None):
|
def _get_xunit_setup_teardown(holder, attr_name, param_obj=None):
|
||||||
|
|
|
@ -280,7 +280,9 @@ class TerminalReporter(object):
|
||||||
|
|
||||||
def write_fspath_result(self, nodeid, res, **markup):
|
def write_fspath_result(self, nodeid, res, **markup):
|
||||||
fspath = self.config.rootdir.join(nodeid.split("::")[0])
|
fspath = self.config.rootdir.join(nodeid.split("::")[0])
|
||||||
if fspath != self.currentfspath:
|
# NOTE: explicitly check for None to work around py bug, and for less
|
||||||
|
# overhead in general (https://github.com/pytest-dev/py/pull/207).
|
||||||
|
if self.currentfspath is None or fspath != self.currentfspath:
|
||||||
if self.currentfspath is not None and self._show_progress_info:
|
if self.currentfspath is not None and self._show_progress_info:
|
||||||
self._write_progress_information_filling_space()
|
self._write_progress_information_filling_space()
|
||||||
self.currentfspath = fspath
|
self.currentfspath = fspath
|
||||||
|
|
|
@ -31,7 +31,7 @@ class TempPathFactory(object):
|
||||||
# using os.path.abspath() to get absolute path instead of resolve() as it
|
# using os.path.abspath() to get absolute path instead of resolve() as it
|
||||||
# does not work the same in all platforms (see #4427)
|
# does not work the same in all platforms (see #4427)
|
||||||
# Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012)
|
# Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012)
|
||||||
convert=attr.converters.optional(
|
converter=attr.converters.optional(
|
||||||
lambda p: Path(os.path.abspath(six.text_type(p)))
|
lambda p: Path(os.path.abspath(six.text_type(p)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -560,7 +560,6 @@ def test_oneline_and_comment():
|
||||||
assert str(source) == "raise ValueError"
|
assert str(source) == "raise ValueError"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(hasattr(sys, "pypy_version_info"), reason="does not work on pypy")
|
|
||||||
def test_comments():
|
def test_comments():
|
||||||
source = '''def test():
|
source = '''def test():
|
||||||
"comment 1"
|
"comment 1"
|
||||||
|
@ -576,9 +575,15 @@ comment 4
|
||||||
'''
|
'''
|
||||||
for line in range(2, 6):
|
for line in range(2, 6):
|
||||||
assert str(getstatement(line, source)) == " x = 1"
|
assert str(getstatement(line, source)) == " x = 1"
|
||||||
for line in range(6, 10):
|
if sys.version_info >= (3, 8) or hasattr(sys, "pypy_version_info"):
|
||||||
|
tqs_start = 8
|
||||||
|
else:
|
||||||
|
tqs_start = 10
|
||||||
|
assert str(getstatement(10, source)) == '"""'
|
||||||
|
for line in range(6, tqs_start):
|
||||||
assert str(getstatement(line, source)) == " assert False"
|
assert str(getstatement(line, source)) == " assert False"
|
||||||
assert str(getstatement(10, source)) == '"""'
|
for line in range(tqs_start, 10):
|
||||||
|
assert str(getstatement(line, source)) == '"""\ncomment 4\n"""'
|
||||||
|
|
||||||
|
|
||||||
def test_comment_in_statement():
|
def test_comment_in_statement():
|
||||||
|
|
|
@ -1308,10 +1308,17 @@ class TestEarlyRewriteBailout(object):
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
sys.platform.startswith("win32"), reason="cannot remove cwd on Windows"
|
sys.platform.startswith("win32"), reason="cannot remove cwd on Windows"
|
||||||
)
|
)
|
||||||
def test_cwd_changed(self, testdir):
|
def test_cwd_changed(self, testdir, monkeypatch):
|
||||||
|
# Setup conditions for py's fspath trying to import pathlib on py34
|
||||||
|
# always (previously triggered via xdist only).
|
||||||
|
# Ref: https://github.com/pytest-dev/py/pull/207
|
||||||
|
monkeypatch.setattr(sys, "path", [""] + sys.path)
|
||||||
|
if "pathlib" in sys.modules:
|
||||||
|
del sys.modules["pathlib"]
|
||||||
|
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
**{
|
**{
|
||||||
"test_bar.py": """
|
"test_setup_nonexisting_cwd.py": """
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -1320,7 +1327,7 @@ class TestEarlyRewriteBailout(object):
|
||||||
os.chdir(d)
|
os.chdir(d)
|
||||||
shutil.rmtree(d)
|
shutil.rmtree(d)
|
||||||
""",
|
""",
|
||||||
"test_foo.py": """
|
"test_test.py": """
|
||||||
def test():
|
def test():
|
||||||
pass
|
pass
|
||||||
""",
|
""",
|
||||||
|
|
|
@ -1206,3 +1206,30 @@ def test_collect_pkg_init_and_file_in_args(testdir):
|
||||||
"*2 passed in*",
|
"*2 passed in*",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
not hasattr(py.path.local, "mksymlinkto"),
|
||||||
|
reason="symlink not available on this platform",
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("use_pkg", (True, False))
|
||||||
|
def test_collect_sub_with_symlinks(use_pkg, testdir):
|
||||||
|
sub = testdir.mkdir("sub")
|
||||||
|
if use_pkg:
|
||||||
|
sub.ensure("__init__.py")
|
||||||
|
sub.ensure("test_file.py").write("def test_file(): pass")
|
||||||
|
|
||||||
|
# Create a broken symlink.
|
||||||
|
sub.join("test_broken.py").mksymlinkto("test_doesnotexist.py")
|
||||||
|
|
||||||
|
# Symlink that gets collected.
|
||||||
|
sub.join("test_symlink.py").mksymlinkto("test_file.py")
|
||||||
|
|
||||||
|
result = testdir.runpytest("-v", str(sub))
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
[
|
||||||
|
"sub/test_file.py::test_file PASSED*",
|
||||||
|
"sub/test_symlink.py::test_file PASSED*",
|
||||||
|
"*2 passed in*",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
|
@ -910,7 +910,6 @@ def test_reportchars_all_error(testdir):
|
||||||
result.stdout.fnmatch_lines(["ERROR*test_foo*"])
|
result.stdout.fnmatch_lines(["ERROR*test_foo*"])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail("hasattr(sys, 'pypy_version_info')")
|
|
||||||
def test_errors_in_xfail_skip_expressions(testdir):
|
def test_errors_in_xfail_skip_expressions(testdir):
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
"""
|
"""
|
||||||
|
@ -931,6 +930,10 @@ def test_errors_in_xfail_skip_expressions(testdir):
|
||||||
if sys.platform.startswith("java"):
|
if sys.platform.startswith("java"):
|
||||||
# XXX report this to java
|
# XXX report this to java
|
||||||
markline = "*" + markline[8:]
|
markline = "*" + markline[8:]
|
||||||
|
elif hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (6,):
|
||||||
|
markline = markline[5:]
|
||||||
|
elif sys.version_info >= (3, 8) or hasattr(sys, "pypy_version_info"):
|
||||||
|
markline = markline[4:]
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
[
|
[
|
||||||
"*ERROR*test_nameerror*",
|
"*ERROR*test_nameerror*",
|
||||||
|
|
Loading…
Reference in New Issue