Merge branch 'master' into merge-master

# Conflicts:
#	AUTHORS
#	CHANGELOG.rst
#	_pytest/monkeypatch.py
#	_pytest/python.py
This commit is contained in:
Bruno Oliveira 2016-07-25 19:04:39 -03:00
commit c2864aba3d
18 changed files with 216 additions and 50 deletions

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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.
""" """

View File

@ -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))

View File

@ -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(

View File

@ -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:

View File

@ -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:

View File

@ -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`_

View File

@ -19,6 +19,7 @@ Full pytest documentation
recwarn recwarn
cache cache
plugins plugins
nose
backwards-compatibility backwards-compatibility
contributing contributing

View File

@ -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.

View File

@ -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):

View File

@ -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):

View File

@ -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.

View File

@ -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

View File

@ -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):

View File

@ -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