Compare commits

..

29 Commits
5.2.2 ... 5.2.3

Author SHA1 Message Date
Bruno Oliveira
dd9a27cf54 Adjust CHANGELOG 2019-11-14 17:51:38 -03:00
Bruno Oliveira
5e8c47faad Preparing release version 5.2.3 2019-11-14 11:12:06 -03:00
Bruno Oliveira
92d6a0500b Show a better message when 'request' is used in parametrize (#6184)
Show a better message when 'request' is used in parametrize
2019-11-13 20:36:23 -03:00
Bruno Oliveira
6f2c0fd2e8 Show a better message when 'request' is used in parametrize
Fix #6183
2019-11-13 19:57:10 -03:00
Zac Hatfield-Dodds
55a58bcd3d Merge pull request #6173 from brettcannon/patch-1
Delineate syntactically that the 'match' argument to 'raises' is keyword-only
2019-11-13 08:17:25 +11:00
Brett Cannon
0b40749c98 Delineate syntactically that the 'match' argument to 'raises' is keyword-only 2019-11-12 12:32:05 -08:00
Bruno Oliveira
adccb63de0 setup.cfg: fix check-manifest ignore [ci skip] (#6156)
setup.cfg: fix check-manifest ignore  [ci skip]
2019-11-12 11:45:31 -03:00
Daniel Hahler
41604eeb3e setup.cfg: fix check-manifest ignore [ci skip] 2019-11-08 22:39:39 +01:00
Bruno Oliveira
85288b5321 fix bug with nonskipped first test in package (#5831)
fix bug with nonskipped first test in package
2019-11-06 16:06:46 -03:00
Daniel Hahler
5f9db8a017 Merge pull request #6138 from blueyed/ci-py38
ci: Travis: remove py38 from allowed failures; do not use "-dev"
2019-11-06 14:19:14 +01:00
Daniel Hahler
957adbbbc7 ci: Travis: remove py38 from allowed failures; do not use "-dev" 2019-11-06 13:09:11 +01:00
Florian Bruhin
990d75b7e6 Merge pull request #6134 from zmhassan/small_bug1
Removing variable being reassigned
2019-11-05 10:17:04 +01:00
Zak Hassan
f9e3a5395c Removing variable being reassigned 2019-11-04 21:11:54 -05:00
Bruno Oliveira
0760406480 update chanelog link to moved pip docs page (#6127)
update chanelog link to moved pip docs page
2019-11-04 13:18:09 -03:00
David Szotten
14580c7e31 update chanelog link to moved pip docs page 2019-11-04 10:05:05 +00:00
Florian Bruhin
35800a2f73 Merge pull request #6112 from gaucheph/fix-small-typo
typos
2019-11-01 11:18:06 +01:00
Patrick Harmon
abc890079f typos 2019-10-31 23:19:35 -05:00
Daniel Hahler
dc5a4fbe23 Merge pull request #6099 from davidszotten/trace_parametrize
Fix --trace for parametrized tests
2019-11-01 05:06:26 +01:00
David Szotten
285524c6cd Fix --trace for parametrized tests
Without this, the second time it tries to stop in a parametrized
function it raises instead:

`ValueError: --trace can't be used with a fixture named func!`

Implementation idea, test (and changelog tweaks) thanks to blueyed

Co-Authored-By: Ronny Pfannschmidt <opensource@ronnypfannschmidt.de>
Co-Authored-By: Daniel Hahler <git@thequod.de>
2019-10-31 21:41:33 +00:00
Bruno Oliveira
cefe6bfec3 Replace a few outdated references to py.test with pytest (#6063)
Replace a few outdated references to py.test with pytest
2019-10-26 12:59:22 -03:00
Bruno Oliveira
ac633b8969 Replace py.io.TextIO with io.StringIO (#6064)
Replace py.io.TextIO with io.StringIO
2019-10-26 12:58:52 -03:00
Ran Benita
0b8c35516f Replace py.io.TextIO with io.StringIO
In Python3, py.io.TextIO is just an alias to io.StringIO. Remove the
indirection.
2019-10-26 16:33:57 +03:00
Ran Benita
96de232791 Replace a few outdated references to py.test with pytest 2019-10-26 16:28:17 +03:00
Bruno Oliveira
2fc1f7b8dc Put the 4.6 changelogs together (#5969)
Put the 4.6 changelogs together
2019-10-24 21:21:59 -03:00
Bruno Oliveira
dae238c9b1 Release version 5.2.2 (#6055)
Release version 5.2.2
2019-10-24 21:09:15 -03:00
Daniil Galiev
5cefcb2052 refactor disabling markers 2019-10-21 00:11:24 +02:00
Daniil Galiev
b94eb4cb7b disable _ALLOW_MARKERS in module __init__.py 2019-10-21 00:11:24 +02:00
Daniil Galiev
9275012ef7 fix bug with nonskipped first test in package 2019-10-21 00:11:24 +02:00
Anthony Sottile
810db2726d Put the 4.6 changelogs together 2019-10-15 18:57:59 -07:00
35 changed files with 245 additions and 103 deletions

View File

@@ -60,7 +60,7 @@ jobs:
- env: TOXENV=py37-freeze
- env: TOXENV=py38-xdist
python: '3.8-dev'
python: '3.8'
- stage: baseline
env: TOXENV=py36-xdist
@@ -94,11 +94,6 @@ jobs:
tags: true
repo: pytest-dev/pytest
matrix:
allow_failures:
- python: '3.8-dev'
env: TOXENV=py38-xdist
before_script:
- |
# Do not (re-)upload coverage with cron runs.

View File

@@ -70,6 +70,7 @@ Daniel Hahler
Daniel Nuri
Daniel Wandschneider
Danielle Jenkins
Daniil Galiev
Dave Hunt
David Díaz-Barquero
David Mohr

View File

@@ -13,11 +13,27 @@ with advance notice in the **Deprecations** section of releases.
file is managed by towncrier. You *may* edit previous change logs to
fix problems like typo corrections or such.
To add a new change log entry, please see
https://pip.pypa.io/en/latest/development/#adding-a-news-entry
https://pip.pypa.io/en/latest/development/contributing/#news-entries
we named the news folder changelog
.. towncrier release notes start
pytest 5.2.3 (2019-11-14)
=========================
Bug Fixes
---------
- `#5830 <https://github.com/pytest-dev/pytest/issues/5830>`_: The first test in a package (``__init__.py``) marked with ``@pytest.mark.skip`` is now correctly skipped.
- `#6099 <https://github.com/pytest-dev/pytest/issues/6099>`_: Fix ``--trace`` when used with parametrized functions.
- `#6183 <https://github.com/pytest-dev/pytest/issues/6183>`_: Using ``request`` as a parameter name in ``@pytest.mark.parametrize`` now produces a more
user-friendly error.
pytest 5.2.2 (2019-10-24)
=========================
@@ -47,33 +63,6 @@ Bug Fixes
- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
pytest 4.6.6 (2019-10-11)
=========================
Bug Fixes
---------
- `#5523 <https://github.com/pytest-dev/pytest/issues/5523>`_: Fixed using multiple short options together in the command-line (for example ``-vs``) in Python 3.8+.
- `#5537 <https://github.com/pytest-dev/pytest/issues/5537>`_: Replace ``importlib_metadata`` backport with ``importlib.metadata`` from the
standard library on Python 3.8+.
- `#5806 <https://github.com/pytest-dev/pytest/issues/5806>`_: Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text".
- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
Trivial/Internal Changes
------------------------
- `#5801 <https://github.com/pytest-dev/pytest/issues/5801>`_: Fixes python version checks (detected by ``flake8-2020``) in case python4 becomes a thing.
pytest 5.2.0 (2019-09-28)
=========================
@@ -544,6 +533,32 @@ Improved Documentation
- `#5416 <https://github.com/pytest-dev/pytest/issues/5416>`_: Fix PytestUnknownMarkWarning in run/skip example.
pytest 4.6.6 (2019-10-11)
=========================
Bug Fixes
---------
- `#5523 <https://github.com/pytest-dev/pytest/issues/5523>`_: Fixed using multiple short options together in the command-line (for example ``-vs``) in Python 3.8+.
- `#5537 <https://github.com/pytest-dev/pytest/issues/5537>`_: Replace ``importlib_metadata`` backport with ``importlib.metadata`` from the
standard library on Python 3.8+.
- `#5806 <https://github.com/pytest-dev/pytest/issues/5806>`_: Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text".
- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
Trivial/Internal Changes
------------------------
- `#5801 <https://github.com/pytest-dev/pytest/issues/5801>`_: Fixes python version checks (detected by ``flake8-2020``) in case python4 becomes a thing.
pytest 4.6.5 (2019-08-05)
=========================

View File

@@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2
release-5.2.3
release-5.2.2
release-5.2.1
release-5.2.0

View File

@@ -0,0 +1,28 @@
pytest-5.2.3
=======================================
pytest 5.2.3 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
* Brett Cannon
* Bruno Oliveira
* Daniel Hahler
* Daniil Galiev
* David Szotten
* Florian Bruhin
* Patrick Harmon
* Ran Benita
* Zac Hatfield-Dodds
* Zak Hassan
Happy testing,
The pytest Development Team

View File

@@ -475,10 +475,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%]
ssssssssssss...ssssssssssss [100%]
========================= short test summary info ==========================
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.5' not found
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.6' not found
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.7' not found
3 passed, 24 skipped in 0.12s
Indirect parametrization of optional implementations/imports

View File

@@ -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}".format(items))
> a, b = items.pop()
E TypeError: cannot unpack non-iterable int object
E TypeError: 'int' object is not iterable
failure_demo.py:181: TypeError
--------------------------- Captured stdout call ---------------------------
@@ -516,7 +516,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 ______________________

View File

@@ -28,7 +28,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.7/site-packages/pytest.py
This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py
.. _`simpletest`:

View File

@@ -59,7 +59,7 @@ pytest.raises
**Tutorial**: :ref:`assertraises`.
.. autofunction:: pytest.raises(expected_exception: Exception, [match])
.. autofunction:: pytest.raises(expected_exception: Exception [, *, match])
:with: excinfo
pytest.deprecated_call

View File

@@ -57,7 +57,7 @@ upload-dir = doc/en/build/html
[check-manifest]
ignore =
_pytest/_version.py
src/_pytest/_version.py
[devpi:upload]
formats = sdist.tgz,bdist_wheel

View File

@@ -4,6 +4,7 @@ import sys
import traceback
from inspect import CO_VARARGS
from inspect import CO_VARKEYWORDS
from io import StringIO
from traceback import format_exception_only
from types import CodeType
from types import TracebackType
@@ -136,7 +137,7 @@ class Frame:
def exec_(self, code, **vars):
""" exec 'code' in the frame
'vars' are optiona; additional local variables
'vars' are optional; additional local variables
"""
f_locals = self.f_locals.copy()
f_locals.update(vars)
@@ -206,7 +207,7 @@ class TracebackEntry:
@property
def locals(self):
""" locals of underlaying frame """
""" locals of underlying frame """
return self.frame.f_locals
def getfirstlinesource(self):
@@ -273,7 +274,7 @@ class TracebackEntry:
@property
def name(self):
""" co_name of underlaying code """
""" co_name of underlying code """
return self.frame.code.raw.co_name
@@ -301,7 +302,7 @@ class Traceback(list):
def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None):
""" return a Traceback instance wrapping part of this Traceback
by provding any combination of path, lineno and firstlineno, the
by providing any combination of path, lineno and firstlineno, the
first frame to start the to-be-returned traceback is determined
this allows cutting the first part of a Traceback instance e.g.
@@ -865,7 +866,7 @@ class TerminalRepr:
def __str__(self):
# FYI this is called from pytest-xdist's serialization of exception
# information.
io = py.io.TextIO()
io = StringIO()
tw = py.io.TerminalWriter(file=io)
self.toterminal(tw)
return io.getvalue().strip()
@@ -1002,7 +1003,7 @@ class ReprFileLocation(TerminalRepr):
def toterminal(self, tw):
# filename and lineno output for each entry,
# using an output format that most editors unterstand
# using an output format that most editors understand
msg = self.message
i = msg.find("\n")
if i != -1:

View File

@@ -31,7 +31,6 @@ def format_explanation(explanation):
for when one explanation needs to span multiple lines, e.g. when
displaying diffs.
"""
explanation = explanation
lines = _split_explanation(explanation)
result = _format_lines(lines)
return "\n".join(result)

View File

@@ -1,5 +1,6 @@
""" interactive debugging with PDB, the Python Debugger. """
import argparse
import functools
import pdb
import sys
from doctest import UnexpectedException
@@ -274,13 +275,16 @@ class PdbTrace:
def _test_pytest_function(pyfuncitem):
_pdb = pytestPDB._init_pdb("runcall")
testfunction = pyfuncitem.obj
pyfuncitem.obj = _pdb.runcall
if "func" in pyfuncitem._fixtureinfo.argnames: # pragma: no branch
raise ValueError("--trace can't be used with a fixture named func!")
pyfuncitem.funcargs["func"] = testfunction
new_list = list(pyfuncitem._fixtureinfo.argnames)
new_list.append("func")
pyfuncitem._fixtureinfo.argnames = tuple(new_list)
# we can't just return `partial(pdb.runcall, testfunction)` because (on
# python < 3.7.4) runcall's first param is `func`, which means we'd get
# an exception if one of the kwargs to testfunction was called `func`
@functools.wraps(testfunction)
def wrapper(*args, **kwargs):
func = functools.partial(testfunction, *args, **kwargs)
_pdb.runcall(func)
pyfuncitem.obj = wrapper
def _enter_pdb(node, excinfo, rep):

View File

@@ -513,7 +513,7 @@ class LogXML:
key = nodeid, slavenode
if key in self.node_reporters:
# TODO: breasks for --dist=each
# TODO: breaks for --dist=each
return self.node_reporters[key]
reporter = _NodeReporter(nodeid, self)

View File

@@ -2,8 +2,7 @@
import logging
import re
from contextlib import contextmanager
import py
from io import StringIO
import pytest
from _pytest.compat import nullcontext
@@ -218,7 +217,7 @@ class LogCaptureHandler(logging.StreamHandler):
def __init__(self):
"""Creates a new log handler."""
logging.StreamHandler.__init__(self, py.io.TextIO())
logging.StreamHandler.__init__(self, StringIO())
self.records = []
def emit(self, record):
@@ -228,7 +227,7 @@ class LogCaptureHandler(logging.StreamHandler):
def reset(self):
self.records = []
self.stream = py.io.TextIO()
self.stream = StringIO()
class LogCaptureFixture:

View File

@@ -429,7 +429,7 @@ class Session(nodes.FSCollector):
# one or more conftests are not in use at this fspath
proxy = FSHookProxy(fspath, pm, remove_mods)
else:
# all plugis are active for this fspath
# all plugins are active for this fspath
proxy = self.config.hook
return proxy

View File

@@ -28,7 +28,7 @@ class MarkEvaluator:
self._mark_name = name
def __bool__(self):
# dont cache here to prevent staleness
# don't cache here to prevent staleness
return bool(self._get_marks())
__nonzero__ = __bool__

View File

@@ -1,6 +1,6 @@
"""
this is a place where we put datastructures used by legacy apis
we hope ot remove
we hope to remove
"""
import keyword

View File

@@ -10,6 +10,7 @@ import time
import traceback
from collections.abc import Sequence
from fnmatch import fnmatch
from io import StringIO
from weakref import WeakKeyDictionary
import py
@@ -1218,7 +1219,7 @@ def getdecoded(out):
class LineComp:
def __init__(self):
self.stringio = py.io.TextIO()
self.stringio = StringIO()
def assert_contains_lines(self, lines2):
"""Assert that lines2 are contained (linearly) in lines1.

View File

@@ -210,8 +210,8 @@ def pytest_pycollect_makeitem(collector, name, obj):
# mock seems to store unbound methods (issue473), normalize it
obj = getattr(obj, "__func__", obj)
# We need to try and unwrap the function if it's a functools.partial
# or a funtools.wrapped.
# We musn't if it's been wrapped with mock.patch (python 2 only)
# or a functools.wrapped.
# We mustn't if it's been wrapped with mock.patch (python 2 only)
if not (inspect.isfunction(obj) or inspect.isfunction(get_real_func(obj))):
filename, lineno = getfslineno(obj)
warnings.warn_explicit(
@@ -251,18 +251,21 @@ class PyobjMixin(PyobjContext):
@property
def obj(self):
"""Underlying Python object."""
self._mount_obj_if_needed()
return self._obj
@obj.setter
def obj(self, value):
self._obj = value
def _mount_obj_if_needed(self):
obj = getattr(self, "_obj", None)
if obj is None:
self._obj = obj = self._getobj()
# XXX evil hack
# used to avoid Instance collector marker duplication
if self._ALLOW_MARKERS:
self.own_markers.extend(get_unpacked_marks(self.obj))
return obj
@obj.setter
def obj(self, value):
self._obj = value
self.own_markers.extend(get_unpacked_marks(obj))
def _getobj(self):
"""Gets the underlying Python object. May be overwritten by subclasses."""
@@ -429,6 +432,14 @@ class PyCollector(PyobjMixin, nodes.Collector):
class Module(nodes.File, PyCollector):
""" Collector for test classes and functions. """
def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None):
if fspath.basename == "__init__.py":
self._ALLOW_MARKERS = False
nodes.FSCollector.__init__(
self, fspath, parent=parent, config=config, session=session, nodeid=nodeid
)
def _getobj(self):
return self._importtestmodule()
@@ -595,7 +606,7 @@ class Package(Module):
# one or more conftests are not in use at this fspath
proxy = FSHookProxy(fspath, pm, remove_mods)
else:
# all plugis are active for this fspath
# all plugins are active for this fspath
proxy = self.config.hook
return proxy
@@ -628,6 +639,7 @@ class Package(Module):
return path in self.session._initialpaths
def collect(self):
self._mount_obj_if_needed()
this_path = self.fspath.dirpath()
init_module = this_path.join("__init__.py")
if init_module.check(file=1) and path_matches_patterns(
@@ -965,6 +977,12 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
)
del argvalues
if "request" in argnames:
fail(
"'request' is a reserved name and cannot be used in @pytest.mark.parametrize",
pytrace=False,
)
if scope is None:
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)

View File

@@ -1,3 +1,4 @@
from io import StringIO
from pprint import pprint
from typing import Optional
from typing import Union
@@ -180,7 +181,7 @@ class BaseReport:
def _report_unserialization_failure(type_name, report_class, reportdict):
url = "https://github.com/pytest-dev/pytest/issues"
stream = py.io.TextIO()
stream = StringIO()
pprint("-" * 100, stream=stream)
pprint("INTERNALERROR: Unknown entry type returned: %s" % type_name, stream=stream)
pprint("report_name: %s" % report_class, stream=stream)

View File

@@ -122,7 +122,7 @@ def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
evalxfail = getattr(item, "_evalxfail", None)
# unitttest special case, see setting of _unexpectedsuccess
# unittest special case, see setting of _unexpectedsuccess
if hasattr(item, "_unexpectedsuccess") and rep.when == "call":
if item._unexpectedsuccess:
@@ -132,7 +132,7 @@ def pytest_runtest_makereport(item, call):
rep.outcome = "failed"
elif item.config.option.runxfail:
pass # don't interefere
pass # don't interfere
elif call.excinfo and call.excinfo.errisinstance(xfail.Exception):
rep.wasxfail = "reason: " + call.excinfo.value.msg
rep.outcome = "skipped"

View File

@@ -1,6 +1,6 @@
"""
This is the script that is actually frozen into an executable: simply executes
py.test main().
pytest main().
"""
if __name__ == "__main__":

View File

@@ -1148,7 +1148,7 @@ def test_dont_collect_non_function_callable(testdir):
"""Test for issue https://github.com/pytest-dev/pytest/issues/331
In this case an INTERNALERROR occurred trying to report the failure of
a test like this one because py test failed to get the source lines.
a test like this one because pytest failed to get the source lines.
"""
testdir.makepyfile(
"""

View File

@@ -15,7 +15,7 @@ class TestMetafunc:
def Metafunc(self, func, config=None):
# the unit tests of this class check if things work correctly
# on the funcarg level, so we don't need a full blown
# initiliazation
# initialization
class FixtureInfo:
name2fixturedefs = None
@@ -72,6 +72,19 @@ class TestMetafunc:
):
metafunc.parametrize("x", [1], scope="doggy")
def test_parametrize_request_name(self, testdir):
"""Show proper error when 'request' is used as a parameter name in parametrize (#6183)"""
def func(request):
raise NotImplementedError()
metafunc = self.Metafunc(func)
with pytest.raises(
pytest.fail.Exception,
match=r"'request' is a reserved name and cannot be used in @pytest.mark.parametrize",
):
metafunc.parametrize("request", [1])
def test_find_parametrized_scope(self):
"""unittest for _find_parametrized_scope (#3941)"""
from _pytest.python import _find_parametrized_scope

View File

@@ -5,10 +5,9 @@ import pickle
import subprocess
import sys
import textwrap
from io import StringIO
from io import UnsupportedOperation
import py
import pytest
from _pytest import capture
from _pytest.capture import CaptureManager
@@ -892,10 +891,10 @@ def test_dupfile_on_bytesio():
def test_dupfile_on_textio():
tio = py.io.TextIO()
f = capture.safe_text_dupfile(tio, "wb")
sio = StringIO()
f = capture.safe_text_dupfile(sio, "wb")
f.write("hello")
assert tio.getvalue() == "hello"
assert sio.getvalue() == "hello"
assert not hasattr(f, "name")

View File

@@ -482,7 +482,7 @@ class TestFunctional:
items, rec = testdir.inline_genitems(p)
base_item, sub_item, sub_item_other = items
print(items, [x.nodeid for x in items])
# new api seregates
# new api segregates
assert not list(base_item.iter_markers(name="b"))
assert not list(sub_item_other.iter_markers(name="b"))
assert list(sub_item.iter_markers(name="b"))

View File

@@ -229,7 +229,7 @@ def test_nose_setup_ordering(testdir):
def test_apiwrapper_problem_issue260(testdir):
# this would end up trying a call an optional teardown on the class
# for plain unittests we dont want nose behaviour
# for plain unittests we don't want nose behaviour
testdir.makepyfile(
"""
import unittest

View File

@@ -304,7 +304,7 @@ def test_argcomplete(testdir, monkeypatch):
shlex.quote(sys.executable)
)
)
# alternative would be exteneded Testdir.{run(),_run(),popen()} to be able
# alternative would be extended Testdir.{run(),_run(),popen()} to be able
# to handle a keyword argument env that replaces os.environ in popen or
# extends the copy, advantage: could not forget to restore
monkeypatch.setenv("_ARGCOMPLETE", "1")

View File

@@ -581,7 +581,7 @@ class TestPDB:
# No extra newline.
assert child.before.endswith(b"c\r\nprint_from_foo\r\n")
# set_debug should not raise outcomes.Exit, if used recrursively.
# set_debug should not raise outcomes. Exit, if used recursively.
child.sendline("debug 42")
child.sendline("q")
child.expect("LEAVING RECURSIVE DEBUGGER")
@@ -1025,6 +1025,51 @@ class TestTraceOption:
assert "Exit: Quitting debugger" not in child.before.decode("utf8")
TestPDB.flush(child)
def test_trace_with_parametrize_handles_shared_fixtureinfo(self, testdir):
p1 = testdir.makepyfile(
"""
import pytest
@pytest.mark.parametrize('myparam', [1,2])
def test_1(myparam, request):
assert myparam in (1, 2)
assert request.function.__name__ == "test_1"
@pytest.mark.parametrize('func', [1,2])
def test_func(func, request):
assert func in (1, 2)
assert request.function.__name__ == "test_func"
@pytest.mark.parametrize('myparam', [1,2])
def test_func_kw(myparam, request, func="func_kw"):
assert myparam in (1, 2)
assert func == "func_kw"
assert request.function.__name__ == "test_func_kw"
"""
)
child = testdir.spawn_pytest("--trace " + str(p1))
for func, argname in [
("test_1", "myparam"),
("test_func", "func"),
("test_func_kw", "myparam"),
]:
child.expect_exact("> PDB runcall (IO-capturing turned off) >")
child.expect_exact(func)
child.expect_exact("Pdb")
child.sendline("args")
child.expect_exact("{} = 1\r\n".format(argname))
child.expect_exact("Pdb")
child.sendline("c")
child.expect_exact("Pdb")
child.sendline("args")
child.expect_exact("{} = 2\r\n".format(argname))
child.expect_exact("Pdb")
child.sendline("c")
child.expect_exact("> PDB continue (IO-capturing resumed) >")
rest = child.read().decode("utf8")
assert "6 passed in" in rest
assert "reading from stdin while output" not in rest
# Only printed once - not on stderr.
assert "Exit: Quitting debugger" not in child.before.decode("utf8")
TestPDB.flush(child)
def test_trace_after_runpytest(testdir):
"""Test that debugging's pytest_configure is re-entrant."""
@@ -1150,7 +1195,6 @@ def test_pdbcls_via_local_module(testdir):
def runcall(self, *args, **kwds):
print("runcall_called", args, kwds)
assert "func" in kwds
""",
)
result = testdir.runpytest(

View File

@@ -133,17 +133,17 @@ class TestReportSerialization:
"""
reprec = testdir.inline_runsource(
"""
import py
import pytest
def test_pass(): pass
def test_fail(): 0/0
@py.test.mark.skipif("True")
@pytest.mark.skipif("True")
def test_skip(): pass
def test_skip_imperative():
py.test.skip("hello")
@py.test.mark.xfail("True")
pytest.skip("hello")
@pytest.mark.xfail("True")
def test_xfail(): 0/0
def test_xfail_imperative():
py.test.xfail("hello")
pytest.xfail("hello")
"""
)
reports = reprec.getreports("pytest_runtest_logreport")

View File

@@ -1,6 +1,5 @@
import os
import py
from io import StringIO
import _pytest._code
import pytest
@@ -13,7 +12,7 @@ pytestmark = pytest.mark.filterwarnings("ignore:--result-log is deprecated")
def test_write_log_entry():
reslog = ResultLog(None, None)
reslog.logfile = py.io.TextIO()
reslog.logfile = StringIO()
reslog.write_log_entry("name", ".", "")
entry = reslog.logfile.getvalue()
assert entry[-1] == "\n"
@@ -21,7 +20,7 @@ def test_write_log_entry():
assert len(entry_lines) == 1
assert entry_lines[0] == ". name"
reslog.logfile = py.io.TextIO()
reslog.logfile = StringIO()
reslog.write_log_entry("name", "s", "Skipped")
entry = reslog.logfile.getvalue()
assert entry[-1] == "\n"
@@ -30,7 +29,7 @@ def test_write_log_entry():
assert entry_lines[0] == "s name"
assert entry_lines[1] == " Skipped"
reslog.logfile = py.io.TextIO()
reslog.logfile = StringIO()
reslog.write_log_entry("name", "s", "Skipped\n")
entry = reslog.logfile.getvalue()
assert entry[-1] == "\n"
@@ -39,7 +38,7 @@ def test_write_log_entry():
assert entry_lines[0] == "s name"
assert entry_lines[1] == " Skipped"
reslog.logfile = py.io.TextIO()
reslog.logfile = StringIO()
longrepr = " tb1\n tb 2\nE tb3\nSome Error"
reslog.write_log_entry("name", "F", longrepr)
entry = reslog.logfile.getvalue()
@@ -118,7 +117,7 @@ class TestWithFunctionIntegration:
raise ValueError
except ValueError:
excinfo = _pytest._code.ExceptionInfo.from_current()
reslog = ResultLog(None, py.io.TextIO())
reslog = ResultLog(None, StringIO())
reslog.pytest_internalerror(excinfo.getrepr(style=style))
entry = reslog.logfile.getvalue()
entry_lines = entry.splitlines()

View File

@@ -1162,3 +1162,26 @@ def test_importorskip():
match="^could not import 'doesnotexist': No module named .*",
):
pytest.importorskip("doesnotexist")
def test_skip_package(testdir):
testdir.makepyfile(
__init__="""
import pytest
pytestmark = pytest.mark.skip
"""
)
testdir.makepyfile(
"""
import pytest
def test_skip1():
assert 0
def test_skip2():
assert 0
"""
)
result = testdir.inline_run()
_, skipped, _ = result.listoutcomes()
assert len(skipped) == 2

View File

@@ -4,7 +4,7 @@ import pytest
@pytest.fixture
def stepwise_testdir(testdir):
# Rather than having to modify our testfile between tests, we introduce
# a flag for wether or not the second test should fail.
# a flag for whether or not the second test should fail.
testdir.makeconftest(
"""
def pytest_addoption(parser):

View File

@@ -5,6 +5,7 @@ import collections
import os
import sys
import textwrap
from io import StringIO
import pluggy
import py
@@ -268,7 +269,7 @@ class TestTerminal:
def test_rewrite(self, testdir, monkeypatch):
config = testdir.parseconfig()
f = py.io.TextIO()
f = StringIO()
monkeypatch.setattr(f, "isatty", lambda *args: True)
tr = TerminalReporter(config, f)
tr._tw.fullwidth = 10