Merge branch 'master' into merge-master
# Conflicts: # AUTHORS # CHANGELOG.rst # _pytest/monkeypatch.py # _pytest/python.py
This commit is contained in:
commit
c2864aba3d
|
@ -2,7 +2,10 @@ Thanks for submitting a PR, your contribution is really appreciated!
|
||||||
|
|
||||||
Here's a quick checklist that should be present in PRs:
|
Here's a quick checklist that should be present in PRs:
|
||||||
|
|
||||||
- [ ] Target: for bug or doc fixes, target `master`; for new features, target `features`
|
- [ ] Target: for bug or doc fixes, target `master`; for new features, target `features`;
|
||||||
- [ ] Make sure to include one or more tests for your change
|
- [ ] Make sure to include one or more tests for your change;
|
||||||
- [ ] Add yourself to `AUTHORS`
|
- [ ] Add yourself to `AUTHORS`;
|
||||||
- [ ] Add a new entry to the `CHANGELOG` (choose any open position to avoid merge conflicts with other PRs)
|
- [ ] Add a new entry to `CHANGELOG.rst`
|
||||||
|
* Choose any open position to avoid merge conflicts with other PRs.
|
||||||
|
* Add a link to the issue you are fixing (if any) using RST syntax.
|
||||||
|
* The pytest team likes to have people to acknowledged in the `CHANGELOG`, so please add a thank note to yourself ("Thanks @user for the PR") and a link to your GitHub profile. It may sound weird thanking yourself, but otherwise a maintainer would have to do it manually before or after merging instead of just using GitHub's merge button. This makes it easier on the maintainers to merge PRs.
|
||||||
|
|
22
AUTHORS
22
AUTHORS
|
@ -8,8 +8,8 @@ Abhijeet Kasurde
|
||||||
Alexei Kozlenok
|
Alexei Kozlenok
|
||||||
Anatoly Bubenkoff
|
Anatoly Bubenkoff
|
||||||
Andreas Zeidler
|
Andreas Zeidler
|
||||||
Andy Freeland
|
|
||||||
Andrzej Ostrowski
|
Andrzej Ostrowski
|
||||||
|
Andy Freeland
|
||||||
Anthon van der Neut
|
Anthon van der Neut
|
||||||
Antony Lee
|
Antony Lee
|
||||||
Armin Rigo
|
Armin Rigo
|
||||||
|
@ -17,6 +17,7 @@ Aron Curzon
|
||||||
Aviv Palivoda
|
Aviv Palivoda
|
||||||
Ben Webb
|
Ben Webb
|
||||||
Benjamin Peterson
|
Benjamin Peterson
|
||||||
|
Bernard Pratz
|
||||||
Bob Ippolito
|
Bob Ippolito
|
||||||
Brian Dorsey
|
Brian Dorsey
|
||||||
Brian Okken
|
Brian Okken
|
||||||
|
@ -38,7 +39,10 @@ Dave Hunt
|
||||||
David Díaz-Barquero
|
David Díaz-Barquero
|
||||||
David Mohr
|
David Mohr
|
||||||
David Vierra
|
David Vierra
|
||||||
|
Diego Russo
|
||||||
|
Dmitry Dygalo
|
||||||
Edison Gustavo Muenz
|
Edison Gustavo Muenz
|
||||||
|
Edoardo Batini
|
||||||
Eduardo Schettino
|
Eduardo Schettino
|
||||||
Elizaveta Shashkova
|
Elizaveta Shashkova
|
||||||
Endre Galaczi
|
Endre Galaczi
|
||||||
|
@ -62,12 +66,14 @@ Jan Balster
|
||||||
Janne Vanhala
|
Janne Vanhala
|
||||||
Jason R. Coombs
|
Jason R. Coombs
|
||||||
Javier Domingo Cansino
|
Javier Domingo Cansino
|
||||||
|
Javier Romero
|
||||||
John Towler
|
John Towler
|
||||||
|
Jon Sonesen
|
||||||
Joshua Bronson
|
Joshua Bronson
|
||||||
Jurko Gospodnetić
|
Jurko Gospodnetić
|
||||||
Justyna Janczyszyn
|
Justyna Janczyszyn
|
||||||
Katarzyna Jachim
|
|
||||||
Kale Kundert
|
Kale Kundert
|
||||||
|
Katarzyna Jachim
|
||||||
Kevin Cox
|
Kevin Cox
|
||||||
Lee Kamentsky
|
Lee Kamentsky
|
||||||
Lukas Bednar
|
Lukas Bednar
|
||||||
|
@ -77,8 +83,8 @@ Marc Schlaich
|
||||||
Mark Abramowitz
|
Mark Abramowitz
|
||||||
Markus Unterwaditzer
|
Markus Unterwaditzer
|
||||||
Martijn Faassen
|
Martijn Faassen
|
||||||
Martin Prusse
|
|
||||||
Martin K. Scherer
|
Martin K. Scherer
|
||||||
|
Martin Prusse
|
||||||
Matt Bachmann
|
Matt Bachmann
|
||||||
Matt Williams
|
Matt Williams
|
||||||
Michael Aquilina
|
Michael Aquilina
|
||||||
|
@ -103,17 +109,17 @@ Ross Lawley
|
||||||
Russel Winder
|
Russel Winder
|
||||||
Ryan Wooden
|
Ryan Wooden
|
||||||
Samuele Pedroni
|
Samuele Pedroni
|
||||||
|
Simon Gomizelj
|
||||||
|
Stefan Farmbauer
|
||||||
|
Stefan Zimmermann
|
||||||
|
Stefano Taschini
|
||||||
Steffen Allner
|
Steffen Allner
|
||||||
Stephan Obermann
|
Stephan Obermann
|
||||||
Tareq Alayan
|
Tareq Alayan
|
||||||
Ted Xiao
|
Ted Xiao
|
||||||
Simon Gomizelj
|
|
||||||
Stefano Taschini
|
|
||||||
Stefan Farmbauer
|
|
||||||
Thomas Grainger
|
Thomas Grainger
|
||||||
Tom Viner
|
Tom Viner
|
||||||
Trevor Bekolay
|
Trevor Bekolay
|
||||||
Vasily Kuznetsov
|
Vasily Kuznetsov
|
||||||
Wouter van Ackooy
|
Wouter van Ackooy
|
||||||
Bernard Pratz
|
|
||||||
Stefan Zimmermann
|
|
||||||
|
|
|
@ -229,6 +229,12 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
removed in pytest-4.0 (`#1684`_).
|
removed in pytest-4.0 (`#1684`_).
|
||||||
Thanks `@nicoddemus`_ for the PR.
|
Thanks `@nicoddemus`_ for the PR.
|
||||||
|
|
||||||
|
* Raise helpful failure message, when requesting parametrized fixture at runtime,
|
||||||
|
e.g. with ``request.getfuncargvalue``. BACKWARD INCOMPAT: Previously these params
|
||||||
|
were simply never defined. So a fixture decorated like ``@pytest.fixture(params=[0, 1, 2])``
|
||||||
|
only ran once. Now a failure is raised. Fixes (`#460`_). Thanks to
|
||||||
|
`@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for the PR.
|
||||||
|
|
||||||
* Passing a command-line string to ``pytest.main()`` is considered deprecated and scheduled
|
* Passing a command-line string to ``pytest.main()`` is considered deprecated and scheduled
|
||||||
for removal in pytest-4.0. It is recommended to pass a list of arguments instead (`#1723`_).
|
for removal in pytest-4.0. It is recommended to pass a list of arguments instead (`#1723`_).
|
||||||
|
|
||||||
|
@ -238,12 +244,19 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
|
|
||||||
* ``optparse`` type usage now triggers DeprecationWarnings (`#1740`_).
|
* ``optparse`` type usage now triggers DeprecationWarnings (`#1740`_).
|
||||||
|
|
||||||
|
|
||||||
* ``optparse`` backward compatibility supports float/complex types (`#457`_).
|
* ``optparse`` backward compatibility supports float/complex types (`#457`_).
|
||||||
|
|
||||||
|
* Renamed the pytest ``pdb`` module (plugin) into ``debugging``.
|
||||||
|
|
||||||
* Better message in case of not using parametrized variable (see `#1539`_).
|
* Better message in case of not using parametrized variable (see `#1539`_).
|
||||||
Thanks to `@tramwaj29`_ for the PR.
|
Thanks to `@tramwaj29`_ for the PR.
|
||||||
|
|
||||||
*
|
* Updated docstrings with a more uniform style.
|
||||||
|
|
||||||
|
* Add stderr write for ``pytest.exit(msg)`` during startup. Previously the message was never shown.
|
||||||
|
Thanks `@BeyondEvil`_ for reporting `#1210`_. Thanks to `@JonathonSonesen`_ and
|
||||||
|
`@tomviner`_ for PR.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
@ -271,7 +284,18 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
identify bugs in ``conftest.py`` files (`#1516`_). Thanks `@txomon`_ for
|
identify bugs in ``conftest.py`` files (`#1516`_). Thanks `@txomon`_ for
|
||||||
the PR.
|
the PR.
|
||||||
|
|
||||||
*
|
* Add an 'E' to the first line of error messages from FixtureLookupErrorRepr.
|
||||||
|
Fixes `#717`_. Thanks `@blueyed`_ for reporting, `@eolo999`_ for the PR
|
||||||
|
and `@tomviner`_ for his guidance during EuroPython2016 sprint.
|
||||||
|
|
||||||
|
* Text documents without any doctests no longer appear as "skipped".
|
||||||
|
Thanks `@graingert`_ for reporting and providing a full PR (`#1580`_).
|
||||||
|
|
||||||
|
* Fixed collection of classes with custom ``__new__`` method.
|
||||||
|
Fixes `#1579`_. Thanks to `@Stranger6667`_ for the PR.
|
||||||
|
|
||||||
|
* Fixed scope overriding inside metafunc.parametrize (`#634`_).
|
||||||
|
Thanks to `@Stranger6667`_ for the PR.
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
@ -281,12 +305,7 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
.. _#372: https://github.com/pytest-dev/pytest/issues/372
|
.. _#1210: https://github.com/pytest-dev/pytest/issues/1210
|
||||||
.. _#460: https://github.com/pytest-dev/pytest/pull/460
|
|
||||||
.. _#457: https://github.com/pytest-dev/pytest/issues/457
|
|
||||||
.. _#1740: https://github.com/pytest-dev/pytest/issues/1740
|
|
||||||
.. _#607: https://github.com/pytest-dev/pytest/issues/607
|
|
||||||
.. _#925: https://github.com/pytest-dev/pytest/issues/925
|
|
||||||
.. _#1235: https://github.com/pytest-dev/pytest/issues/1235
|
.. _#1235: https://github.com/pytest-dev/pytest/issues/1235
|
||||||
.. _#1351: https://github.com/pytest-dev/pytest/issues/1351
|
.. _#1351: https://github.com/pytest-dev/pytest/issues/1351
|
||||||
.. _#1421: https://github.com/pytest-dev/pytest/issues/1421
|
.. _#1421: https://github.com/pytest-dev/pytest/issues/1421
|
||||||
|
@ -305,9 +324,11 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
.. _#1519: https://github.com/pytest-dev/pytest/pull/1519
|
.. _#1519: https://github.com/pytest-dev/pytest/pull/1519
|
||||||
.. _#1520: https://github.com/pytest-dev/pytest/pull/1520
|
.. _#1520: https://github.com/pytest-dev/pytest/pull/1520
|
||||||
.. _#1526: https://github.com/pytest-dev/pytest/pull/1526
|
.. _#1526: https://github.com/pytest-dev/pytest/pull/1526
|
||||||
|
.. _#1539: https://github.com/pytest-dev/pytest/issues/1539
|
||||||
.. _#1544: https://github.com/pytest-dev/pytest/issues/1544
|
.. _#1544: https://github.com/pytest-dev/pytest/issues/1544
|
||||||
.. _#1553: https://github.com/pytest-dev/pytest/issues/1553
|
.. _#1553: https://github.com/pytest-dev/pytest/issues/1553
|
||||||
.. _#1562: https://github.com/pytest-dev/pytest/issues/1562
|
.. _#1562: https://github.com/pytest-dev/pytest/issues/1562
|
||||||
|
.. _#1579: https://github.com/pytest-dev/pytest/issues/1579
|
||||||
.. _#1580: https://github.com/pytest-dev/pytest/pull/1580
|
.. _#1580: https://github.com/pytest-dev/pytest/pull/1580
|
||||||
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597
|
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597
|
||||||
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605
|
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605
|
||||||
|
@ -315,32 +336,40 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
.. _#1618: https://github.com/pytest-dev/pytest/issues/1618
|
.. _#1618: https://github.com/pytest-dev/pytest/issues/1618
|
||||||
.. _#1619: https://github.com/pytest-dev/pytest/issues/1619
|
.. _#1619: https://github.com/pytest-dev/pytest/issues/1619
|
||||||
.. _#1626: https://github.com/pytest-dev/pytest/pull/1626
|
.. _#1626: https://github.com/pytest-dev/pytest/pull/1626
|
||||||
.. _#1668: https://github.com/pytest-dev/pytest/issues/1668
|
|
||||||
.. _#1627: https://github.com/pytest-dev/pytest/pull/1627
|
.. _#1627: https://github.com/pytest-dev/pytest/pull/1627
|
||||||
.. _#1628: https://github.com/pytest-dev/pytest/pull/1628
|
.. _#1628: https://github.com/pytest-dev/pytest/pull/1628
|
||||||
.. _#1629: https://github.com/pytest-dev/pytest/issues/1629
|
.. _#1629: https://github.com/pytest-dev/pytest/issues/1629
|
||||||
.. _#1632: https://github.com/pytest-dev/pytest/issues/1632
|
.. _#1632: https://github.com/pytest-dev/pytest/issues/1632
|
||||||
.. _#1633: https://github.com/pytest-dev/pytest/pull/1633
|
.. _#1633: https://github.com/pytest-dev/pytest/pull/1633
|
||||||
.. _#1664: https://github.com/pytest-dev/pytest/pull/1664
|
.. _#1664: https://github.com/pytest-dev/pytest/pull/1664
|
||||||
|
.. _#1668: https://github.com/pytest-dev/pytest/issues/1668
|
||||||
.. _#1684: https://github.com/pytest-dev/pytest/pull/1684
|
.. _#1684: https://github.com/pytest-dev/pytest/pull/1684
|
||||||
.. _#1723: https://github.com/pytest-dev/pytest/pull/1723
|
.. _#1723: https://github.com/pytest-dev/pytest/pull/1723
|
||||||
.. _#1539: https://github.com/pytest-dev/pytest/issues/1539
|
.. _#1740: https://github.com/pytest-dev/pytest/issues/1740
|
||||||
.. _#1749: https://github.com/pytest-dev/pytest/issues/1749
|
.. _#1749: https://github.com/pytest-dev/pytest/issues/1749
|
||||||
|
.. _#372: https://github.com/pytest-dev/pytest/issues/372
|
||||||
|
.. _#457: https://github.com/pytest-dev/pytest/issues/457
|
||||||
|
.. _#460: https://github.com/pytest-dev/pytest/pull/460
|
||||||
|
.. _#607: https://github.com/pytest-dev/pytest/issues/607
|
||||||
|
.. _#634: https://github.com/pytest-dev/pytest/issues/634
|
||||||
|
.. _#717: https://github.com/pytest-dev/pytest/issues/717
|
||||||
|
.. _#925: https://github.com/pytest-dev/pytest/issues/925
|
||||||
|
|
||||||
.. _@DRMacIver: https://github.com/DRMacIver
|
|
||||||
.. _@RedBeardCode: https://github.com/RedBeardCode
|
|
||||||
.. _@Vogtinator: https://github.com/Vogtinator
|
|
||||||
.. _@anntzer: https://github.com/anntzer
|
.. _@anntzer: https://github.com/anntzer
|
||||||
.. _@bagerard: https://github.com/bagerard
|
.. _@bagerard: https://github.com/bagerard
|
||||||
|
.. _@BeyondEvil: https://github.com/BeyondEvil
|
||||||
.. _@blueyed: https://github.com/blueyed
|
.. _@blueyed: https://github.com/blueyed
|
||||||
.. _@ceridwen: https://github.com/ceridwen
|
.. _@ceridwen: https://github.com/ceridwen
|
||||||
.. _@csaftoiu: https://github.com/csaftoiu
|
.. _@csaftoiu: https://github.com/csaftoiu
|
||||||
.. _@d6e: https://github.com/d6e
|
.. _@d6e: https://github.com/d6e
|
||||||
.. _@davehunt: https://github.com/davehunt
|
.. _@davehunt: https://github.com/davehunt
|
||||||
|
.. _@DRMacIver: https://github.com/DRMacIver
|
||||||
|
.. _@eolo999: https://github.com/eolo999
|
||||||
.. _@fengxx: https://github.com/fengxx
|
.. _@fengxx: https://github.com/fengxx
|
||||||
.. _@flub: https://github.com/flub
|
.. _@flub: https://github.com/flub
|
||||||
.. _@graingert: https://github.com/graingert
|
.. _@graingert: https://github.com/graingert
|
||||||
.. _@hartym: https://github.com/hartym
|
.. _@hartym: https://github.com/hartym
|
||||||
|
.. _@JonathonSonesen: https://github.com/JonathonSonesen
|
||||||
.. _@kalekundert: https://github.com/kalekundert
|
.. _@kalekundert: https://github.com/kalekundert
|
||||||
.. _@kvas-it: https://github.com/kvas-it
|
.. _@kvas-it: https://github.com/kvas-it
|
||||||
.. _@marscher: https://github.com/marscher
|
.. _@marscher: https://github.com/marscher
|
||||||
|
@ -353,12 +382,16 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
.. _@olegpidsadnyi: https://github.com/olegpidsadnyi
|
.. _@olegpidsadnyi: https://github.com/olegpidsadnyi
|
||||||
.. _@omarkohl: https://github.com/omarkohl
|
.. _@omarkohl: https://github.com/omarkohl
|
||||||
.. _@palaviv: https://github.com/palaviv
|
.. _@palaviv: https://github.com/palaviv
|
||||||
|
.. _@RedBeardCode: https://github.com/RedBeardCode
|
||||||
.. _@sallner: https://github.com/sallner
|
.. _@sallner: https://github.com/sallner
|
||||||
.. _@sober7: https://github.com/sober7
|
.. _@sober7: https://github.com/sober7
|
||||||
|
.. _@Stranger6667: https://github.com/Stranger6667
|
||||||
.. _@tareqalayan: https://github.com/tareqalayan
|
.. _@tareqalayan: https://github.com/tareqalayan
|
||||||
.. _@taschini: https://github.com/taschini
|
.. _@taschini: https://github.com/taschini
|
||||||
.. _@txomon: https://github.com/txomon
|
|
||||||
.. _@tramwaj29: https://github.com/tramwaj29
|
.. _@tramwaj29: https://github.com/tramwaj29
|
||||||
|
.. _@txomon: https://github.com/txomon
|
||||||
|
.. _@Vogtinator: https://github.com/Vogtinator
|
||||||
|
|
||||||
|
|
||||||
2.9.2
|
2.9.2
|
||||||
=====
|
=====
|
||||||
|
@ -392,8 +425,8 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
|
|
||||||
.. _#510: https://github.com/pytest-dev/pytest/issues/510
|
.. _#510: https://github.com/pytest-dev/pytest/issues/510
|
||||||
.. _#1506: https://github.com/pytest-dev/pytest/pull/1506
|
.. _#1506: https://github.com/pytest-dev/pytest/pull/1506
|
||||||
.. _#1496: https://github.com/pytest-dev/pytest/issue/1496
|
.. _#1496: https://github.com/pytest-dev/pytest/issues/1496
|
||||||
.. _#1524: https://github.com/pytest-dev/pytest/issue/1524
|
.. _#1524: https://github.com/pytest-dev/pytest/pull/1524
|
||||||
|
|
||||||
.. _@prusse-martin: https://github.com/prusse-martin
|
.. _@prusse-martin: https://github.com/prusse-martin
|
||||||
.. _@astraw38: https://github.com/astraw38
|
.. _@astraw38: https://github.com/astraw38
|
||||||
|
|
|
@ -157,7 +157,7 @@ error_capsysfderror = "cannot use capsys and capfd at the same time"
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def capsys(request):
|
def capsys(request):
|
||||||
"""enables capturing of writes to sys.stdout/sys.stderr and makes
|
"""Enable capturing of writes to sys.stdout/sys.stderr and make
|
||||||
captured output available via ``capsys.readouterr()`` method calls
|
captured output available via ``capsys.readouterr()`` method calls
|
||||||
which return a ``(out, err)`` tuple.
|
which return a ``(out, err)`` tuple.
|
||||||
"""
|
"""
|
||||||
|
@ -168,7 +168,7 @@ def capsys(request):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def capfd(request):
|
def capfd(request):
|
||||||
"""enables capturing of writes to file descriptors 1 and 2 and makes
|
"""Enable capturing of writes to file descriptors 1 and 2 and make
|
||||||
captured output available via ``capfd.readouterr()`` method calls
|
captured output available via ``capfd.readouterr()`` method calls
|
||||||
which return a ``(out, err)`` tuple.
|
which return a ``(out, err)`` tuple.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -673,8 +673,13 @@ class FixtureLookupErrorRepr(TerminalRepr):
|
||||||
#tw.line("FixtureLookupError: %s" %(self.argname), red=True)
|
#tw.line("FixtureLookupError: %s" %(self.argname), red=True)
|
||||||
for tbline in self.tblines:
|
for tbline in self.tblines:
|
||||||
tw.line(tbline.rstrip())
|
tw.line(tbline.rstrip())
|
||||||
for line in self.errorstring.split("\n"):
|
lines = self.errorstring.split("\n")
|
||||||
tw.line(" " + line.strip(), red=True)
|
for line in lines:
|
||||||
|
if line == lines[0]:
|
||||||
|
prefix = 'E '
|
||||||
|
else:
|
||||||
|
prefix = ' '
|
||||||
|
tw.line(prefix + line.strip(), red=True)
|
||||||
tw.line()
|
tw.line()
|
||||||
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
|
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
|
||||||
|
|
||||||
|
|
|
@ -186,8 +186,8 @@ class _NodeReporter(object):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def record_xml_property(request):
|
def record_xml_property(request):
|
||||||
"""Fixture that adds extra xml properties to the tag for the calling test.
|
"""Add extra xml properties to the tag for the calling test.
|
||||||
The fixture is callable with (name, value), with value being automatically
|
The fixture is callable with ``(name, value)``, with value being automatically
|
||||||
xml-encoded.
|
xml-encoded.
|
||||||
"""
|
"""
|
||||||
request.node.warn(
|
request.node.warn(
|
||||||
|
|
|
@ -98,6 +98,10 @@ def wrap_session(config, doit):
|
||||||
raise
|
raise
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
excinfo = _pytest._code.ExceptionInfo()
|
excinfo = _pytest._code.ExceptionInfo()
|
||||||
|
if initstate < 2 and isinstance(
|
||||||
|
excinfo.value, pytest.exit.Exception):
|
||||||
|
sys.stderr.write('{0}: {1}\n'.format(
|
||||||
|
excinfo.typename, excinfo.value.msg))
|
||||||
config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||||
session.exitstatus = EXIT_INTERRUPTED
|
session.exitstatus = EXIT_INTERRUPTED
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -489,6 +489,10 @@ class Class(PyCollector):
|
||||||
self.warn("C1", "cannot collect test class %r because it has a "
|
self.warn("C1", "cannot collect test class %r because it has a "
|
||||||
"__init__ constructor" % self.obj.__name__)
|
"__init__ constructor" % self.obj.__name__)
|
||||||
return []
|
return []
|
||||||
|
elif hasnew(self.obj):
|
||||||
|
self.warn("C1", "cannot collect test class %r because it has a "
|
||||||
|
"__new__ constructor" % self.obj.__name__)
|
||||||
|
return []
|
||||||
return [self._getcustomclass("Instance")(name="()", parent=self)]
|
return [self._getcustomclass("Instance")(name="()", parent=self)]
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
@ -506,8 +510,7 @@ class Class(PyCollector):
|
||||||
|
|
||||||
class Instance(PyCollector):
|
class Instance(PyCollector):
|
||||||
def _getobj(self):
|
def _getobj(self):
|
||||||
obj = self.parent.obj()
|
return self.parent.obj()
|
||||||
return obj
|
|
||||||
|
|
||||||
def collect(self):
|
def collect(self):
|
||||||
self.session._fixturemanager.parsefactories(self)
|
self.session._fixturemanager.parsefactories(self)
|
||||||
|
@ -622,8 +625,13 @@ class Generator(FunctionMixin, PyCollector):
|
||||||
def hasinit(obj):
|
def hasinit(obj):
|
||||||
init = getattr(obj, '__init__', None)
|
init = getattr(obj, '__init__', None)
|
||||||
if init:
|
if init:
|
||||||
if init != object.__init__:
|
return init != object.__init__
|
||||||
return True
|
|
||||||
|
|
||||||
|
def hasnew(obj):
|
||||||
|
new = getattr(obj, '__new__', None)
|
||||||
|
if new:
|
||||||
|
return new != object.__new__
|
||||||
|
|
||||||
|
|
||||||
class CallSpec2(object):
|
class CallSpec2(object):
|
||||||
|
@ -763,7 +771,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||||
It will also override any fixture-function defined scope, allowing
|
It will also override any fixture-function defined scope, allowing
|
||||||
to set a dynamic scope using test context or configuration.
|
to set a dynamic scope using test context or configuration.
|
||||||
"""
|
"""
|
||||||
|
from _pytest.fixtures import scopes
|
||||||
# individual parametrized argument sets can be wrapped in a series
|
# individual parametrized argument sets can be wrapped in a series
|
||||||
# of markers in which case we unwrap the values and apply the mark
|
# of markers in which case we unwrap the values and apply the mark
|
||||||
# at Function init
|
# at Function init
|
||||||
|
@ -794,10 +802,16 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||||
newmarks = newkeywords.setdefault(0, {})
|
newmarks = newkeywords.setdefault(0, {})
|
||||||
newmarks[newmark.markname] = newmark
|
newmarks[newmark.markname] = newmark
|
||||||
|
|
||||||
|
|
||||||
if scope is None:
|
if scope is None:
|
||||||
scope = "function"
|
if self._arg2fixturedefs:
|
||||||
scopenum = fixtures.scopes.index(scope)
|
# Takes the most narrow scope from used fixtures
|
||||||
|
fixtures_scopes = [fixturedef[0].scope for fixturedef in self._arg2fixturedefs.values()]
|
||||||
|
for scope in reversed(scopes):
|
||||||
|
if scope in fixtures_scopes:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
scope = 'function'
|
||||||
|
scopenum = scopes.index(scope)
|
||||||
valtypes = {}
|
valtypes = {}
|
||||||
for arg in argnames:
|
for arg in argnames:
|
||||||
if arg not in self.fixturenames:
|
if arg not in self.fixturenames:
|
||||||
|
|
|
@ -108,7 +108,7 @@ def tmpdir_factory(request):
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def tmpdir(request, tmpdir_factory):
|
def tmpdir(request, tmpdir_factory):
|
||||||
"""return a temporary directory path object
|
"""Return a temporary directory path object
|
||||||
which is unique to each test function invocation,
|
which is unique to each test function invocation,
|
||||||
created as a sub directory of the base temporary
|
created as a sub directory of the base temporary
|
||||||
directory. The returned object is a `py.path.local`_
|
directory. The returned object is a `py.path.local`_
|
||||||
|
|
|
@ -19,6 +19,7 @@ Full pytest documentation
|
||||||
recwarn
|
recwarn
|
||||||
cache
|
cache
|
||||||
plugins
|
plugins
|
||||||
|
nose
|
||||||
|
|
||||||
backwards-compatibility
|
backwards-compatibility
|
||||||
contributing
|
contributing
|
||||||
|
|
|
@ -24,7 +24,7 @@ Supported nose Idioms
|
||||||
* setup and teardown at module/class/method level
|
* setup and teardown at module/class/method level
|
||||||
* SkipTest exceptions and markers
|
* SkipTest exceptions and markers
|
||||||
* setup/teardown decorators
|
* setup/teardown decorators
|
||||||
* yield-based tests and their setup
|
* ``yield``-based tests and their setup
|
||||||
* ``__test__`` attribute on modules/classes/functions
|
* ``__test__`` attribute on modules/classes/functions
|
||||||
* general usage of nose utilities
|
* general usage of nose utilities
|
||||||
|
|
||||||
|
@ -51,5 +51,12 @@ Unsupported idioms / known issues
|
||||||
- nose-style doctests are not collected and executed correctly,
|
- nose-style doctests are not collected and executed correctly,
|
||||||
also doctest fixtures don't work.
|
also doctest fixtures don't work.
|
||||||
|
|
||||||
- no nose-configuration is recognized
|
- no nose-configuration is recognized.
|
||||||
|
|
||||||
|
- ``yield``-based methods don't support ``setup`` properly because
|
||||||
|
the ``setup`` method is always called in the same class instance.
|
||||||
|
There are no plans to fix this currently because ``yield``-tests
|
||||||
|
are deprecated in pytest 3.0, with ``pytest.mark.parametrize``
|
||||||
|
being the recommended alternative.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -377,7 +377,7 @@ class TestGeneralUsage:
|
||||||
res = testdir.runpytest(p)
|
res = testdir.runpytest(p)
|
||||||
res.stdout.fnmatch_lines([
|
res.stdout.fnmatch_lines([
|
||||||
"*source code not available*",
|
"*source code not available*",
|
||||||
"*fixture 'invalid_fixture' not found",
|
"E*fixture 'invalid_fixture' not found",
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_plugins_given_as_strings(self, tmpdir, monkeypatch):
|
def test_plugins_given_as_strings(self, tmpdir, monkeypatch):
|
||||||
|
|
|
@ -121,6 +121,18 @@ class TestClass:
|
||||||
colitems = modcol.collect()
|
colitems = modcol.collect()
|
||||||
assert len(colitems) == 0
|
assert len(colitems) == 0
|
||||||
|
|
||||||
|
def test_issue1579_namedtuple(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import collections
|
||||||
|
|
||||||
|
TestCase = collections.namedtuple('TestCase', ['a'])
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest('-rw')
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
"*cannot collect test class 'TestCase' "
|
||||||
|
"because it has a __new__ constructor*"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestGenerator:
|
class TestGenerator:
|
||||||
def test_generative_functions(self, testdir):
|
def test_generative_functions(self, testdir):
|
||||||
|
|
|
@ -351,6 +351,38 @@ class TestFillFixtures:
|
||||||
result = testdir.runpytest(testfile)
|
result = testdir.runpytest(testfile)
|
||||||
result.stdout.fnmatch_lines(["*3 passed*"])
|
result.stdout.fnmatch_lines(["*3 passed*"])
|
||||||
|
|
||||||
|
def test_override_autouse_fixture_with_parametrized_fixture_conftest_conftest(self, testdir):
|
||||||
|
"""Test override of the autouse fixture with parametrized one on the conftest level.
|
||||||
|
This test covers the issue explained in issue 1601
|
||||||
|
"""
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def spam():
|
||||||
|
return 'spam'
|
||||||
|
""")
|
||||||
|
subdir = testdir.mkpydir('subdir')
|
||||||
|
subdir.join("conftest.py").write(_pytest._code.Source("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(params=[1, 2, 3])
|
||||||
|
def spam(request):
|
||||||
|
return request.param
|
||||||
|
"""))
|
||||||
|
testfile = subdir.join("test_spam.py")
|
||||||
|
testfile.write(_pytest._code.Source("""
|
||||||
|
params = {'spam': 1}
|
||||||
|
|
||||||
|
def test_spam(spam):
|
||||||
|
assert spam == params['spam']
|
||||||
|
params['spam'] += 1
|
||||||
|
"""))
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines(["*3 passed*"])
|
||||||
|
result = testdir.runpytest(testfile)
|
||||||
|
result.stdout.fnmatch_lines(["*3 passed*"])
|
||||||
|
|
||||||
def test_autouse_fixture_plugin(self, testdir):
|
def test_autouse_fixture_plugin(self, testdir):
|
||||||
# A fixture from a plugin has no baseid set, which screwed up
|
# A fixture from a plugin has no baseid set, which screwed up
|
||||||
# the autouse fixture handling.
|
# the autouse fixture handling.
|
||||||
|
|
|
@ -930,6 +930,43 @@ class TestMetafuncFunctional:
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=5)
|
reprec.assertoutcome(passed=5)
|
||||||
|
|
||||||
|
def test_parametrize_issue634(self, testdir):
|
||||||
|
testdir.makepyfile('''
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(scope='module')
|
||||||
|
def foo(request):
|
||||||
|
print('preparing foo-%d' % request.param)
|
||||||
|
return 'foo-%d' % request.param
|
||||||
|
|
||||||
|
|
||||||
|
def test_one(foo):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_two(foo):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
test_two.test_with = (2, 3)
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_generate_tests(metafunc):
|
||||||
|
params = (1, 2, 3, 4)
|
||||||
|
if not 'foo' in metafunc.fixturenames:
|
||||||
|
return
|
||||||
|
|
||||||
|
test_with = getattr(metafunc.function, 'test_with', None)
|
||||||
|
if test_with:
|
||||||
|
params = test_with
|
||||||
|
metafunc.parametrize('foo', params, indirect=True)
|
||||||
|
|
||||||
|
''')
|
||||||
|
result = testdir.runpytest("-s")
|
||||||
|
output = result.stdout.str()
|
||||||
|
assert output.count('preparing foo-2') == 1
|
||||||
|
assert output.count('preparing foo-3') == 1
|
||||||
|
|
||||||
def test_parametrize_issue323(self, testdir):
|
def test_parametrize_issue323(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
|
@ -416,9 +416,9 @@ class TestCaptureFixture:
|
||||||
result = testdir.runpytest(p)
|
result = testdir.runpytest(p)
|
||||||
result.stdout.fnmatch_lines([
|
result.stdout.fnmatch_lines([
|
||||||
"*ERROR*setup*test_one*",
|
"*ERROR*setup*test_one*",
|
||||||
"*capsys*capfd*same*time*",
|
"E*capsys*capfd*same*time*",
|
||||||
"*ERROR*setup*test_two*",
|
"*ERROR*setup*test_two*",
|
||||||
"*capsys*capfd*same*time*",
|
"E*capsys*capfd*same*time*",
|
||||||
"*2 error*"])
|
"*2 error*"])
|
||||||
|
|
||||||
def test_capturing_getfixturevalue(self, testdir):
|
def test_capturing_getfixturevalue(self, testdir):
|
||||||
|
|
|
@ -448,6 +448,18 @@ def test_pytest_fail():
|
||||||
s = excinfo.exconly(tryshort=True)
|
s = excinfo.exconly(tryshort=True)
|
||||||
assert s.startswith("Failed")
|
assert s.startswith("Failed")
|
||||||
|
|
||||||
|
def test_pytest_exit_msg(testdir):
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
def pytest_configure(config):
|
||||||
|
pytest.exit('oh noes')
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stderr.fnmatch_lines([
|
||||||
|
"Exit: oh noes",
|
||||||
|
])
|
||||||
|
|
||||||
def test_pytest_fail_notrace(testdir):
|
def test_pytest_fail_notrace(testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
Loading…
Reference in New Issue