diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 239650e5a..2bcea39d8 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -172,13 +172,36 @@
* Add proposal to docs for a new feature that enables users to combine multiple
fixtures into one. Thanks to `@hpk42`_ and `@hackebrot`_.
+* Rename ``getfuncargvalue`` to ``getfixturevalue``. ``getfuncargvalue`` is
+ deprecated but still present. Thanks to `@RedBeardCode`_ and `@tomviner`_
+ for PR (`#1626`_).
+
+* Always include full assertion explanation. The previous behaviour was hiding
+ sub-expressions that happened to be False, assuming this was redundant information.
+ Thanks `@bagerard`_ for reporting (`#1503`_). Thanks to `@davehunt`_ and
+ `@tomviner`_ for PR.
+
+* Renamed the pytest ``pdb`` module (plugin) into ``debugging``.
+
+* Improve of the test output for logical expression with brackets.
+ Fixes(`#925`_). Thanks `@DRMacIver`_ for reporting. Thanks to `@RedBeardCode`_
+ for PR.
+
+* ImportErrors in plugins now are a fatal error instead of issuing a
.. _#1632: https://github.com/pytest-dev/pytest/issues/1632
+
+ pytest warning (`#1479`_). Thanks to `@The-Compiler`_ for the PR.
+
.. _#1580: https://github.com/pytest-dev/pytest/pull/1580
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597
.. _#460: https://github.com/pytest-dev/pytest/pull/460
.. _#1553: https://github.com/pytest-dev/pytest/issues/1553
+.. _#1626: https://github.com/pytest-dev/pytest/pull/1626
+.. _#1503: https://github.com/pytest-dev/pytest/issues/1503
+.. _#1479: https://github.com/pytest-dev/pytest/issues/1479
+.. _#925: https://github.com/pytest-dev/pytest/issues/925
.. _@graingert: https://github.com/graingert
.. _@taschini: https://github.com/taschini
@@ -187,6 +210,9 @@
.. _@Vogtinator: https://github.com/Vogtinator
.. _@blueyed: https://github.com/blueyed
.. _@fengxx: https://github.com/fengxx
+.. _@bagerard: https://github.com/bagerard
+.. _@davehunt: https://github.com/davehunt
+.. _@DRMacIver: https://github.com/DRMacIver
* Fix `#1421`_: Exit tests if a collection error occurs and add
``--continue-on-collection-errors`` option to restore previous behaviour.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index bedc82c65..947d4e655 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -120,6 +120,8 @@ the following:
- an issue tracker for bug reports and enhancement requests.
+- a `changelog `_
+
If no contributor strongly objects and two agree, the repository can then be
transferred to the ``pytest-dev`` organisation.
diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py
index 921d17a10..06944b016 100644
--- a/_pytest/assertion/rewrite.py
+++ b/_pytest/assertion/rewrite.py
@@ -1,6 +1,7 @@
"""Rewrite assertion AST to produce nice error messages"""
import ast
+import _ast
import errno
import itertools
import imp
@@ -876,6 +877,8 @@ class AssertionRewriter(ast.NodeVisitor):
def visit_Compare(self, comp):
self.push_format_context()
left_res, left_expl = self.visit(comp.left)
+ if isinstance(comp.left, (_ast.Compare, _ast.BoolOp)):
+ left_expl = "({0})".format(left_expl)
res_variables = [self.variable() for i in range(len(comp.ops))]
load_names = [ast.Name(v, ast.Load()) for v in res_variables]
store_names = [ast.Name(v, ast.Store()) for v in res_variables]
@@ -885,6 +888,8 @@ class AssertionRewriter(ast.NodeVisitor):
results = [left_res]
for i, op, next_operand in it:
next_res, next_expl = self.visit(next_operand)
+ if isinstance(next_operand, (_ast.Compare, _ast.BoolOp)):
+ next_expl = "({0})".format(next_expl)
results.append(next_res)
sym = binop_map[op.__class__]
syms.append(ast.Str(sym))
diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py
index 8bf425caf..2481cf34c 100644
--- a/_pytest/assertion/util.py
+++ b/_pytest/assertion/util.py
@@ -38,44 +38,11 @@ def format_explanation(explanation):
displaying diffs.
"""
explanation = ecu(explanation)
- explanation = _collapse_false(explanation)
lines = _split_explanation(explanation)
result = _format_lines(lines)
return u('\n').join(result)
-def _collapse_false(explanation):
- """Collapse expansions of False
-
- So this strips out any "assert False\n{where False = ...\n}"
- blocks.
- """
- where = 0
- while True:
- start = where = explanation.find("False\n{False = ", where)
- if where == -1:
- break
- level = 0
- prev_c = explanation[start]
- for i, c in enumerate(explanation[start:]):
- if prev_c + c == "\n{":
- level += 1
- elif prev_c + c == "\n}":
- level -= 1
- if not level:
- break
- prev_c = c
- else:
- raise AssertionError("unbalanced braces: %r" % (explanation,))
- end = start + i
- where = end
- if explanation[end - 1] == '\n':
- explanation = (explanation[:start] + explanation[start+15:end-1] +
- explanation[end+1:])
- where -= 17
- return explanation
-
-
def _split_explanation(explanation):
"""Return a list of individual lines in the explanation
diff --git a/_pytest/config.py b/_pytest/config.py
index 463d8f04f..dfc066675 100644
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -63,7 +63,7 @@ class UsageError(Exception):
_preinit = []
default_plugins = (
- "mark main terminal runner python pdb unittest capture skipping "
+ "mark main terminal runner python debugging unittest capture skipping "
"tmpdir monkeypatch recwarn pastebin helpconfig nose assertion "
"junitxml resultlog doctest cacheprovider freeze_support "
"setuponly setupplan").split()
@@ -656,20 +656,17 @@ class Argument:
self._long_opts.append(opt)
def __repr__(self):
- retval = 'Argument('
+ args = []
if self._short_opts:
- retval += '_short_opts: ' + repr(self._short_opts) + ', '
+ args += ['_short_opts: ' + repr(self._short_opts)]
if self._long_opts:
- retval += '_long_opts: ' + repr(self._long_opts) + ', '
- retval += 'dest: ' + repr(self.dest) + ', '
+ args += ['_long_opts: ' + repr(self._long_opts)]
+ args += ['dest: ' + repr(self.dest)]
if hasattr(self, 'type'):
- retval += 'type: ' + repr(self.type) + ', '
+ args += ['type: ' + repr(self.type)]
if hasattr(self, 'default'):
- retval += 'default: ' + repr(self.default) + ', '
- if retval[-2:] == ', ': # always long enough to test ("Argument(" )
- retval = retval[:-2]
- retval += ')'
- return retval
+ args += ['default: ' + repr(self.default)]
+ return 'Argument({0})'.format(', '.join(args))
class OptionGroup:
@@ -928,10 +925,7 @@ class Config(object):
args[:] = self.getini("addopts") + args
self._checkversion()
self.pluginmanager.consider_preparse(args)
- try:
- self.pluginmanager.load_setuptools_entrypoints("pytest11")
- except ImportError as e:
- self.warn("I2", "could not load setuptools entry import: %s" % (e,))
+ self.pluginmanager.load_setuptools_entrypoints("pytest11")
self.pluginmanager.consider_env()
self.known_args_namespace = ns = self._parser.parse_known_args(args, namespace=self.option.copy())
if self.known_args_namespace.confcutdir is None and self.inifile:
diff --git a/_pytest/pdb.py b/_pytest/debugging.py
similarity index 100%
rename from _pytest/pdb.py
rename to _pytest/debugging.py
diff --git a/_pytest/doctest.py b/_pytest/doctest.py
index 4411158ab..b1babf1e6 100644
--- a/_pytest/doctest.py
+++ b/_pytest/doctest.py
@@ -70,7 +70,7 @@ class DoctestItem(pytest.Item):
def setup(self):
if self.dtest is not None:
self.fixture_request = _setup_fixtures(self)
- globs = dict(getfixture=self.fixture_request.getfuncargvalue)
+ globs = dict(getfixture=self.fixture_request.getfixturevalue)
for name, value in self.fixture_request.getfuncargvalue('doctest_namespace').items():
globs[name] = value
self.dtest.globs.update(globs)
diff --git a/_pytest/python.py b/_pytest/python.py
index a0624839b..c959b21d8 100644
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -6,8 +6,9 @@ import inspect
import re
import types
import sys
-import math
+import warnings
import collections
+import math
import py
import pytest
@@ -1855,7 +1856,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
fixturedefs = self._arg2fixturedefs.get(argname, None)
if fixturedefs is None:
# we arrive here because of a a dynamic call to
- # getfuncargvalue(argname) usage which was naturally
+ # getfixturevalue(argname) usage which was naturally
# not known at parsing/collection time
fixturedefs = self._fixturemanager.getfixturedefs(
argname, self._pyfuncitem.parent.nodeid)
@@ -1950,7 +1951,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
fixturenames = getattr(item, "fixturenames", self.fixturenames)
for argname in fixturenames:
if argname not in item.funcargs:
- item.funcargs[argname] = self.getfuncargvalue(argname)
+ item.funcargs[argname] = self.getfixturevalue(argname)
def cached_setup(self, setup, teardown=None, scope="module", extrakey=None):
""" (deprecated) Return a testing resource managed by ``setup`` &
@@ -1984,17 +1985,23 @@ class FixtureRequest(FuncargnamesCompatAttr):
self._addfinalizer(finalizer, scope=scope)
return val
- def getfuncargvalue(self, argname):
- """ Dynamically retrieve a named fixture function argument.
+ def getfixturevalue(self, argname):
+ """ Dynamically run a named fixture function.
- As of pytest-2.3, it is easier and usually better to access other
- fixture values by stating it as an input argument in the fixture
- function. If you only can decide about using another fixture at test
+ Declaring fixtures via function argument is recommended where possible.
+ But if you can only decide whether to use another fixture at test
setup time, you may use this function to retrieve it inside a fixture
- function body.
+ or test function body.
"""
return self._get_active_fixturedef(argname).cached_result[0]
+ def getfuncargvalue(self, argname):
+ """ Deprecated, use getfixturevalue. """
+ warnings.warn(
+ "use of getfuncargvalue is deprecated, use getfixturevalue",
+ DeprecationWarning)
+ return self.getfixturevalue(argname)
+
def _get_active_fixturedef(self, argname):
try:
return self._fixturedefs[argname]
@@ -2010,7 +2017,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
raise
# remove indent to prevent the python3 exception
# from leaking into the call
- result = self._getfuncargvalue(fixturedef)
+ result = self._getfixturevalue(fixturedef)
self._funcargs[argname] = result
self._fixturedefs[argname] = fixturedef
return fixturedef
@@ -2026,7 +2033,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
l.append(fixturedef)
current = current._parent_request
- def _getfuncargvalue(self, fixturedef):
+ def _getfixturevalue(self, fixturedef):
# prepare a subrequest object before calling fixture function
# (latter managed by fixturedef)
argname = fixturedef.argname
diff --git a/appveyor.yml b/appveyor.yml
index 4b73645f7..2bd72db45 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,6 +5,13 @@ environment:
# using pytestbot account as detailed here:
# https://www.appveyor.com/docs/build-configuration#secure-variables
+ matrix:
+ # create multiple jobs to execute a set of tox runs on each; this is to workaround having
+ # builds timing out in AppVeyor
+ - TOXENV: "linting,py26,py27,py33,py34,py35,pypy"
+ - TOXENV: "py27-pexpect,py27-xdist,py27-trial,py35-pexpect,py35-xdist,py35-trial"
+ - TOXENV: "py27-nobyte,doctesting,py27-cxfreeze"
+
install:
- echo Installed Pythons
- dir c:\Python*
diff --git a/doc/en/_templates/layout.html b/doc/en/_templates/layout.html
index 0ce480be3..2fc8e2a7f 100644
--- a/doc/en/_templates/layout.html
+++ b/doc/en/_templates/layout.html
@@ -1,19 +1,5 @@
{% extends "!layout.html" %}
{% block header %}
-
{{super()}}
{% endblock %}
{% block footer %}
diff --git a/doc/en/_templates/links.html b/doc/en/_templates/links.html
index 200258e16..56486a750 100644
--- a/doc/en/_templates/links.html
+++ b/doc/en/_templates/links.html
@@ -1,10 +1,5 @@
Useful Links
- -
-
- Sprint funding campaign
-
-
- The pytest Website
- Contribution Guide
- pytest @ PyPI
diff --git a/doc/en/announce/sprint2016.rst b/doc/en/announce/sprint2016.rst
index 86dd499c9..16e0f0e37 100644
--- a/doc/en/announce/sprint2016.rst
+++ b/doc/en/announce/sprint2016.rst
@@ -4,9 +4,9 @@ python testing sprint June 20th-26th 2016
.. image:: ../img/freiburg2.jpg
:width: 400
-The pytest core group is heading towards the biggest sprint
-in its history, to take place in the black forest town Freiburg
-in Germany. As of February 2016 we have started a `funding
+The pytest core group held the biggest sprint
+in its history in June 2016, taking place in the black forest town Freiburg
+in Germany. In February 2016 we started a `funding
campaign on Indiegogo to cover expenses
`_ The page also mentions
some preliminary topics:
@@ -35,73 +35,32 @@ some preliminary topics:
Participants
--------------
-Here are preliminary participants who said they are likely to come,
-given some expenses funding::
-
- Anatoly Bubenkoff, Netherlands
+Over 20 participants took part from 4 continents, including employees
+from Splunk, Personalkollen, Cobe.io, FanDuel and Dolby. Some newcomers
+mixed with developers who have worked on pytest since its beginning, and
+of course everyone in between.
Ana Ribeiro, Brazil
- Andreas Pelme, Personalkollen, Sweden
- Anthony Wang, Splunk, US
- Brianna Laugher, Australia
- Bruno Oliveira, Brazil
- Danielle Jenkins, Splunk, US
- Dave Hunt, UK
- Florian Bruhin, Switzerland
- Floris Bruynooghe, Cobe.io, UK
- Holger Krekel, merlinux, Germany
- Oliver Bestwalter, Avira, Germany
- Omar Kohl, Germany
- Raphael Pierzina, FanDuel, UK
Ronny Pfannschmidt, Germany
- Tom Viner, UK
-
-
-
-Other contributors and experienced newcomers are invited to join as well
-but please send a mail to the pytest-dev mailing list if you intend to
-do so somewhat soon, also how much funding you need if so. And if you
-are working for a company and using pytest heavily you are welcome to
-join and we encourage your company to provide some funding for the
-sprint. They may see it, and rightfully so, as a very cheap and deep
-training which brings you together with the experts in the field :)
Sprint organisation, schedule
-------------------------------
-tentative schedule:
+People arrived in Freiburg on the 19th, with sprint development taking
+place on 20th, 21st, 22nd, 24th and 25th. On the 23rd we took a break
+day for some hot hiking in the Black Forest.
-- 19/20th arrival in Freiburg
-- 20th social get together, initial hacking
-- 21/22th full sprint days
-- 23rd break day, hiking
-- 24/25th full sprint days
-- 26th departure
+Sprint activity was organised heavily around pairing, with plenty of group
+discusssions to take advantage of the high bandwidth, and lightning talks
+as well.
-We might adjust according to weather to make sure that if
-we do some hiking or excursion we'll have good weather.
-Freiburg is one of the sunniest places in Germany so
-it shouldn't be too much of a constraint.
-
-
-Accomodation
-----------------
-
-We'll see to arrange for renting a flat with multiple
-beds/rooms. Hotels are usually below 100 per night.
-The earlier we book the better.
Money / funding
---------------
-The Indiegogo campaign asks for 11000 USD which should cover
-the costs for flights and accomodation, renting a sprint place
-and maybe a bit of food as well.
-If your organisation wants to support the sprint but prefers
-to give money according to an invoice, get in contact with
-holger at http://merlinux.eu who can invoice your organisation
-properly.
+The Indiegogo campaign aimed for 11000 USD and in the end raised over
+12000, to reimburse travel costs, pay for a sprint venue and catering.
-If we have excess money we'll use for further sprint/travel
-funding for pytest/tox contributors.
+Excess money is reserved for further sprint/travel funding for pytest/tox
+contributors.
diff --git a/doc/en/fixture.rst b/doc/en/fixture.rst
index b40c3943a..2077f2db0 100644
--- a/doc/en/fixture.rst
+++ b/doc/en/fixture.rst
@@ -823,6 +823,10 @@ If we run it, we get two passing tests::
Here is how autouse fixtures work in other scopes:
+- autouse fixtures obey the ``scope=`` keyword-argument: if an autouse fixture
+ has ``scope='session'`` it will only be run once, no matter where it is
+ defined. ``scope='class'`` means it will be run once per class, etc.
+
- if an autouse fixture is defined in a test module, all its test
functions automatically use it.
diff --git a/doc/en/genapi.py b/doc/en/genapi.py
index f8cdda6cf..89ddc8731 100644
--- a/doc/en/genapi.py
+++ b/doc/en/genapi.py
@@ -32,7 +32,7 @@ class Writer:
def pytest_funcarg__a(request):
with Writer("request") as writer:
- writer.docmethod(request.getfuncargvalue)
+ writer.docmethod(request.getfixturevalue)
writer.docmethod(request.cached_setup)
writer.docmethod(request.addfinalizer)
writer.docmethod(request.applymarker)
diff --git a/doc/en/talks.rst b/doc/en/talks.rst
index 7a5221845..1572832f0 100644
--- a/doc/en/talks.rst
+++ b/doc/en/talks.rst
@@ -11,9 +11,6 @@ Talks and Tutorials
Talks and blog postings
---------------------------------------------
-.. _`tutorial1 repository`: http://bitbucket.org/pytest-dev/pytest-tutorial1/
-.. _`pycon 2010 tutorial PDF`: http://bitbucket.org/pytest-dev/pytest-tutorial1/raw/tip/pytest-basic.pdf
-
- `pytest - Rapid Simple Testing, Florian Bruhin, Swiss Python Summit 2016
`_.
@@ -52,12 +49,14 @@ Talks and blog postings
- `pytest introduction from Brian Okken (January 2013)
`_
-- `monkey patching done right`_ (blog post, consult `monkeypatch
- plugin`_ for up-to-date API)
+- pycon australia 2012 pytest talk from Brianna Laugher (`video `_, `slides `_, `code `_)
+- `pycon 2012 US talk video from Holger Krekel `_
+
+- `monkey patching done right`_ (blog post, consult `monkeypatch plugin`_ for up-to-date API)
Test parametrization:
-- `generating parametrized tests with funcargs`_ (uses deprecated ``addcall()`` API.
+- `generating parametrized tests with fixtures`_.
- `test generators and cached setup`_
- `parametrizing tests, generalized`_ (blog post)
- `putting test-hooks into local or global plugins`_ (blog post)
@@ -78,39 +77,17 @@ Plugin specific examples:
- `many examples in the docs for plugins`_
.. _`skipping slow tests by default in pytest`: http://bruynooghe.blogspot.com/2009/12/skipping-slow-test-by-default-in-pytest.html
-.. _`many examples in the docs for plugins`: plugin/index.html
-.. _`monkeypatch plugin`: plugin/monkeypatch.html
-.. _`application setup in test functions with funcargs`: funcargs.html#appsetup
+.. _`many examples in the docs for plugins`: plugins.html
+.. _`monkeypatch plugin`: monkeypatch.html
+.. _`application setup in test functions with fixtures`: fixture.html#interdependent-fixtures
.. _`simultaneously test your code on all platforms`: http://tetamap.wordpress.com/2009/03/23/new-simultanously-test-your-code-on-all-platforms/
.. _`monkey patching done right`: http://tetamap.wordpress.com/2009/03/03/monkeypatching-in-unit-tests-done-right/
.. _`putting test-hooks into local or global plugins`: http://tetamap.wordpress.com/2009/05/14/putting-test-hooks-into-local-and-global-plugins/
.. _`parametrizing tests, generalized`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/
-.. _`generating parametrized tests with funcargs`: funcargs.html#test-generators
+.. _`generating parametrized tests with fixtures`: parametrize.html#test-generators
.. _`test generators and cached setup`: http://bruynooghe.blogspot.com/2010/06/pytest-test-generators-and-cached-setup.html
-Older conference talks and tutorials
-----------------------------------------
-- `pycon australia 2012 pytest talk from Brianna Laugher
- `_ (`video `_, `slides `_, `code `_)
-- `pycon 2012 US talk video from Holger Krekel `_
-- `pycon 2010 tutorial PDF`_ and `tutorial1 repository`_
-- `ep2009-rapidtesting.pdf`_ tutorial slides (July 2009):
- - testing terminology
- - basic pytest usage, file system layout
- - test function arguments (funcargs_) and test fixtures
- - existing plugins
- - distributed testing
-- `ep2009-pytest.pdf`_ 60 minute pytest talk, highlighting unique features and a roadmap (July 2009)
-
-- `pycon2009-pytest-introduction.zip`_ slides and files, extended version of pytest basic introduction, discusses more options, also introduces old-style xUnit setup, looponfailing and other features.
-
-- `pycon2009-pytest-advanced.pdf`_ contain a slightly older version of funcargs and distributed testing, compared to the EuroPython 2009 slides.
-
-.. _`ep2009-rapidtesting.pdf`: http://codespeak.net/download/py/ep2009-rapidtesting.pdf
-.. _`ep2009-pytest.pdf`: http://codespeak.net/download/py/ep2009-pytest.pdf
-.. _`pycon2009-pytest-introduction.zip`: http://codespeak.net/download/py/pycon2009-pytest-introduction.zip
-.. _`pycon2009-pytest-advanced.pdf`: http://codespeak.net/download/py/pycon2009-pytest-advanced.pdf
diff --git a/doc/en/usage.rst b/doc/en/usage.rst
index 06cc18969..c2a269a15 100644
--- a/doc/en/usage.rst
+++ b/doc/en/usage.rst
@@ -79,7 +79,7 @@ than ``--tb=long``). It also ensures that a stack trace is printed on
**KeyboardInterrrupt** (Ctrl+C).
This is very useful if the tests are taking too long and you interrupt them
with Ctrl+C to find out where the tests are *hanging*. By default no output
-will be shown (because KeyboardInterrupt is catched by pytest). By using this
+will be shown (because KeyboardInterrupt is caught by pytest). By using this
option you make sure a trace is shown.
Dropping to PDB_ (Python Debugger) on failures
diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py
index 59756645a..48696b5b0 100644
--- a/testing/code/test_excinfo.py
+++ b/testing/code/test_excinfo.py
@@ -384,7 +384,7 @@ class TestFormattedExcinfo:
def pytest_funcarg__importasmod(self, request):
def importasmod(source):
source = _pytest._code.Source(source)
- tmpdir = request.getfuncargvalue("tmpdir")
+ tmpdir = request.getfixturevalue("tmpdir")
modpath = tmpdir.join("mod.py")
tmpdir.ensure("__init__.py")
modpath.write(source)
diff --git a/testing/cx_freeze/runtests_setup.py b/testing/cx_freeze/runtests_setup.py
index ee11d8854..6d7e43750 100644
--- a/testing/cx_freeze/runtests_setup.py
+++ b/testing/cx_freeze/runtests_setup.py
@@ -8,7 +8,7 @@ if __name__ == '__main__':
setup(
name="runtests",
version="0.1",
- description="exemple of how embedding pytest into an executable using cx_freeze",
+ description="example of how embedding pytest into an executable using cx_freeze",
executables=[Executable("runtests_script.py")],
options={"build_exe": {'includes': pytest.freeze_includes()}},
)
diff --git a/testing/python/fixture.py b/testing/python/fixture.py
index 83ec29cb5..a4a8ab46c 100644
--- a/testing/python/fixture.py
+++ b/testing/python/fixture.py
@@ -93,12 +93,12 @@ class TestFillFixtures:
sub1.join("conftest.py").write(_pytest._code.Source("""
import pytest
def pytest_funcarg__arg1(request):
- pytest.raises(Exception, "request.getfuncargvalue('arg2')")
+ pytest.raises(Exception, "request.getfixturevalue('arg2')")
"""))
sub2.join("conftest.py").write(_pytest._code.Source("""
import pytest
def pytest_funcarg__arg2(request):
- pytest.raises(Exception, "request.getfuncargvalue('arg1')")
+ pytest.raises(Exception, "request.getfixturevalue('arg1')")
"""))
sub1.join("test_in_sub1.py").write("def test_1(arg1): pass")
@@ -435,21 +435,23 @@ class TestRequestBasic:
assert len(arg2fixturedefs) == 1
assert arg2fixturedefs[0].__name__ == "pytest_funcarg__something"
- def test_getfuncargvalue_recursive(self, testdir):
+ def test_getfixturevalue_recursive(self, testdir):
testdir.makeconftest("""
def pytest_funcarg__something(request):
return 1
""")
testdir.makepyfile("""
def pytest_funcarg__something(request):
- return request.getfuncargvalue("something") + 1
+ return request.getfixturevalue("something") + 1
def test_func(something):
assert something == 2
""")
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1)
- def test_getfuncargvalue(self, testdir):
+ @pytest.mark.parametrize(
+ 'getfixmethod', ('getfixturevalue', 'getfuncargvalue'))
+ def test_getfixturevalue(self, testdir, getfixmethod):
item = testdir.getitem("""
l = [2]
def pytest_funcarg__something(request): return 1
@@ -458,14 +460,15 @@ class TestRequestBasic:
def test_func(something): pass
""")
req = item._request
- pytest.raises(FixtureLookupError, req.getfuncargvalue, "notexists")
- val = req.getfuncargvalue("something")
+ fixture_fetcher = getattr(req, getfixmethod)
+ pytest.raises(FixtureLookupError, fixture_fetcher, "notexists")
+ val = fixture_fetcher("something")
assert val == 1
- val = req.getfuncargvalue("something")
+ val = fixture_fetcher("something")
assert val == 1
- val2 = req.getfuncargvalue("other")
+ val2 = fixture_fetcher("other")
assert val2 == 2
- val2 = req.getfuncargvalue("other") # see about caching
+ val2 = fixture_fetcher("other") # see about caching
assert val2 == 2
pytest._fillfuncargs(item)
assert item.funcargs["something"] == 1
@@ -812,10 +815,10 @@ class TestRequestCachedSetup:
"*1 passed*"
])
- def test_request_cached_setup_getfuncargvalue(self, testdir):
+ def test_request_cached_setup_getfixturevalue(self, testdir):
testdir.makepyfile("""
def pytest_funcarg__arg1(request):
- arg1 = request.getfuncargvalue("arg2")
+ arg1 = request.getfixturevalue("arg2")
return request.cached_setup(lambda: arg1 + 1)
def pytest_funcarg__arg2(request):
return request.cached_setup(lambda: 10)
@@ -1118,7 +1121,7 @@ class TestFixtureUsages:
class TestFixtureManagerParseFactories:
def pytest_funcarg__testdir(self, request):
- testdir = request.getfuncargvalue("testdir")
+ testdir = request.getfixturevalue("testdir")
testdir.makeconftest("""
def pytest_funcarg__hello(request):
return "conftest"
@@ -1804,9 +1807,9 @@ class TestFixtureMarker:
reprec.assertoutcome(passed=4)
@pytest.mark.parametrize("method", [
- 'request.getfuncargvalue("arg")',
+ 'request.getfixturevalue("arg")',
'request.cached_setup(lambda: None, scope="function")',
- ], ids=["getfuncargvalue", "cached_setup"])
+ ], ids=["getfixturevalue", "cached_setup"])
def test_scope_mismatch_various(self, testdir, method):
testdir.makeconftest("""
import pytest
@@ -2718,6 +2721,7 @@ class TestContextManagerFixtureFuncs:
""".format(flavor=flavor))
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines("*mew*")
+
class TestParameterizedSubRequest:
def test_call_from_fixture(self, testdir):
testfile = testdir.makepyfile("""
@@ -2729,7 +2733,7 @@ class TestParameterizedSubRequest:
@pytest.fixture
def get_named_fixture(request):
- return request.getfuncargvalue('fix_with_param')
+ return request.getfixturevalue('fix_with_param')
def test_foo(request, get_named_fixture):
pass
@@ -2754,7 +2758,7 @@ class TestParameterizedSubRequest:
return request.param
def test_foo(request):
- request.getfuncargvalue('fix_with_param')
+ request.getfixturevalue('fix_with_param')
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines("""
@@ -2778,7 +2782,7 @@ class TestParameterizedSubRequest:
testfile = testdir.makepyfile("""
def test_foo(request):
- request.getfuncargvalue('fix_with_param')
+ request.getfixturevalue('fix_with_param')
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines("""
@@ -2808,7 +2812,7 @@ class TestParameterizedSubRequest:
from fix import fix_with_param
def test_foo(request):
- request.getfuncargvalue('fix_with_param')
+ request.getfixturevalue('fix_with_param')
"""))
tests_dir.chdir()
@@ -2823,3 +2827,7 @@ class TestParameterizedSubRequest:
E*{1}:5
*1 failed*
""".format(fixfile.strpath, testfile.basename))
+
+
+def test_getfuncargvalue_is_deprecated(request):
+ pytest.deprecated_call(request.getfuncargvalue, 'tmpdir')
diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py
index 0c07dca36..046e1371f 100644
--- a/testing/python/metafunc.py
+++ b/testing/python/metafunc.py
@@ -749,14 +749,14 @@ class TestMetafuncFunctional:
"*4 failed*",
])
- def test_parametrize_and_inner_getfuncargvalue(self, testdir):
+ def test_parametrize_and_inner_getfixturevalue(self, testdir):
p = testdir.makepyfile("""
def pytest_generate_tests(metafunc):
metafunc.parametrize("arg1", [1], indirect=True)
metafunc.parametrize("arg2", [10], indirect=True)
def pytest_funcarg__arg1(request):
- x = request.getfuncargvalue("arg2")
+ x = request.getfixturevalue("arg2")
return x + request.param
def pytest_funcarg__arg2(request):
diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py
index 8d16bfc66..5f8127af9 100644
--- a/testing/test_assertrewrite.py
+++ b/testing/test_assertrewrite.py
@@ -213,10 +213,12 @@ class TestAssertionRewrite:
return False
def f():
assert x() and x()
- assert getmsg(f, {"x" : x}) == "assert (x())"
+ assert getmsg(f, {"x" : x}) == """assert (False)
+ + where False = x()"""
def f():
assert False or x()
- assert getmsg(f, {"x" : x}) == "assert (False or x())"
+ assert getmsg(f, {"x" : x}) == """assert (False or False)
+ + where False = x()"""
def f():
assert 1 in {} and 2 in {}
assert getmsg(f) == "assert (1 in {})"
@@ -299,27 +301,34 @@ class TestAssertionRewrite:
ns = {"g" : g}
def f():
assert g()
- assert getmsg(f, ns) == """assert g()"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g()"""
def f():
assert g(1)
- assert getmsg(f, ns) == """assert g(1)"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g(1)"""
def f():
assert g(1, 2)
- assert getmsg(f, ns) == """assert g(1, 2)"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g(1, 2)"""
def f():
assert g(1, g=42)
- assert getmsg(f, ns) == """assert g(1, g=42)"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g(1, g=42)"""
def f():
assert g(1, 3, g=23)
- assert getmsg(f, ns) == """assert g(1, 3, g=23)"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g(1, 3, g=23)"""
def f():
seq = [1, 2, 3]
assert g(*seq)
- assert getmsg(f, ns) == """assert g(*[1, 2, 3])"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g(*[1, 2, 3])"""
def f():
x = "a"
assert g(**{x : 2})
- assert getmsg(f, ns) == """assert g(**{'a': 2})"""
+ assert getmsg(f, ns) == """assert False
+ + where False = g(**{'a': 2})"""
def test_attribute(self):
class X(object):
@@ -332,7 +341,8 @@ class TestAssertionRewrite:
def f():
x.a = False # noqa
assert x.a # noqa
- assert getmsg(f, ns) == """assert x.a"""
+ assert getmsg(f, ns) == """assert False
+ + where False = x.a"""
def test_comparisons(self):
def f():
@@ -746,5 +756,28 @@ def test_issue731(testdir):
assert 'unbalanced braces' not in result.stdout.str()
-def test_collapse_false_unbalanced_braces():
- util._collapse_false('some text{ False\n{False = some more text\n}')
+class TestIssue925():
+ def test_simple_case(self, testdir):
+ testdir.makepyfile("""
+ def test_ternary_display():
+ assert (False == False) == False
+ """)
+ result = testdir.runpytest()
+ result.stdout.fnmatch_lines('*E*assert (False == False) == False')
+
+ def test_long_case(self, testdir):
+ testdir.makepyfile("""
+ def test_ternary_display():
+ assert False == (False == True) == True
+ """)
+ result = testdir.runpytest()
+ result.stdout.fnmatch_lines('*E*assert (False == True) == True')
+
+ def test_many_brackets(self, testdir):
+ testdir.makepyfile("""
+ def test_ternary_display():
+ assert True == ((False == True) == True)
+ """)
+ result = testdir.runpytest()
+ result.stdout.fnmatch_lines('*E*assert True == ((False == True) == True)')
+
diff --git a/testing/test_config.py b/testing/test_config.py
index fe550dbdd..bb686c3b0 100644
--- a/testing/test_config.py
+++ b/testing/test_config.py
@@ -391,6 +391,23 @@ def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
plugin = config.pluginmanager.getplugin("mytestplugin")
assert plugin.x == 42
+
+def test_setuptools_importerror_issue1479(testdir, monkeypatch):
+ pkg_resources = pytest.importorskip("pkg_resources")
+ def my_iter(name):
+ assert name == "pytest11"
+ class EntryPoint:
+ name = "mytestplugin"
+ dist = None
+ def load(self):
+ raise ImportError("Don't hide me!")
+ return iter([EntryPoint()])
+
+ monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
+ with pytest.raises(ImportError):
+ testdir.parseconfig()
+
+
def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch):
pkg_resources = pytest.importorskip("pkg_resources")
def my_iter(name):
diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py
index afec1114c..cc9aa23cd 100644
--- a/testing/test_parseopt.py
+++ b/testing/test_parseopt.py
@@ -29,6 +29,9 @@ class TestParser:
assert argument.dest == 'test'
argument = parseopt.Argument('-t', '--test', dest='abc')
assert argument.dest == 'abc'
+ assert str(argument) == (
+ "Argument(_short_opts: ['-t'], _long_opts: ['--test'], dest: 'abc')"
+ )
def test_argument_type(self):
argument = parseopt.Argument('-t', dest='abc', type='int')
diff --git a/testing/test_pdb.py b/testing/test_pdb.py
index eeddcf0ae..44163a204 100644
--- a/testing/test_pdb.py
+++ b/testing/test_pdb.py
@@ -13,11 +13,11 @@ def runpdb_and_get_report(testdir, source):
class TestPDB:
def pytest_funcarg__pdblist(self, request):
- monkeypatch = request.getfuncargvalue("monkeypatch")
+ monkeypatch = request.getfixturevalue("monkeypatch")
pdblist = []
def mypdb(*args):
pdblist.append(args)
- plugin = request.config.pluginmanager.getplugin('pdb')
+ plugin = request.config.pluginmanager.getplugin('debugging')
monkeypatch.setattr(plugin, 'post_mortem', mypdb)
return pdblist
diff --git a/tox.ini b/tox.ini
index 957849559..e2ccea837 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,7 @@
[tox]
minversion=2.0
distshare={homedir}/.tox/distshare
+# make sure to update enviroment list on appveyor.yml
envlist=
linting,py26,py27,py33,py34,py35,pypy,
{py27,py35}-{pexpect,xdist,trial},