diff -Nru pytest-3.0.5/AUTHORS pytest-3.0.6/AUTHORS --- pytest-3.0.5/AUTHORS 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/AUTHORS 2017-01-20 16:40:36.000000000 +0000 @@ -71,6 +71,7 @@ Jason R. Coombs Javier Domingo Cansino Javier Romero +Jeff Widman John Towler Jon Sonesen Jordan Guymon @@ -82,6 +83,7 @@ Kevin Cox Lee Kamentsky Lev Maximov +Loic Esteve Lukas Bednar Luke Murphy Maciek Fijalkowski @@ -139,3 +141,4 @@ Vasily Kuznetsov Wouter van Ackooy Xuecong Liao +Eli Boyarski diff -Nru pytest-3.0.5/CHANGELOG.rst pytest-3.0.6/CHANGELOG.rst --- pytest-3.0.5/CHANGELOG.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/CHANGELOG.rst 2017-01-22 17:44:30.000000000 +0000 @@ -1,5 +1,52 @@ -3.0.5 -===== +3.0.6 (2017-01-29) +======================= + +* pytest no longer generates ``PendingDeprecationWarning`` from its own operations, which was introduced by mistake in version ``3.0.5`` (`#2118`_). + Thanks to `@nicoddemus`_ for the report and `@RonnyPfannschmidt`_ for the PR. + + +* pytest no longer recognizes coroutine functions as yield tests (`#2129`_). + Thanks to `@malinoff`_ for the PR. + +* Plugins loaded by the ``PYTEST_PLUGINS`` environment variable are now automatically + considered for assertion rewriting (`#2185`_). + Thanks `@nicoddemus`_ for the PR. + +* Improve error message when pytest.warns fails (`#2150`_). The type(s) of the + expected warnings and the list of caught warnings is added to the + error message. Thanks `@lesteve`_ for the PR. + +* Fix ``pytester`` internal plugin to work correctly with latest versions of + ``zope.interface`` (`#1989`_). Thanks `@nicoddemus`_ for the PR. + +* Assert statements of the ``pytester`` plugin again benefit from assertion rewriting (`#1920`_). + Thanks `@RonnyPfannschmidt`_ for the report and `@nicoddemus`_ for the PR. + +* Specifying tests with colons like ``test_foo.py::test_bar`` for tests in + subdirectories with ini configuration files now uses the correct ini file + (`#2148`_). Thanks `@pelme`_. + +* Fail ``testdir.runpytest().assert_outcomes()`` explicitly if the pytest + terminal output it relies on is missing. Thanks to `@eli-b`_ for the PR. + + +.. _@lesteve: https://github.com/lesteve +.. _@malinoff: https://github.com/malinoff +.. _@pelme: https://github.com/pelme +.. _@eli-b: https://github.com/eli-b + +.. _#2118: https://github.com/pytest-dev/pytest/issues/2118 + +.. _#1989: https://github.com/pytest-dev/pytest/issues/1989 +.. _#1920: https://github.com/pytest-dev/pytest/issues/1920 +.. _#2129: https://github.com/pytest-dev/pytest/issues/2129 +.. _#2148: https://github.com/pytest-dev/pytest/issues/2148 +.. _#2150: https://github.com/pytest-dev/pytest/issues/2150 +.. _#2185: https://github.com/pytest-dev/pytest/issues/2185 + + +3.0.5 (2016-12-05) +================== * Add warning when not passing ``option=value`` correctly to ``-o/--override-ini`` (`#2105`_). Also improved the help documentation. Thanks to `@mbukatov`_ for the report and @@ -66,8 +113,8 @@ .. _#687: https://github.com/pytest-dev/pytest/issues/687 -3.0.4 -===== +3.0.4 (2016-11-09) +================== * Import errors when collecting test modules now display the full traceback (`#1976`_). Thanks `@cwitty`_ for the report and `@nicoddemus`_ for the PR. @@ -120,8 +167,8 @@ .. _#1649: https://github.com/pytest-dev/pytest/issues/1649 -3.0.3 -===== +3.0.3 (2016-09-28) +================== * The ``ids`` argument to ``parametrize`` again accepts ``unicode`` strings in Python 2 (`#1905`_). @@ -159,8 +206,8 @@ -3.0.2 -===== +3.0.2 (2016-09-01) +================== * Improve error message when passing non-string ids to ``pytest.mark.parametrize`` (`#1857`_). Thanks `@okken`_ for the report and `@nicoddemus`_ for the PR. @@ -199,8 +246,8 @@ .. _#1898: https://github.com/pytest-dev/pytest/issues/1898 -3.0.1 -===== +3.0.1 (2016-08-23) +================== * Fix regression when ``importorskip`` is used at module level (`#1822`_). Thanks `@jaraco`_ and `@The-Compiler`_ for the report and `@nicoddemus`_ for the PR. @@ -225,8 +272,8 @@ .. _#1849: https://github.com/pytest-dev/pytest/issues/1849 -3.0.0 -===== +3.0.0 (2016-08-18) +================== **Incompatible changes** @@ -651,8 +698,8 @@ .. _@matthiasha: https://github.com/matthiasha -2.9.2 -===== +2.9.2 (2016-05-31) +================== **Bug Fixes** @@ -663,7 +710,7 @@ Thanks `@astraw38`_ for reporting the issue (`#1496`_) and `@tomviner`_ for PR the (`#1524`_). -* Fix win32 path issue when puttinging custom config file with absolute path +* Fix win32 path issue when putting custom config file with absolute path in ``pytest.main("-c your_absolute_path")``. * Fix maximum recursion depth detection when raised error class is not aware @@ -690,8 +737,8 @@ .. _@astraw38: https://github.com/astraw38 -2.9.1 -===== +2.9.1 (2016-03-17) +================== **Bug Fixes** @@ -726,8 +773,8 @@ .. _@asottile: https://github.com/asottile -2.9.0 -===== +2.9.0 (2016-02-29) +================== **New Features** @@ -847,13 +894,13 @@ .. _@pquentin: https://github.com/pquentin .. _@ioggstream: https://github.com/ioggstream -2.8.7 -===== +2.8.7 (2016-01-24) +================== - fix #1338: use predictable object resolution for monkeypatch -2.8.6 -===== +2.8.6 (2016-01-21) +================== - fix #1259: allow for double nodeids in junitxml, this was a regression failing plugins combinations @@ -884,8 +931,8 @@ Thanks Georgy Dyuldin for the PR. -2.8.5 -===== +2.8.5 (2015-12-11) +================== - fix #1243: fixed issue where class attributes injected during collection could break pytest. PR by Alexei Kozlenok, thanks Ronny Pfannschmidt and Bruno Oliveira for the review and help. @@ -898,8 +945,8 @@ Bruno Oliveira for the PR. -2.8.4 -===== +2.8.4 (2015-12-06) +================== - fix #1190: ``deprecated_call()`` now works when the deprecated function has been already called by another test in the same @@ -922,8 +969,8 @@ - a number of documentation modernizations wrt good practices. Thanks Bruno Oliveira for the PR. -2.8.3 -===== +2.8.3 (2015-11-18) +================== - fix #1169: add __name__ attribute to testcases in TestCaseFunction to support the @unittest.skip decorator on functions and methods. @@ -950,8 +997,8 @@ system integrity protection (thanks Florian) -2.8.2 -===== +2.8.2 (2015-10-07) +================== - fix #1085: proper handling of encoding errors when passing encoded byte strings to pytest.parametrize in Python 2. @@ -970,8 +1017,8 @@ Thanks Sergey B Kirpichev and Vital Kudzelka for contributing and Bruno Oliveira for the PR. -2.8.1 -===== +2.8.1 (2015-09-29) +================== - fix #1034: Add missing nodeid on pytest_logwarning call in addhook. Thanks Simon Gomizelj for the PR. @@ -995,7 +1042,7 @@ - (experimental) adapt more SEMVER style versioning and change meaning of master branch in git repo: "master" branch now keeps the bugfixes, changes - aimed for micro releases. "features" branch will only be be released + aimed for micro releases. "features" branch will only be released with minor or major pytest releases. - Fix issue #766 by removing documentation references to distutils. @@ -1017,8 +1064,8 @@ - fix issue 1029: transform errors when writing cache values into pytest-warnings -2.8.0 -===== +2.8.0 (2015-09-18) +================== - new ``--lf`` and ``-ff`` options to run only the last failing tests or "failing tests first" from the last run. This functionality is provided @@ -1129,7 +1176,7 @@ - new option ``--import-mode`` to allow to change test module importing behaviour to append to sys.path instead of prepending. This better allows - to run test modules against installated versions of a package even if the + to run test modules against installed versions of a package even if the package under test has the same import root. In this example:: testing/__init__.py @@ -1207,8 +1254,8 @@ properly used to discover ``rootdir`` and ``ini`` files. Thanks Peter Lauri for the report and Bruno Oliveira for the PR. -2.7.3 (compared to 2.7.2) -============================= +2.7.3 (2015-09-15) +================== - Allow 'dev', 'rc', or other non-integer version strings in ``importorskip``. Thanks to Eric Hunsberger for the PR. @@ -1250,8 +1297,8 @@ directories created by this fixture (defaults to $TEMP/pytest-$USER). Thanks Bruno Oliveira for the PR. -2.7.2 (compared to 2.7.1) -============================= +2.7.2 (2015-06-23) +================== - fix issue767: pytest.raises value attribute does not contain the exception instance on Python 2.6. Thanks Eric Siegerman for providing the test @@ -1279,15 +1326,15 @@ which has a refined algorithm for traceback generation. -2.7.1 (compared to 2.7.0) -============================= +2.7.1 (2015-05-19) +================== - fix issue731: do not get confused by the braces which may be present and unbalanced in an object's repr while collapsing False explanations. Thanks Carl Meyer for the report and test case. - fix issue553: properly handling inspect.getsourcelines failures in - FixtureLookupError which would lead to to an internal error, + FixtureLookupError which would lead to an internal error, obfuscating the original problem. Thanks talljosh for initial diagnose/patch and Bruno Oliveira for final patch. @@ -1312,8 +1359,8 @@ - reintroduced _pytest fixture of the pytester plugin which is used at least by pytest-xdist. -2.7.0 (compared to 2.6.4) -============================= +2.7.0 (2015-03-26) +================== - fix issue435: make reload() work when assert rewriting is active. Thanks Daniel Hahler. @@ -1382,8 +1429,8 @@ ``sys.last_traceback`` are set, so that a user can inspect the error via postmortem debugging (almarklein). -2.6.4 -===== +2.6.4 (2014-10-24) +================== - Improve assertion failure reporting on iterables, by using ndiff and pprint. @@ -1411,8 +1458,8 @@ - fix issue614: fixed pastebin support. -2.6.3 -===== +2.6.3 (2014-09-24) +================== - fix issue575: xunit-xml was reporting collection errors as failures instead of errors, thanks Oleg Sinyavskiy. @@ -1430,7 +1477,7 @@ - fix conftest related fixture visibility issue: when running with a CWD outside of a test package pytest would get fixture discovery wrong. - Thanks to Wolfgang Schnerring for figuring out a reproducable example. + Thanks to Wolfgang Schnerring for figuring out a reproducible example. - Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the timeout when interactively entering pdb). Thanks Wolfgang Schnerring. @@ -1438,8 +1485,8 @@ - check xfail/skip also with non-python function test items. Thanks Floris Bruynooghe. -2.6.2 -===== +2.6.2 (2014-09-05) +================== - Added function pytest.freeze_includes(), which makes it easy to embed pytest into executables using tools like cx_freeze. @@ -1467,8 +1514,8 @@ replace the py.test introspection message but are shown in addition to them. -2.6.1 -===== +2.6.1 (2014-08-07) +================== - No longer show line numbers in the --verbose output, the output is now purely the nodeid. The line number is still shown in failure reports. @@ -1604,8 +1651,8 @@ in monkeypatch plugin. Improves output in documentation. -2.5.2 -===== +2.5.2 (2014-01-29) +================== - fix issue409 -- better interoperate with cx_freeze by not trying to import from collections.abc which causes problems @@ -1629,11 +1676,11 @@ - fix issue429: comparing byte strings with non-ascii chars in assert expressions now work better. Thanks Floris Bruynooghe. -- make capfd/capsys.capture private, its unused and shouldnt be exposed +- make capfd/capsys.capture private, its unused and shouldn't be exposed -2.5.1 -===== +2.5.1 (2013-12-17) +================== - merge new documentation styling PR from Tobias Bieniek. @@ -1653,8 +1700,8 @@ -2.5.0 -===== +2.5.0 (2013-12-12) +================== - dropped python2.5 from automated release testing of pytest itself which means it's probably going to break soon (but still works @@ -1686,7 +1733,7 @@ to problems for more than >966 non-function scoped parameters). - fix issue290 - there is preliminary support now for parametrizing - with repeated same values (sometimes useful to to test if calling + with repeated same values (sometimes useful to test if calling a second time works as with the first time). - close issue240 - document precisely how pytest module importing @@ -1789,8 +1836,8 @@ - fix verbose reporting for @mock'd test functions -2.4.2 -===== +2.4.2 (2013-10-04) +================== - on Windows require colorama and a newer py lib so that py.io.TerminalWriter() now uses colorama instead of its own ctypes hacks. (fixes issue365) @@ -1820,8 +1867,8 @@ - add pluginmanager.do_configure(config) as a link to config.do_configure() for plugin-compatibility -2.4.1 -===== +2.4.1 (2013-10-02) +================== - When using parser.addoption() unicode arguments to the "type" keyword should also be converted to the respective types. @@ -1900,7 +1947,7 @@ - fix issue322: tearDownClass is not run if setUpClass failed. Thanks Mathieu Agopian for the initial fix. Also make all of pytest/nose - finalizer mimick the same generic behaviour: if a setupX exists and + finalizer mimic the same generic behaviour: if a setupX exists and fails, don't run teardownX. This internally introduces a new method "node.addfinalizer()" helper which can only be called during the setup phase of a node. @@ -2005,8 +2052,8 @@ ".section(title)" and ".line(msg)" methods to print extra information at the end of a test run. -2.3.5 -===== +2.3.5 (2013-04-30) +================== - fix issue169: respect --tb=style with setup/teardown errors as well. @@ -2019,11 +2066,11 @@ (thanks Adam Goucher) - Issue 265 - integrate nose setup/teardown with setupstate - so it doesnt try to teardown if it did not setup + so it doesn't try to teardown if it did not setup -- issue 271 - dont write junitxml on slave nodes +- issue 271 - don't write junitxml on slave nodes -- Issue 274 - dont try to show full doctest example +- Issue 274 - don't try to show full doctest example when doctest does not know the example location - issue 280 - disable assertion rewriting on buggy CPython 2.6.0 @@ -2059,7 +2106,7 @@ - allow to specify prefixes starting with "_" when customizing python_functions test discovery. (thanks Graham Horler) -- improve PYTEST_DEBUG tracing output by puting +- improve PYTEST_DEBUG tracing output by putting extra data on a new lines with additional indent - ensure OutcomeExceptions like skip/fail have initialized exception attributes @@ -2070,8 +2117,8 @@ - fix issue266 - accept unicode in MarkEvaluator expressions -2.3.4 -===== +2.3.4 (2012-11-20) +================== - yielded test functions will now have autouse-fixtures active but cannot accept fixtures as funcargs - it's anyway recommended to @@ -2090,8 +2137,8 @@ need to write as -k "TestClass and test_method" to match a certain method in a certain test class. -2.3.3 -===== +2.3.3 (2012-11-06) +================== - fix issue214 - parse modules that contain special objects like e. g. flask's request object which blows up on getattr access if no request @@ -2108,7 +2155,7 @@ - fix issue209 - reintroduce python2.4 support by depending on newer pylib which re-introduced statement-finding for pre-AST interpreters -- nose support: only call setup if its a callable, thanks Andrew +- nose support: only call setup if it's a callable, thanks Andrew Taumoefolau - fix issue219 - add py2.4-3.3 classifiers to TROVE list @@ -2122,8 +2169,8 @@ - fix issue127 - improve documentation for pytest_addoption() and add a ``config.getoption(name)`` helper function for consistency. -2.3.2 -===== +2.3.2 (2012-10-25) +================== - fix issue208 and fix issue29 use new py version to avoid long pauses when printing tracebacks in long modules @@ -2155,8 +2202,8 @@ - add tox.ini to pytest distribution so that ignore-dirs and others config bits are properly distributed for maintainers who run pytest-own tests -2.3.1 -===== +2.3.1 (2012-10-20) +================== - fix issue202 - fix regression: using "self" from fixture functions now works as expected (it's the same "self" instance that a test method @@ -2168,8 +2215,8 @@ - link to web pages from --markers output which provides help for pytest.mark.* usage. -2.3.0 -===== +2.3.0 (2012-10-19) +================== - fix issue202 - better automatic names for parametrized test functions - fix issue139 - introduce @pytest.fixture which allows direct scoping @@ -2204,7 +2251,7 @@ - fix issue128: show captured output when capsys/capfd are used -- fix issue179: propperly show the dependency chain of factories +- fix issue179: properly show the dependency chain of factories - pluginmanager.register(...) now raises ValueError if the plugin has been already registered or the name is taken @@ -2245,10 +2292,10 @@ - don't show deselected reason line if there is none - - py.test -vv will show all of assert comparisations instead of truncating + - py.test -vv will show all of assert comparisons instead of truncating -2.2.4 -===== +2.2.4 (2012-05-22) +================== - fix error message for rewritten assertions involving the % operator - fix issue 126: correctly match all invalid xml characters for junitxml @@ -2256,7 +2303,7 @@ - fix issue with unittest: now @unittest.expectedFailure markers should be processed correctly (you can also use @pytest.mark markers) - document integration with the extended distribute/setuptools test commands -- fix issue 140: propperly get the real functions +- fix issue 140: properly get the real functions of bound classmethods for setup/teardown_class - fix issue #141: switch from the deceased paste.pocoo.org to bpaste.net - fix issue #143: call unconfigure/sessionfinish always when @@ -2264,13 +2311,13 @@ - fix issue #144: better mangle test ids to junitxml classnames - upgrade distribute_setup.py to 0.6.27 -2.2.3 -===== +2.2.3 (2012-02-05) +================== -- fix uploaded package to only include neccesary files +- fix uploaded package to only include necessary files -2.2.2 -===== +2.2.2 (2012-02-05) +================== - fix issue101: wrong args to unittest.TestCase test function now produce better output @@ -2289,8 +2336,8 @@ - allow adding of attributes to test reports such that it also works with distributed testing (no upgrade of pytest-xdist needed) -2.2.1 -===== +2.2.1 (2011-12-16) +================== - fix issue99 (in pytest and py) internallerrors with resultlog now produce better output - fixed by normalizing pytest_internalerror @@ -2306,8 +2353,8 @@ - fix collection crash due to unknown-source collected items, thanks to Ralf Schmitt (fixed by depending on a more recent pylib) -2.2.0 -===== +2.2.0 (2011-11-18) +================== - fix issue90: introduce eager tearing down of test items so that teardown function are called earlier. @@ -2341,8 +2388,8 @@ - simplify junitxml output code by relying on py.xml - add support for skip properties on unittest classes and functions -2.1.3 -===== +2.1.3 (2011-10-18) +================== - fix issue79: assertion rewriting failed on some comparisons in boolops - correctly handle zero length arguments (a la pytest '') @@ -2350,8 +2397,8 @@ - fix issue75 / skipping test failure on jython - fix issue77 / Allow assertrepr_compare hook to apply to a subset of tests -2.1.2 -===== +2.1.2 (2011-09-24) +================== - fix assertion rewriting on files with windows newlines on some Python versions - refine test discovery by package/module name (--pyargs), thanks Florian Mayer @@ -2373,8 +2420,8 @@ - fix issue61: assertion rewriting on boolean operations with 3 or more operands - you can now build a man page with "cd doc ; make man" -2.1.0 -===== +2.1.0 (2011-07-09) +================== - fix issue53 call nosestyle setup functions with correct ordering - fix issue58 and issue59: new assertion code fixes @@ -2393,8 +2440,8 @@ - report KeyboardInterrupt even if interrupted during session startup - fix issue 35 - provide PDF doc version and download link from index page -2.0.3 -===== +2.0.3 (2011-05-11) +================== - fix issue38: nicer tracebacks on calls to hooks, particularly early configure/sessionstart ones @@ -2408,13 +2455,13 @@ - don't require zlib (and other libs) for genscript plugin without --genscript actually being used. -- speed up skips (by not doing a full traceback represenation +- speed up skips (by not doing a full traceback representation internally) - fix issue37: avoid invalid characters in junitxml's output -2.0.2 -===== +2.0.2 (2011-03-09) +================== - tackle issue32 - speed up test runs of very quick test functions by reducing the relative overhead @@ -2456,17 +2503,17 @@ this. - fixed typos in the docs (thanks Victor Garcia, Brianna Laugher) and particular - thanks to Laura Creighton who also revieved parts of the documentation. + thanks to Laura Creighton who also reviewed parts of the documentation. -- fix slighly wrong output of verbose progress reporting for classes +- fix slightly wrong output of verbose progress reporting for classes (thanks Amaury) - more precise (avoiding of) deprecation warnings for node.Class|Function accesses - avoid std unittest assertion helper code in tracebacks (thanks Ronny) -2.0.1 -===== +2.0.1 (2011-02-07) +================== - refine and unify initial capturing so that it works nicely even if the logging module is used on an early-loaded conftest.py @@ -2514,12 +2561,12 @@ parametraization remains the "pytest_generate_tests" mechanism, see the docs. -2.0.0 -===== +2.0.0 (2010-11-25) +================== - pytest-2.0 is now its own package and depends on pylib-2.0 - new ability: python -m pytest / python -m pytest.main ability -- new python invcation: pytest.main(args, plugins) to load +- new python invocation: pytest.main(args, plugins) to load some custom plugins early. - try harder to run unittest test suites in a more compatible manner by deferring setup/teardown semantics to the unittest package. @@ -2559,8 +2606,8 @@ - add ability to use "class" level for cached_setup helper - fix strangeness: mark.* objects are now immutable, create new instances -1.3.4 -===== +1.3.4 (2010-09-14) +================== - fix issue111: improve install documentation for windows - fix issue119: fix custom collectability of __init__.py as a module @@ -2568,8 +2615,8 @@ - fix issue115: unify internal exception passthrough/catching/GeneratorExit - fix issue118: new --tb=native for presenting cpython-standard exceptions -1.3.3 -===== +1.3.3 (2010-07-30) +================== - fix issue113: assertion representation problem with triple-quoted strings (and possibly other cases) @@ -2583,8 +2630,8 @@ (thanks Armin Ronacher for reporting) - remove trailing whitespace in all py/text distribution files -1.3.2 -===== +1.3.2 (2010-07-08) +================== **New features** @@ -2656,8 +2703,8 @@ - fix homedir detection on Windows - ship distribute_setup.py version 0.6.13 -1.3.1 -===== +1.3.1 (2010-05-25) +================== **New features** @@ -2726,8 +2773,8 @@ (and internally be more careful when presenting unexpected byte sequences) -1.3.0 -===== +1.3.0 (2010-05-05) +================== - deprecate --report option in favour of a new shorter and easier to remember -r option: it takes a string argument consisting of any @@ -2758,7 +2805,7 @@ - extend and refine xfail mechanism: ``@py.test.mark.xfail(run=False)`` do not run the decorated test ``@py.test.mark.xfail(reason="...")`` prints the reason string in xfail summaries - specifiying ``--runxfail`` on command line virtually ignores xfail markers + specifying ``--runxfail`` on command line virtually ignores xfail markers - expose (previously internal) commonly useful methods: py.io.get_terminal_with() -> return terminal width @@ -2791,8 +2838,8 @@ - added links to the new capturelog and coverage plugins -1.2.0 -===== +1.2.0 (2010-01-18) +================== - refined usage and options for "py.cleanup":: @@ -2830,8 +2877,8 @@ - fix plugin links -1.1.1 -===== +1.1.1 (2009-11-24) +================== - moved dist/looponfailing from py.test core into a new separately released pytest-xdist plugin. @@ -2914,8 +2961,8 @@ - fix docs, fix internal bin/ script generation -1.1.0 -===== +1.1.0 (2009-11-05) +================== - introduce automatic plugin registration via 'pytest11' entrypoints via setuptools' pkg_resources.iter_entry_points @@ -2983,7 +3030,7 @@ * add the ability to specify a path for py.lookup to search in -* fix a funcarg cached_setup bug probably only occuring +* fix a funcarg cached_setup bug probably only occurring in distributed testing and "module" scope with teardown. * many fixes and changes for making the code base python3 compatible, @@ -3018,16 +3065,16 @@ * simplified internal localpath implementation -1.0.2 -===== +1.0.2 (2009-08-27) +================== * fixing packaging issues, triggered by fedora redhat packaging, also added doc, examples and contrib dirs to the tarball. * added a documentation link to the new django plugin. -1.0.1 -===== +1.0.1 (2009-08-19) +================== * added a 'pytest_nose' plugin which handles nose.SkipTest, nose-style function/method/generator setup/teardown and @@ -3060,14 +3107,14 @@ * simplified multicall mechanism and plugin architecture, renamed some internal methods and argnames -1.0.0 -===== +1.0.0 (2009-08-04) +================== * more terse reporting try to show filesystem path relatively to current dir * improve xfail output a bit -1.0.0b9 -======= +1.0.0b9 (2009-07-31) +==================== * cleanly handle and report final teardown of test setup @@ -3100,8 +3147,8 @@ * item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr) -1.0.0b8 -======= +1.0.0b8 (2009-07-22) +==================== * pytest_unittest-plugin is now enabled by default @@ -3154,8 +3201,8 @@ * make __name__ == "__channelexec__" for remote_exec code -1.0.0b3 -======= +1.0.0b3 (2009-06-19) +==================== * plugin classes are removed: one now defines hooks directly in conftest.py or global pytest_*.py @@ -3249,10 +3296,10 @@ * fixed issue with 2.5 type representations in py.test [45483, 45484] * made that internal reporting issues displaying is done atomically in py.test [45518] -* made that non-existing files are igored by the py.lookup script [45519] +* made that non-existing files are ignored by the py.lookup script [45519] * improved exception name creation in py.test [45535] * made that less threads are used in execnet [merge in 45539] -* removed lock required for atomical reporting issue displaying in py.test +* removed lock required for atomic reporting issue displaying in py.test [45545] * removed globals from execnet [45541, 45547] * refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit diff -Nru pytest-3.0.5/debian/changelog pytest-3.0.6/debian/changelog --- pytest-3.0.5/debian/changelog 2016-12-14 19:43:52.000000000 +0000 +++ pytest-3.0.6/debian/changelog 2017-01-26 17:05:43.000000000 +0000 @@ -1,3 +1,10 @@ +pytest (3.0.6-1) unstable; urgency=medium + + * New upstream release. + * debian/control: Fix B-C on python3-twisted. + + -- Sebastian Ramacher Thu, 26 Jan 2017 18:05:43 +0100 + pytest (3.0.5-2) unstable; urgency=medium * debian/*: Install pytest entrypoints since logilab-common removed them. diff -Nru pytest-3.0.5/debian/control pytest-3.0.6/debian/control --- pytest-3.0.5/debian/control 2016-12-14 19:43:28.000000000 +0000 +++ pytest-3.0.6/debian/control 2017-01-26 17:05:15.000000000 +0000 @@ -30,7 +30,7 @@ python3-setuptools Build-Conflicts: python-twisted-core, - python3-twisted-core + python3-twisted X-Python-Version: >= 2.6 X-Python3-Version: >= 3.3 Standards-Version: 3.9.8 diff -Nru pytest-3.0.5/debian/.git-dpm pytest-3.0.6/debian/.git-dpm --- pytest-3.0.5/debian/.git-dpm 2016-12-09 16:48:37.000000000 +0000 +++ pytest-3.0.6/debian/.git-dpm 2017-01-26 08:09:35.000000000 +0000 @@ -1,11 +1,11 @@ # see git-dpm(1) from git-dpm package -87bb9d9c26d539317d01c9bebc44c0366bed878c -87bb9d9c26d539317d01c9bebc44c0366bed878c -67133214465533c29639c0c0aad1a4d8a7b4dab6 -67133214465533c29639c0c0aad1a4d8a7b4dab6 -pytest_3.0.5.orig.tar.gz -000879c6b0879245cc4e10492f265c66f95ce376 -740656 +0522ce0b62c58959b4e733dd686706e62fba6073 +0522ce0b62c58959b4e733dd686706e62fba6073 +094551e172d9415ad7c68b3d0aa2e63b76e920bc +094551e172d9415ad7c68b3d0aa2e63b76e920bc +pytest_3.0.6.orig.tar.gz +16a43b3e6908ccdff64079a82b9c065cc5ff3a33 +748748 debianTag="debian/%e%v" patchedTag="patched/%e%v" upstreamTag="upstream/%e%u" diff -Nru pytest-3.0.5/debian/patches/intersphinx.patch pytest-3.0.6/debian/patches/intersphinx.patch --- pytest-3.0.5/debian/patches/intersphinx.patch 2016-12-09 16:48:37.000000000 +0000 +++ pytest-3.0.6/debian/patches/intersphinx.patch 2017-01-26 08:09:35.000000000 +0000 @@ -1,4 +1,4 @@ -From 87bb9d9c26d539317d01c9bebc44c0366bed878c Mon Sep 17 00:00:00 2001 +From 0522ce0b62c58959b4e733dd686706e62fba6073 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Thu, 14 Jul 2016 23:01:01 +0200 Subject: Use local intersphinx mappings @@ -9,7 +9,7 @@ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/doc/en/conf.py b/doc/en/conf.py -index f3b8d7d..a736ab5 100644 +index 40f1e41..3bb64cc 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -309,11 +309,18 @@ texinfo_documents = [ diff -Nru pytest-3.0.5/debian/patches/remove_google_js pytest-3.0.6/debian/patches/remove_google_js --- pytest-3.0.5/debian/patches/remove_google_js 2016-12-09 16:48:37.000000000 +0000 +++ pytest-3.0.6/debian/patches/remove_google_js 2017-01-26 08:09:35.000000000 +0000 @@ -1,4 +1,4 @@ -From 19adb5fce691071fbe32264ef9bba0fdb2715074 Mon Sep 17 00:00:00 2001 +From 3c64bc322679543f5563b60dd8a0d5385bf665b2 Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Thu, 8 Oct 2015 11:04:33 -0700 Subject: Remove Google Analytics and Google+ javascript. diff -Nru pytest-3.0.5/debian/rules pytest-3.0.6/debian/rules --- pytest-3.0.5/debian/rules 2016-12-12 22:30:05.000000000 +0000 +++ pytest-3.0.6/debian/rules 2017-01-26 08:09:34.000000000 +0000 @@ -10,12 +10,8 @@ dh_auto_build PYTHONPATH=$(CURDIR) $(MAKE) -C doc/en man html mkdir -p debian/tmp - cp doc/en/_build/man/pytest.1 debian/pytest-3.1 - cp doc/en/_build/man/pytest.1 debian/pytest-pypy.1 - sed -i 's/PYTEST/PYTEST-3/g' debian/pytest-3.1 - sed -i 's/PYTEST/PYTEST-PYPY/g' debian/pytest-pypy.1 - sed -i 's/pytest/pytest-3/g' debian/pytest-3.1 - sed -i 's/pytest/pytest-pypy/g' debian/pytest-pypy.1 + sed 's/PYTEST/PYTEST-3/g' doc/en/_build/man/pytest.1 > debian/pytest-3.1 + sed 's/PYTEST/PYTEST-PYPY/g' doc/en/_build/man/pytest.1 > debian/pytest-pypy.1 # 2015-12-16 barry@debian.org: Because pytest does not clean up after itself, # use a custom temporary directory (which is easier to clean up manually, diff -Nru pytest-3.0.5/doc/en/announce/index.rst pytest-3.0.6/doc/en/announce/index.rst --- pytest-3.0.5/doc/en/announce/index.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/index.rst 2017-01-22 17:44:30.000000000 +0000 @@ -6,6 +6,7 @@ :maxdepth: 2 + release-3.0.6 release-3.0.5 release-3.0.4 release-3.0.3 diff -Nru pytest-3.0.5/doc/en/announce/release-2.0.2.rst pytest-3.0.6/doc/en/announce/release-2.0.2.rst --- pytest-3.0.5/doc/en/announce/release-2.0.2.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.0.2.rst 2017-01-20 17:15:39.000000000 +0000 @@ -63,9 +63,9 @@ this. - fixed typos in the docs (thanks Victor Garcia, Brianna Laugher) and particular - thanks to Laura Creighton who also revieved parts of the documentation. + thanks to Laura Creighton who also reviewed parts of the documentation. -- fix slighly wrong output of verbose progress reporting for classes +- fix slightly wrong output of verbose progress reporting for classes (thanks Amaury) - more precise (avoiding of) deprecation warnings for node.Class|Function accesses diff -Nru pytest-3.0.5/doc/en/announce/release-2.0.3.rst pytest-3.0.6/doc/en/announce/release-2.0.3.rst --- pytest-3.0.5/doc/en/announce/release-2.0.3.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.0.3.rst 2017-01-20 17:15:39.000000000 +0000 @@ -13,7 +13,7 @@ easy_install -U pytest There also is a bugfix release 1.6 of pytest-xdist, the plugin -that enables seemless distributed and "looponfail" testing for Python. +that enables seamless distributed and "looponfail" testing for Python. best, holger krekel @@ -33,7 +33,7 @@ - don't require zlib (and other libs) for genscript plugin without --genscript actually being used. -- speed up skips (by not doing a full traceback represenation +- speed up skips (by not doing a full traceback representation internally) - fix issue37: avoid invalid characters in junitxml's output diff -Nru pytest-3.0.5/doc/en/announce/release-2.2.1.rst pytest-3.0.6/doc/en/announce/release-2.2.1.rst --- pytest-3.0.5/doc/en/announce/release-2.2.1.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.2.1.rst 2017-01-20 17:15:39.000000000 +0000 @@ -2,7 +2,7 @@ =========================================================================== -pytest-2.2.1 is a minor backward-compatible release of the the py.test +pytest-2.2.1 is a minor backward-compatible release of the py.test testing tool. It contains bug fixes and little improvements, including documentation fixes. If you are using the distributed testing pluginmake sure to upgrade it to pytest-xdist-1.8. diff -Nru pytest-3.0.5/doc/en/announce/release-2.2.4.rst pytest-3.0.6/doc/en/announce/release-2.2.4.rst --- pytest-3.0.5/doc/en/announce/release-2.2.4.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.2.4.rst 2017-01-20 17:15:39.000000000 +0000 @@ -29,7 +29,7 @@ - fix issue with unittest: now @unittest.expectedFailure markers should be processed correctly (you can also use @pytest.mark markers) - document integration with the extended distribute/setuptools test commands -- fix issue 140: propperly get the real functions +- fix issue 140: properly get the real functions of bound classmethods for setup/teardown_class - fix issue #141: switch from the deceased paste.pocoo.org to bpaste.net - fix issue #143: call unconfigure/sessionfinish always when diff -Nru pytest-3.0.5/doc/en/announce/release-2.3.0.rst pytest-3.0.6/doc/en/announce/release-2.3.0.rst --- pytest-3.0.5/doc/en/announce/release-2.3.0.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.3.0.rst 2017-01-20 17:15:39.000000000 +0000 @@ -89,7 +89,7 @@ - fix issue128: show captured output when capsys/capfd are used -- fix issue179: propperly show the dependency chain of factories +- fix issue179: properly show the dependency chain of factories - pluginmanager.register(...) now raises ValueError if the plugin has been already registered or the name is taken @@ -130,5 +130,5 @@ - don't show deselected reason line if there is none - - py.test -vv will show all of assert comparisations instead of truncating + - py.test -vv will show all of assert comparisons instead of truncating diff -Nru pytest-3.0.5/doc/en/announce/release-2.3.2.rst pytest-3.0.6/doc/en/announce/release-2.3.2.rst --- pytest-3.0.5/doc/en/announce/release-2.3.2.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.3.2.rst 2017-01-20 17:15:39.000000000 +0000 @@ -1,7 +1,7 @@ pytest-2.3.2: some fixes and more traceback-printing speed =========================================================================== -pytest-2.3.2 is a another stabilization release: +pytest-2.3.2 is another stabilization release: - issue 205: fixes a regression with conftest detection - issue 208/29: fixes traceback-printing speed in some bad cases diff -Nru pytest-3.0.5/doc/en/announce/release-2.3.3.rst pytest-3.0.6/doc/en/announce/release-2.3.3.rst --- pytest-3.0.5/doc/en/announce/release-2.3.3.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.3.3.rst 2017-01-20 17:15:39.000000000 +0000 @@ -1,7 +1,7 @@ -pytest-2.3.3: integration fixes, py24 suport, ``*/**`` shown in traceback +pytest-2.3.3: integration fixes, py24 support, ``*/**`` shown in traceback =========================================================================== -pytest-2.3.3 is a another stabilization release of the py.test tool +pytest-2.3.3 is another stabilization release of the py.test tool which offers uebersimple assertions, scalable fixture mechanisms and deep customization for testing with Python. Particularly, this release provides: @@ -46,7 +46,7 @@ - fix issue209 - reintroduce python2.4 support by depending on newer pylib which re-introduced statement-finding for pre-AST interpreters -- nose support: only call setup if its a callable, thanks Andrew +- nose support: only call setup if it's a callable, thanks Andrew Taumoefolau - fix issue219 - add py2.4-3.3 classifiers to TROVE list diff -Nru pytest-3.0.5/doc/en/announce/release-2.3.5.rst pytest-3.0.6/doc/en/announce/release-2.3.5.rst --- pytest-3.0.5/doc/en/announce/release-2.3.5.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.3.5.rst 2017-01-20 17:15:39.000000000 +0000 @@ -44,11 +44,11 @@ (thanks Adam Goucher) - Issue 265 - integrate nose setup/teardown with setupstate - so it doesnt try to teardown if it did not setup + so it doesn't try to teardown if it did not setup -- issue 271 - dont write junitxml on slave nodes +- issue 271 - don't write junitxml on slave nodes -- Issue 274 - dont try to show full doctest example +- Issue 274 - don't try to show full doctest example when doctest does not know the example location - issue 280 - disable assertion rewriting on buggy CPython 2.6.0 @@ -84,7 +84,7 @@ - allow to specify prefixes starting with "_" when customizing python_functions test discovery. (thanks Graham Horler) -- improve PYTEST_DEBUG tracing output by puting +- improve PYTEST_DEBUG tracing output by putting extra data on a new lines with additional indent - ensure OutcomeExceptions like skip/fail have initialized exception attributes diff -Nru pytest-3.0.5/doc/en/announce/release-2.4.0.rst pytest-3.0.6/doc/en/announce/release-2.4.0.rst --- pytest-3.0.5/doc/en/announce/release-2.4.0.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.4.0.rst 2017-01-20 17:15:39.000000000 +0000 @@ -36,7 +36,7 @@ - reporting: color the last line red or green depending if failures/errors occurred or everything passed. -The documentation has been updated to accomodate the changes, +The documentation has been updated to accommodate the changes, see `http://pytest.org `_ To install or upgrade pytest:: @@ -118,7 +118,7 @@ - fix issue322: tearDownClass is not run if setUpClass failed. Thanks Mathieu Agopian for the initial fix. Also make all of pytest/nose - finalizer mimick the same generic behaviour: if a setupX exists and + finalizer mimic the same generic behaviour: if a setupX exists and fails, don't run teardownX. This internally introduces a new method "node.addfinalizer()" helper which can only be called during the setup phase of a node. diff -Nru pytest-3.0.5/doc/en/announce/release-2.5.0.rst pytest-3.0.6/doc/en/announce/release-2.5.0.rst --- pytest-3.0.5/doc/en/announce/release-2.5.0.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.5.0.rst 2017-01-20 17:15:39.000000000 +0000 @@ -70,7 +70,7 @@ to problems for more than >966 non-function scoped parameters). - fix issue290 - there is preliminary support now for parametrizing - with repeated same values (sometimes useful to to test if calling + with repeated same values (sometimes useful to test if calling a second time works as with the first time). - close issue240 - document precisely how pytest module importing @@ -149,7 +149,7 @@ would not work correctly because pytest assumes @pytest.mark.some gets a function to be decorated already. We now at least detect if this - arg is an lambda and thus the example will work. Thanks Alex Gaynor + arg is a lambda and thus the example will work. Thanks Alex Gaynor for bringing it up. - xfail a test on pypy that checks wrong encoding/ascii (pypy does diff -Nru pytest-3.0.5/doc/en/announce/release-2.5.2.rst pytest-3.0.6/doc/en/announce/release-2.5.2.rst --- pytest-3.0.5/doc/en/announce/release-2.5.2.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.5.2.rst 2017-01-20 17:15:39.000000000 +0000 @@ -60,5 +60,5 @@ - fix issue429: comparing byte strings with non-ascii chars in assert expressions now work better. Thanks Floris Bruynooghe. -- make capfd/capsys.capture private, its unused and shouldnt be exposed +- make capfd/capsys.capture private, its unused and shouldn't be exposed diff -Nru pytest-3.0.5/doc/en/announce/release-2.6.3.rst pytest-3.0.6/doc/en/announce/release-2.6.3.rst --- pytest-3.0.5/doc/en/announce/release-2.6.3.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.6.3.rst 2017-01-20 17:15:39.000000000 +0000 @@ -42,7 +42,7 @@ - fix conftest related fixture visibility issue: when running with a CWD outside of a test package pytest would get fixture discovery wrong. - Thanks to Wolfgang Schnerring for figuring out a reproducable example. + Thanks to Wolfgang Schnerring for figuring out a reproducible example. - Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the timeout when interactively entering pdb). Thanks Wolfgang Schnerring. diff -Nru pytest-3.0.5/doc/en/announce/release-2.7.1.rst pytest-3.0.6/doc/en/announce/release-2.7.1.rst --- pytest-3.0.5/doc/en/announce/release-2.7.1.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.7.1.rst 2017-01-20 17:15:39.000000000 +0000 @@ -32,7 +32,7 @@ explanations. Thanks Carl Meyer for the report and test case. - fix issue553: properly handling inspect.getsourcelines failures in - FixtureLookupError which would lead to to an internal error, + FixtureLookupError which would lead to an internal error, obfuscating the original problem. Thanks talljosh for initial diagnose/patch and Bruno Oliveira for final patch. diff -Nru pytest-3.0.5/doc/en/announce/release-2.9.2.rst pytest-3.0.6/doc/en/announce/release-2.9.2.rst --- pytest-3.0.5/doc/en/announce/release-2.9.2.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-2.9.2.rst 2017-01-20 17:15:39.000000000 +0000 @@ -46,7 +46,7 @@ Thanks `@astraw38`_ for reporting the issue (`#1496`_) and `@tomviner`_ for PR the (`#1524`_). -* Fix win32 path issue when puttinging custom config file with absolute path +* Fix win32 path issue when putting custom config file with absolute path in ``pytest.main("-c your_absolute_path")``. * Fix maximum recursion depth detection when raised error class is not aware diff -Nru pytest-3.0.5/doc/en/announce/release-3.0.6.rst pytest-3.0.6/doc/en/announce/release-3.0.6.rst --- pytest-3.0.5/doc/en/announce/release-3.0.6.rst 1970-01-01 00:00:00.000000000 +0000 +++ pytest-3.0.6/doc/en/announce/release-3.0.6.rst 2017-01-22 17:44:30.000000000 +0000 @@ -0,0 +1,33 @@ +pytest-3.0.6 +============ + +pytest 3.0.6 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 http://doc.pytest.org/en/latest/changelog.html. + + +Thanks to all who contributed to this release, among them: + +* Andreas Pelme +* Bruno Oliveira +* Dmitry Malinovsky +* Eli Boyarski +* Jakub Wilk +* Jeff Widman +* Loïc Estève +* Luke Murphy +* Miro Hrončok +* Oscar Hellström +* Peter Heatwole +* Philippe Ombredanne +* Ronny Pfannschmidt +* Rutger Prins +* Stefan Scherfke + + +Happy testing, +The pytest Development Team diff -Nru pytest-3.0.5/doc/en/assert.rst pytest-3.0.6/doc/en/assert.rst --- pytest-3.0.5/doc/en/assert.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/assert.rst 2017-01-22 17:44:30.000000000 +0000 @@ -26,7 +26,7 @@ $ pytest test_assert1.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items @@ -170,7 +170,7 @@ $ pytest test_assert2.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items @@ -262,50 +262,20 @@ .. versionadded:: 2.1 -Reporting details about a failing assertion is achieved either by rewriting -assert statements before they are run or re-evaluating the assert expression and -recording the intermediate values. Which technique is used depends on the -location of the assert, ``pytest`` configuration, and Python version being used -to run ``pytest``. - -By default, ``pytest`` rewrites assert statements in test modules. -Rewritten assert statements put introspection information into the assertion failure message. -``pytest`` only rewrites test modules directly discovered by its test collection process, so -asserts in supporting modules which are not themselves test modules will not be -rewritten. +Reporting details about a failing assertion is achieved by rewriting assert +statements before they are run. Rewritten assert statements put introspection +information into the assertion failure message. ``pytest`` only rewrites test +modules directly discovered by its test collection process, so asserts in +supporting modules which are not themselves test modules will not be rewritten. .. note:: ``pytest`` rewrites test modules on import. It does this by using an import - hook to write a new pyc files. Most of the time this works transparently. + hook to write new pyc files. Most of the time this works transparently. However, if you are messing with import yourself, the import hook may - interfere. If this is the case, simply use ``--assert=reinterp`` or - ``--assert=plain``. Additionally, rewriting will fail silently if it cannot - write new pycs, i.e. in a read-only filesystem or a zipfile. - -If an assert statement has not been rewritten or the Python version is less than -2.6, ``pytest`` falls back on assert reinterpretation. In assert -reinterpretation, ``pytest`` walks the frame of the function containing the -assert statement to discover sub-expression results of the failing assert -statement. You can force ``pytest`` to always use assertion reinterpretation by -passing the ``--assert=reinterp`` option. - -Assert reinterpretation has a caveat not present with assert rewriting: If -evaluating the assert expression has side effects you may get a warning that the -intermediate values could not be determined safely. A common example of this -issue is an assertion which reads from a file:: - - assert f.read() != '...' - -If this assertion fails then the re-evaluation will probably succeed! -This is because ``f.read()`` will return an empty string when it is -called the second time during the re-evaluation. However, it is -easy to rewrite the assertion and avoid any trouble:: - - content = f.read() - assert content != '...' - -All assert introspection can be turned off by passing ``--assert=plain``. + interfere. If this is the case, use ``--assert=plain``. Additionally, + rewriting will fail silently if it cannot write new pycs, i.e. in a read-only + filesystem or a zipfile. For further information, Benjamin Peterson wrote up `Behind the scenes of pytest's new assertion rewriting `_. @@ -318,3 +288,4 @@ .. versionchanged:: 3.0 Removes the ``--no-assert`` and``--nomagic`` options. + Removes the ``--assert=reinterp`` option. diff -Nru pytest-3.0.5/doc/en/cache.rst pytest-3.0.6/doc/en/cache.rst --- pytest-3.0.5/doc/en/cache.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/cache.rst 2017-01-22 17:44:30.000000000 +0000 @@ -80,7 +80,7 @@ $ pytest --lf ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 run-last-failure: rerun last 2 failures rootdir: $REGENDOC_TMPDIR, inifile: collected 50 items @@ -122,7 +122,7 @@ $ pytest --ff ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 run-last-failure: rerun last 2 failures first rootdir: $REGENDOC_TMPDIR, inifile: collected 50 items @@ -227,7 +227,7 @@ $ py.test --cache-show ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: cachedir: $REGENDOC_TMPDIR/.cache ------------------------------- cache values ------------------------------- @@ -246,7 +246,7 @@ pytest --cache-clear -This is recommended for invocations from Continous Integration +This is recommended for invocations from Continuous Integration servers where isolation and correctness is more important than speed. diff -Nru pytest-3.0.5/doc/en/capture.rst pytest-3.0.6/doc/en/capture.rst --- pytest-3.0.5/doc/en/capture.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/capture.rst 2017-01-22 17:44:30.000000000 +0000 @@ -64,7 +64,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items diff -Nru pytest-3.0.5/doc/en/conf.py pytest-3.0.6/doc/en/conf.py --- pytest-3.0.5/doc/en/conf.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/conf.py 2017-01-20 16:40:21.000000000 +0000 @@ -303,7 +303,7 @@ ('Holger Krekel@*Benjamin Peterson@*Ronny Pfannschmidt@*' 'Floris Bruynooghe@*others'), 'pytest', - 'simple powerful testing with Pytho', + 'simple powerful testing with Python', 'Programming', 1), ] diff -Nru pytest-3.0.5/doc/en/doctest.rst pytest-3.0.6/doc/en/doctest.rst --- pytest-3.0.5/doc/en/doctest.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/doctest.rst 2017-01-22 17:44:30.000000000 +0000 @@ -49,7 +49,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 1 items diff -Nru pytest-3.0.5/doc/en/example/markers.rst pytest-3.0.6/doc/en/example/markers.rst --- pytest-3.0.5/doc/en/example/markers.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/example/markers.rst 2017-01-22 17:44:30.000000000 +0000 @@ -31,7 +31,7 @@ $ pytest -v -m webtest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 4 items @@ -45,7 +45,7 @@ $ pytest -v -m "not webtest" ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 4 items @@ -66,7 +66,7 @@ $ pytest -v test_server.py::TestClass::test_method ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 5 items @@ -79,7 +79,7 @@ $ pytest -v test_server.py::TestClass ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 4 items @@ -92,7 +92,7 @@ $ pytest -v test_server.py::TestClass test_server.py::test_send_http ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 8 items @@ -130,7 +130,7 @@ $ pytest -v -k http # running with the above defined example module ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 4 items @@ -144,7 +144,7 @@ $ pytest -k "not send_http" -v ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 4 items @@ -160,7 +160,7 @@ $ pytest -k "http or quick" -v ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 4 items @@ -205,7 +205,7 @@ @pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html - @pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html + @pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html @pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples. @@ -352,7 +352,7 @@ $ pytest -E stage2 ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items @@ -364,7 +364,7 @@ $ pytest -E stage1 ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items @@ -381,7 +381,7 @@ @pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html - @pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html + @pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html @pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples. @@ -450,7 +450,7 @@ import sys import pytest - ALL = set("darwin linux2 win32".split()) + ALL = set("darwin linux win32".split()) def pytest_runtest_setup(item): if isinstance(item, item.Function): @@ -470,7 +470,7 @@ def test_if_apple_is_evil(): pass - @pytest.mark.linux2 + @pytest.mark.linux def test_if_linux_works(): pass @@ -481,32 +481,32 @@ def test_runs_everywhere(): pass -then you will see two test skipped and two executed tests as expected:: +then you will see two tests skipped and two executed tests as expected:: $ pytest -rs # this option reports skip reasons ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items - test_plat.py sss. + test_plat.py s.s. ======= short test summary info ======== - SKIP [3] $REGENDOC_TMPDIR/conftest.py:12: cannot run on platform linux + SKIP [2] $REGENDOC_TMPDIR/conftest.py:12: cannot run on platform linux - ======= 1 passed, 3 skipped in 0.12 seconds ======== + ======= 2 passed, 2 skipped in 0.12 seconds ======== Note that if you specify a platform via the marker-command line option like this:: - $ pytest -m linux2 + $ pytest -m linux ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items - test_plat.py s + test_plat.py . ======= 3 tests deselected ======== - ======= 1 skipped, 3 deselected in 0.12 seconds ======== + ======= 1 passed, 3 deselected in 0.12 seconds ======== then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests. @@ -551,7 +551,7 @@ $ pytest -m interface --tb=short ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items @@ -573,7 +573,7 @@ $ pytest -m "interface or event" --tb=short ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items diff -Nru pytest-3.0.5/doc/en/example/nonpython.rst pytest-3.0.6/doc/en/example/nonpython.rst --- pytest-3.0.5/doc/en/example/nonpython.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/example/nonpython.rst 2017-01-22 17:44:30.000000000 +0000 @@ -27,7 +27,7 @@ nonpython $ pytest test_simple.yml ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR/nonpython, inifile: collected 2 items @@ -59,7 +59,7 @@ nonpython $ pytest -v ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR/nonpython, inifile: collecting ... collected 2 items @@ -81,7 +81,7 @@ nonpython $ pytest --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR/nonpython, inifile: collected 2 items diff -Nru pytest-3.0.5/doc/en/example/parametrize.rst pytest-3.0.6/doc/en/example/parametrize.rst --- pytest-3.0.5/doc/en/example/parametrize.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/example/parametrize.rst 2017-01-22 17:44:30.000000000 +0000 @@ -130,7 +130,7 @@ $ pytest test_time.py --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 6 items @@ -181,7 +181,7 @@ $ pytest test_scenarios.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items @@ -194,7 +194,7 @@ $ pytest --collect-only test_scenarios.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items @@ -259,7 +259,7 @@ $ pytest test_backends.py --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items @@ -320,7 +320,7 @@ $ pytest test_indirect_list.py --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items @@ -397,10 +397,12 @@ Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (5 interpreters times 5 interpreters times 3 objects to serialize/deserialize):: . $ pytest -rs -q multipython.py - sssssssssssssss.........sss.........sss......... + sssssssssssssssssssssssssssssssssssssssssssss... ======= short test summary info ======== - SKIP [21] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python2.6' not found - 27 passed, 21 skipped in 0.12 seconds + SKIP [15] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python2.6' not found + SKIP [15] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python3.4' not found + SKIP [15] $REGENDOC_TMPDIR/CWD/multipython.py:23: 'python2.7' not found + 3 passed, 45 skipped in 0.12 seconds Indirect parametrization of optional implementations/imports -------------------------------------------------------------------- @@ -447,7 +449,7 @@ $ pytest -rs test_module.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items diff -Nru pytest-3.0.5/doc/en/example/pythoncollection.rst pytest-3.0.6/doc/en/example/pythoncollection.rst --- pytest-3.0.5/doc/en/example/pythoncollection.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/example/pythoncollection.rst 2017-01-22 17:44:30.000000000 +0000 @@ -95,7 +95,7 @@ :confval:`python_functions` configuration options. Example:: # content of pytest.ini - # can also be defined in in tox.ini or setup.cfg file, although the section + # can also be defined in tox.ini or setup.cfg file, although the section # name in setup.cfg files should be "tool:pytest" [pytest] python_files=check_*.py @@ -117,7 +117,7 @@ $ pytest --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 2 items @@ -163,7 +163,7 @@ . $ pytest --collect-only pythoncollection.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 3 items @@ -230,7 +230,7 @@ $ pytest --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 0 items diff -Nru pytest-3.0.5/doc/en/example/reportingdemo.rst pytest-3.0.6/doc/en/example/reportingdemo.rst --- pytest-3.0.5/doc/en/example/reportingdemo.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/example/reportingdemo.rst 2017-01-22 17:44:30.000000000 +0000 @@ -11,7 +11,7 @@ assertion $ pytest failure_demo.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR/assertion, inifile: collected 42 items diff -Nru pytest-3.0.5/doc/en/example/simple.rst pytest-3.0.6/doc/en/example/simple.rst --- pytest-3.0.5/doc/en/example/simple.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/example/simple.rst 2017-01-22 17:44:30.000000000 +0000 @@ -113,7 +113,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 0 items @@ -164,7 +164,7 @@ $ pytest -rs # "-rs" means report details on the little 's' ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items @@ -178,7 +178,7 @@ $ pytest --runslow ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items @@ -302,7 +302,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 project deps: mylib-1.1 rootdir: $REGENDOC_TMPDIR, inifile: collected 0 items @@ -327,7 +327,7 @@ $ pytest -v ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache info1: did you know that ... did you? @@ -340,7 +340,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 0 items @@ -374,7 +374,7 @@ $ pytest --durations=3 ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 3 items @@ -440,7 +440,7 @@ $ pytest -rx ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 4 items @@ -476,7 +476,7 @@ tests or test classes rather than relying on implicitly executing setup/teardown functions, especially if they are far away from the actual tests. -Here is a an example for making a ``db`` fixture available in a directory: +Here is an example for making a ``db`` fixture available in a directory: .. code-block:: python @@ -519,7 +519,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 7 items @@ -585,7 +585,7 @@ "report" object is about to be created. Here we write out all failing test calls and also access a fixture (if it was used by the test) in case you want to query/look at it during your post processing. In our -case we just write some informations out to a ``failures`` file: +case we just write some information out to a ``failures`` file: .. code-block:: python @@ -627,7 +627,7 @@ $ pytest test_module.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items @@ -678,7 +678,7 @@ outcome = yield rep = outcome.get_result() - # set an report attribute for each phase of a call, which can + # set a report attribute for each phase of a call, which can # be "setup", "call", "teardown" setattr(item, "rep_" + rep.when, rep) @@ -721,7 +721,7 @@ $ pytest -s test_module.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 3 items diff -Nru pytest-3.0.5/doc/en/faq.rst pytest-3.0.6/doc/en/faq.rst --- pytest-3.0.5/doc/en/faq.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/faq.rst 2017-01-20 17:15:23.000000000 +0000 @@ -66,14 +66,6 @@ It also means, that you can use Python's ``-O`` optimization without losing assertions in test modules. -``pytest`` contains a second, mostly obsolete, assert debugging technique -invoked via ``--assert=reinterpret``: When an ``assert`` statement fails, ``pytest`` re-interprets -the expression part to show intermediate values. This technique suffers -from a caveat that the rewriting does not: If your expression has side -effects (better to avoid them anyway!) the intermediate values may not -be the same, confusing the reinterpreter and obfuscating the initial -error (this is also explained at the command line if it happens). - You can also turn off all assertion interaction using the ``--assert=plain`` option. diff -Nru pytest-3.0.5/doc/en/fixture.rst pytest-3.0.6/doc/en/fixture.rst --- pytest-3.0.5/doc/en/fixture.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/fixture.rst 2017-01-22 17:44:30.000000000 +0000 @@ -11,7 +11,7 @@ .. _`xUnit`: http://en.wikipedia.org/wiki/XUnit .. _`purpose of test fixtures`: http://en.wikipedia.org/wiki/Test_fixture#Software -.. _`Dependency injection`: http://en.wikipedia.org/wiki/Dependency_injection#Definition +.. _`Dependency injection`: http://en.wikipedia.org/wiki/Dependency_injection The `purpose of test fixtures`_ is to provide a fixed baseline upon which tests can reliably and repeatedly execute. pytest fixtures @@ -70,7 +70,7 @@ $ pytest test_smtpsimple.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items @@ -188,7 +188,7 @@ $ pytest test_module.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items @@ -257,8 +257,9 @@ print("teardown smtp") smtp.close() -The ``print`` and ``smtp.close()`` statements will execute when the last test using -the fixture in the module has finished execution, regardless of the exception status of the tests. +The ``print`` and ``smtp.close()`` statements will execute when the last test in +the module has finished execution, regardless of the exception status of the +tests. Let's execute it:: @@ -519,7 +520,7 @@ $ pytest --collect-only ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 11 items @@ -572,7 +573,7 @@ $ pytest -v test_appsetup.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 2 items @@ -641,7 +642,7 @@ $ pytest -v -s test_module.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 -- $PYTHON_PREFIX/bin/python3.5m cachedir: .cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 8 items @@ -1001,7 +1002,7 @@ @pytest.mark.parametrize('username', ['directly-overridden-username-other']) def test_username_other(other_username): - assert username == 'other-directly-overridden-username-other' + assert other_username == 'other-directly-overridden-username-other' In the example above, a fixture value is overridden by the test parameter value. Note that the value of the fixture can be overridden this way even if the test doesn't use it directly (doesn't mention it in the function prototype). diff -Nru pytest-3.0.5/doc/en/funcarg_compare.rst pytest-3.0.6/doc/en/funcarg_compare.rst --- pytest-3.0.5/doc/en/funcarg_compare.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/funcarg_compare.rst 2017-01-20 17:15:32.000000000 +0000 @@ -97,7 +97,7 @@ ... # use request.param Here the factory will be invoked twice (with the respective "mysql" -and "pg" values set as ``request.param`` attributes) and and all of +and "pg" values set as ``request.param`` attributes) and all of the tests requiring "db" will run twice as well. The "mysql" and "pg" values will also be used for reporting the test-invocation variants. diff -Nru pytest-3.0.5/doc/en/getting-started.rst pytest-3.0.6/doc/en/getting-started.rst --- pytest-3.0.5/doc/en/getting-started.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/getting-started.rst 2017-01-22 17:44:30.000000000 +0000 @@ -26,7 +26,7 @@ To check your installation has installed the correct version:: $ pytest --version - This is pytest version 3.0.5, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py + This is pytest version 3.0.6, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py .. _`simpletest`: @@ -46,7 +46,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items diff -Nru pytest-3.0.5/doc/en/goodpractices.rst pytest-3.0.6/doc/en/goodpractices.rst --- pytest-3.0.5/doc/en/goodpractices.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/goodpractices.rst 2017-01-20 17:15:34.000000000 +0000 @@ -147,7 +147,7 @@ If you frequently release code and want to make sure that your actual package passes all tests you may want to look into `tox`_, the virtualenv test automation tool and its `pytest support -`_. +`_. Tox helps you to setup virtualenv environments with pre-defined dependencies and then executing a pre-configured test command with options. It will run tests against the installed package and not diff -Nru pytest-3.0.5/doc/en/index.rst pytest-3.0.6/doc/en/index.rst --- pytest-3.0.5/doc/en/index.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/index.rst 2017-01-22 17:44:30.000000000 +0000 @@ -25,7 +25,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items diff -Nru pytest-3.0.5/doc/en/monkeypatch.rst pytest-3.0.6/doc/en/monkeypatch.rst --- pytest-3.0.5/doc/en/monkeypatch.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/monkeypatch.rst 2017-01-20 17:15:34.000000000 +0000 @@ -35,7 +35,7 @@ assert x == '/abc/.ssh' Here our test function monkeypatches ``os.path.expanduser`` and -then calls into an function that calls it. After the test function +then calls into a function that calls it. After the test function finishes the ``os.path.expanduser`` modification will be undone. example: preventing "requests" from remote operations @@ -60,7 +60,7 @@ Be advised that it is not recommended to patch builtin functions such as ``open``, ``compile``, etc., because it might break pytest's internals. If that's unavoidable, passing ``--tb=native``, ``--assert=plain`` and ``--capture=no`` might - help althought there's no guarantee. + help although there's no guarantee. Method reference of the monkeypatch fixture diff -Nru pytest-3.0.5/doc/en/parametrize.rst pytest-3.0.6/doc/en/parametrize.rst --- pytest-3.0.5/doc/en/parametrize.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/parametrize.rst 2017-01-22 17:44:30.000000000 +0000 @@ -55,7 +55,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 3 items @@ -103,7 +103,7 @@ $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 3 items diff -Nru pytest-3.0.5/doc/en/parametrize.rst.orig pytest-3.0.6/doc/en/parametrize.rst.orig --- pytest-3.0.5/doc/en/parametrize.rst.orig 1970-01-01 00:00:00.000000000 +0000 +++ pytest-3.0.6/doc/en/parametrize.rst.orig 2017-01-19 09:27:41.000000000 +0000 @@ -0,0 +1,238 @@ + +.. _`test generators`: +.. _`parametrizing-tests`: +.. _`parametrized test functions`: +.. _`parametrize`: + +.. _`parametrize-basics`: + +Parametrizing fixtures and test functions +========================================================================== + +pytest supports test parametrization in several well-integrated ways: + +- :py:func:`pytest.fixture` allows to define :ref:`parametrization + at the level of fixture functions `. + +* `@pytest.mark.parametrize`_ allows to define parametrization at the + function or class level, provides multiple argument/fixture sets + for a particular test function or class. + +* `pytest_generate_tests`_ enables implementing your own custom + dynamic parametrization scheme or extensions. + +.. _parametrizemark: +.. _`@pytest.mark.parametrize`: + + +``@pytest.mark.parametrize``: parametrizing test functions +--------------------------------------------------------------------- + +.. regendoc: wipe + +.. versionadded:: 2.2 +.. versionchanged:: 2.4 + Several improvements. + +The builtin ``pytest.mark.parametrize`` decorator enables +parametrization of arguments for a test function. Here is a typical example +of a test function that implements checking that a certain input leads +to an expected output:: + + # content of test_expectation.py + import pytest + @pytest.mark.parametrize("test_input,expected", [ + ("3+5", 8), + ("2+4", 6), + ("6*9", 42), + ]) + def test_eval(test_input, expected): + assert eval(test_input) == expected + +Here, the ``@parametrize`` decorator defines three different ``(test_input,expected)`` +tuples so that the ``test_eval`` function will run three times using +them in turn:: + + $ pytest + ======= test session starts ======== + platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 + rootdir: $REGENDOC_TMPDIR, inifile: + collected 3 items + + test_expectation.py ..F + + ======= FAILURES ======== + _______ test_eval[6*9-42] ________ + + test_input = '6*9', expected = 42 + + @pytest.mark.parametrize("test_input,expected", [ + ("3+5", 8), + ("2+4", 6), + ("6*9", 42), + ]) + def test_eval(test_input, expected): + > assert eval(test_input) == expected + E assert 54 == 42 + E + where 54 = eval('6*9') + + test_expectation.py:8: AssertionError + ======= 1 failed, 2 passed in 0.12 seconds ======== + +As designed in this example, only one pair of input/output values fails +the simple test function. And as usual with test function arguments, +you can see the ``input`` and ``output`` values in the traceback. + +Note that you could also use the parametrize marker on a class or a module +(see :ref:`mark`) which would invoke several functions with the argument sets. + +It is also possible to mark individual test instances within parametrize, +for example with the builtin ``mark.xfail``:: + + # content of test_expectation.py + import pytest + @pytest.mark.parametrize("test_input,expected", [ + ("3+5", 8), + ("2+4", 6), +<<<<<<< HEAD + pytest.mark.xfail(("6*9", 42)), +======= + pytest.param("6*9", 42, + marks=pytest.mark.xfail), +>>>>>>> pytest.param: update docs from marked + ]) + def test_eval(test_input, expected): + assert eval(test_input) == expected + +.. note:: + + prior to version 3.1 the supported mechanism for marking values + used the syntax:: + + import pytest + @pytest.mark.parametrize("test_input,expected", [ + ("3+5", 8), + ("2+4", 6), + pytest.mark.xfail(("6*9", 42),), + ]) + def test_eval(test_input, expected): + assert eval(test_input) == expected + + +Let's run this:: + + $ pytest + ======= test session starts ======== + platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 + rootdir: $REGENDOC_TMPDIR, inifile: + collected 3 items + + test_expectation.py ..x + + ======= 2 passed, 1 xfailed in 0.12 seconds ======== + +The one parameter set which caused a failure previously now +shows up as an "xfailed (expected to fail)" test. + +To get all combinations of multiple parametrized arguments you can stack +``parametrize`` decorators:: + + import pytest + @pytest.mark.parametrize("x", [0, 1]) + @pytest.mark.parametrize("y", [2, 3]) + def test_foo(x, y): + pass + +This will run the test with the arguments set to x=0/y=2, x=0/y=3, x=1/y=2 and +x=1/y=3. + +.. note:: + + In versions prior to 2.4 one needed to specify the argument + names as a tuple. This remains valid but the simpler ``"name1,name2,..."`` + comma-separated-string syntax is now advertised first because + it's easier to write and produces less line noise. + +.. _`pytest_generate_tests`: + +Basic ``pytest_generate_tests`` example +--------------------------------------------- + +Sometimes you may want to implement your own parametrization scheme +or implement some dynamism for determining the parameters or scope +of a fixture. For this, you can use the ``pytest_generate_tests`` hook +which is called when collecting a test function. Through the passed in +``metafunc`` object you can inspect the requesting test context and, most +importantly, you can call ``metafunc.parametrize()`` to cause +parametrization. + +For example, let's say we want to run a test taking string inputs which +we want to set via a new ``pytest`` command line option. Let's first write +a simple test accepting a ``stringinput`` fixture function argument:: + + # content of test_strings.py + + def test_valid_string(stringinput): + assert stringinput.isalpha() + +Now we add a ``conftest.py`` file containing the addition of a +command line option and the parametrization of our test function:: + + # content of conftest.py + + def pytest_addoption(parser): + parser.addoption("--stringinput", action="append", default=[], + help="list of stringinputs to pass to test functions") + + def pytest_generate_tests(metafunc): + if 'stringinput' in metafunc.fixturenames: + metafunc.parametrize("stringinput", + metafunc.config.option.stringinput) + +If we now pass two stringinput values, our test will run twice:: + + $ pytest -q --stringinput="hello" --stringinput="world" test_strings.py + .. + 2 passed in 0.12 seconds + +Let's also run with a stringinput that will lead to a failing test:: + + $ pytest -q --stringinput="!" test_strings.py + F + ======= FAILURES ======== + _______ test_valid_string[!] ________ + + stringinput = '!' + + def test_valid_string(stringinput): + > assert stringinput.isalpha() + E assert False + E + where False = () + E + where = '!'.isalpha + + test_strings.py:3: AssertionError + 1 failed in 0.12 seconds + +As expected our test function fails. + +If you don't specify a stringinput it will be skipped because +``metafunc.parametrize()`` will be called with an empty parameter +list:: + + $ pytest -q -rs test_strings.py + s + ======= short test summary info ======== + SKIP [1] test_strings.py:1: got empty parameter set ['stringinput'], function test_valid_string at $REGENDOC_TMPDIR/test_strings.py:1 + 1 skipped in 0.12 seconds + +For further examples, you might want to look at :ref:`more +parametrization examples `. + +.. _`metafunc object`: + +The **metafunc** object +------------------------------------------- + +.. currentmodule:: _pytest.python +.. autoclass:: Metafunc + :members: diff -Nru pytest-3.0.5/doc/en/projects.rst pytest-3.0.6/doc/en/projects.rst --- pytest-3.0.5/doc/en/projects.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/projects.rst 2017-01-20 17:15:36.000000000 +0000 @@ -58,7 +58,7 @@ * `katcp `_ Telescope communication protocol over Twisted * `kss plugin timer `_ * `pyudev `_ a pure Python binding to the Linux library libudev -* `pytest-localserver `_ a plugin for pytest that provides a httpserver and smtpserver +* `pytest-localserver `_ a plugin for pytest that provides an httpserver and smtpserver * `pytest-monkeyplus `_ a plugin that extends monkeypatch These projects help integrate ``pytest`` into other Python frameworks: diff -Nru pytest-3.0.5/doc/en/skipping.rst pytest-3.0.6/doc/en/skipping.rst --- pytest-3.0.5/doc/en/skipping.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/skipping.rst 2017-01-22 17:44:30.000000000 +0000 @@ -2,7 +2,7 @@ .. _skipping: -Skip and xfail: dealing with tests that can not succeed +Skip and xfail: dealing with tests that cannot succeed ===================================================================== If you have test functions that cannot be run on certain platforms @@ -224,7 +224,7 @@ example $ pytest -rx xfail_demo.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR/example, inifile: collected 7 items diff -Nru pytest-3.0.5/doc/en/test/plugin/xdist.rst pytest-3.0.6/doc/en/test/plugin/xdist.rst --- pytest-3.0.5/doc/en/test/plugin/xdist.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/test/plugin/xdist.rst 2017-01-20 16:40:21.000000000 +0000 @@ -71,7 +71,7 @@ pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg This will synchronize your ``mypkg`` package directory -to an remote ssh account and then locally collect tests +to a remote ssh account and then locally collect tests and send them to remote places for execution. You can specify multiple ``--rsyncdir`` directories diff -Nru pytest-3.0.5/doc/en/tmpdir.rst pytest-3.0.6/doc/en/tmpdir.rst --- pytest-3.0.5/doc/en/tmpdir.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/tmpdir.rst 2017-01-22 17:44:30.000000000 +0000 @@ -29,7 +29,7 @@ $ pytest test_tmpdir.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 1 items diff -Nru pytest-3.0.5/doc/en/unittest.rst pytest-3.0.6/doc/en/unittest.rst --- pytest-3.0.5/doc/en/unittest.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/unittest.rst 2017-01-22 17:44:30.000000000 +0000 @@ -100,7 +100,7 @@ $ pytest test_unittest_db.py ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.33, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 2 items diff -Nru pytest-3.0.5/doc/en/usage.rst pytest-3.0.6/doc/en/usage.rst --- pytest-3.0.5/doc/en/usage.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/usage.rst 2017-01-20 17:15:39.000000000 +0000 @@ -16,8 +16,8 @@ python -m pytest [...] -This is equivalent to invoking the command line script ``pytest [...]`` -directly. +This is almost equivalent to invoking the command line script ``pytest [...]`` +directly, except that python will also add the current directory to ``sys.path``. Getting help on version, option names, environment variables -------------------------------------------------------------- @@ -49,7 +49,7 @@ # will select TestMyClass.test_something # but not TestMyClass.test_method_simple pytest test_mod.py::test_func # only run tests that match the "node ID", - # e.g "test_mod.py::test_func" will select + # e.g. "test_mod.py::test_func" will select # only test_func in test_mod.py pytest test_mod.py::TestClass::test_method # run a single method in # a single class @@ -76,7 +76,7 @@ The ``--full-trace`` causes very long traces to be printed on error (longer than ``--tb=long``). It also ensures that a stack trace is printed on -**KeyboardInterrrupt** (Ctrl+C). +**KeyboardInterrupt** (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 caught by pytest). By using this diff -Nru pytest-3.0.5/doc/en/writing_plugins.rst pytest-3.0.6/doc/en/writing_plugins.rst --- pytest-3.0.5/doc/en/writing_plugins.rst 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/doc/en/writing_plugins.rst 2017-01-20 17:15:39.000000000 +0000 @@ -172,7 +172,7 @@ .. note:: Make sure to include ``Framework :: Pytest`` in your list of - `PyPI classifiers `_ + `PyPI classifiers `_ to make it easy for users to find your plugin. @@ -250,8 +250,8 @@ Plugins imported like this will automatically be marked to require assertion rewriting using the :func:`pytest.register_assert_rewrite` mechanism. However for this to have any effect the module must not be -imported already, it it was already imported at the time the -``pytest_plugins`` statement is processed a warning will result and +imported already; if it was already imported at the time the +``pytest_plugins`` statement is processed, a warning will result and assertions inside the plugin will not be re-written. To fix this you can either call :func:`pytest.register_assert_rewrite` yourself before the module is imported, or you can arrange the code to delay the diff -Nru pytest-3.0.5/.gitattributes pytest-3.0.6/.gitattributes --- pytest-3.0.5/.gitattributes 1970-01-01 00:00:00.000000000 +0000 +++ pytest-3.0.6/.gitattributes 2016-06-25 14:19:06.000000000 +0000 @@ -0,0 +1 @@ +CHANGELOG merge=union diff -Nru pytest-3.0.5/.gitignore pytest-3.0.6/.gitignore --- pytest-3.0.5/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ pytest-3.0.6/.gitignore 2016-12-06 18:09:16.000000000 +0000 @@ -0,0 +1,36 @@ +# Automatically generated by `hgimportsvn` +.svn +.hgsvn + +# Ignore local virtualenvs +lib/ +bin/ +include/ +.Python/ + +# These lines are suggested according to the svn:ignore property +# Feel free to enable them by uncommenting them +*.pyc +*.pyo +*.swp +*.class +*.orig +*~ +.hypothesis/ + +.eggs/ + +doc/*/_build +build/ +dist/ +*.egg-info +issue/ +env/ +.env/ +3rdparty/ +.tox +.cache +.coverage +.ropeproject +.idea +.hypothesis diff -Nru pytest-3.0.5/PKG-INFO pytest-3.0.6/PKG-INFO --- pytest-3.0.5/PKG-INFO 2016-12-05 12:22:39.000000000 +0000 +++ pytest-3.0.6/PKG-INFO 2017-01-22 21:15:07.000000000 +0000 @@ -1,10 +1,10 @@ Metadata-Version: 1.1 Name: pytest -Version: 3.0.5 +Version: 3.0.6 Summary: pytest: simple powerful testing with Python Home-page: http://pytest.org Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others -Author-email: holger at merlinux.eu +Author-email: UNKNOWN License: MIT license Description: .. image:: http://docs.pytest.org/en/latest/_static/pytest1.png :target: http://docs.pytest.org diff -Nru pytest-3.0.5/_pytest/compat.py pytest-3.0.6/_pytest/compat.py --- pytest-3.0.5/_pytest/compat.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/compat.py 2017-01-20 16:40:21.000000000 +0000 @@ -19,6 +19,7 @@ # Only available in Python 3.4+ or as a backport enum = None + _PY3 = sys.version_info > (3, 0) _PY2 = not _PY3 @@ -26,6 +27,9 @@ NoneType = type(None) NOTSET = object() +PY36 = sys.version_info[:2] >= (3, 6) +MODULE_NOT_FOUND_ERROR = 'ModuleNotFoundError' if PY36 else 'ImportError' + if hasattr(inspect, 'signature'): def _format_args(func): return str(inspect.signature(func)) @@ -42,11 +46,18 @@ def is_generator(func): - try: - return _pytest._code.getrawcode(func).co_flags & 32 # generator function - except AttributeError: # builtin functions have no bytecode - # assume them to not be generators - return False + genfunc = inspect.isgeneratorfunction(func) + return genfunc and not iscoroutinefunction(func) + + +def iscoroutinefunction(func): + """Return True if func is a decorated coroutine function. + + Note: copied and modified from Python 3.5's builtin couroutines.py to avoid import asyncio directly, + which in turns also initializes the "logging" module as side-effect (see issue #8). + """ + return (getattr(func, '_is_coroutine', False) or + (hasattr(inspect, 'iscoroutinefunction') and inspect.iscoroutinefunction(func))) def getlocation(function, curdir): diff -Nru pytest-3.0.5/_pytest/config.py pytest-3.0.6/_pytest/config.py --- pytest-3.0.5/_pytest/config.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/config.py 2017-01-20 16:40:36.000000000 +0000 @@ -402,31 +402,26 @@ self._import_plugin_specs(os.environ.get("PYTEST_PLUGINS")) def consider_module(self, mod): - plugins = getattr(mod, 'pytest_plugins', []) - if isinstance(plugins, str): - plugins = [plugins] - self.rewrite_hook.mark_rewrite(*plugins) - self._import_plugin_specs(plugins) + self._import_plugin_specs(getattr(mod, 'pytest_plugins', [])) def _import_plugin_specs(self, spec): - if spec: - if isinstance(spec, str): - spec = spec.split(",") - for import_spec in spec: - self.import_plugin(import_spec) + plugins = _get_plugin_specs_as_list(spec) + for import_spec in plugins: + self.import_plugin(import_spec) def import_plugin(self, modname): # most often modname refers to builtin modules, e.g. "pytester", # "terminal" or "capture". Those plugins are registered under their # basename for historic purposes but must be imported with the # _pytest prefix. - assert isinstance(modname, str) + assert isinstance(modname, str), "module name as string required, got %r" % modname if self.get_plugin(modname) is not None: return if modname in builtin_plugins: importspec = "_pytest." + modname else: importspec = modname + self.rewrite_hook.mark_rewrite(importspec) try: __import__(importspec) except ImportError as e: @@ -447,6 +442,24 @@ self.consider_module(mod) +def _get_plugin_specs_as_list(specs): + """ + Parses a list of "plugin specs" and returns a list of plugin names. + + Plugin specs can be given as a list of strings separated by "," or already as a list/tuple in + which case it is returned as a list. Specs can also be `None` in which case an + empty list is returned. + """ + if specs is not None: + if isinstance(specs, str): + specs = specs.split(',') if specs else [] + if not isinstance(specs, (list, tuple)): + raise UsageError("Plugin specs must be a ','-separated string or a " + "list/tuple of strings for plugin names. Given: %r" % specs) + return list(specs) + return [] + + class Parser: """ Parser for command line arguments and ini-file values. @@ -1228,25 +1241,20 @@ return None, None, None -def get_common_ancestor(args): - # args are what we get after early command line parsing (usually - # strings, but can be py.path.local objects as well) +def get_common_ancestor(paths): common_ancestor = None - for arg in args: - if str(arg)[0] == "-": - continue - p = py.path.local(arg) - if not p.exists(): + for path in paths: + if not path.exists(): continue if common_ancestor is None: - common_ancestor = p + common_ancestor = path else: - if p.relto(common_ancestor) or p == common_ancestor: + if path.relto(common_ancestor) or path == common_ancestor: continue - elif common_ancestor.relto(p): - common_ancestor = p + elif common_ancestor.relto(path): + common_ancestor = path else: - shared = p.common(common_ancestor) + shared = path.common(common_ancestor) if shared is not None: common_ancestor = shared if common_ancestor is None: @@ -1257,9 +1265,29 @@ def get_dirs_from_args(args): - return [d for d in (py.path.local(x) for x in args - if not str(x).startswith("-")) - if d.exists()] + def is_option(x): + return str(x).startswith('-') + + def get_file_part_from_node_id(x): + return str(x).split('::')[0] + + def get_dir_from_path(path): + if path.isdir(): + return path + return py.path.local(path.dirname) + + # These look like paths but may not exist + possible_paths = ( + py.path.local(get_file_part_from_node_id(arg)) + for arg in args + if not is_option(arg) + ) + + return [ + get_dir_from_path(path) + for path in possible_paths + if path.exists() + ] def determine_setup(inifile, args, warnfunc=None): diff -Nru pytest-3.0.5/_pytest/__init__.py pytest-3.0.6/_pytest/__init__.py --- pytest-3.0.5/_pytest/__init__.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/__init__.py 2017-01-22 17:44:30.000000000 +0000 @@ -1,2 +1,2 @@ # -__version__ = '3.0.5' +__version__ = '3.0.6' diff -Nru pytest-3.0.5/_pytest/main.py pytest-3.0.6/_pytest/main.py --- pytest-3.0.5/_pytest/main.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/main.py 2017-01-20 16:40:36.000000000 +0000 @@ -190,14 +190,22 @@ self.__dict__[name] = x return x -def compatproperty(name): - def fget(self): - import warnings - warnings.warn("This usage is deprecated, please use pytest.{0} instead".format(name), - PendingDeprecationWarning, stacklevel=2) - return getattr(pytest, name) +class _CompatProperty(object): + def __init__(self, name): + self.name = name + + def __get__(self, obj, owner): + if obj is None: + return self + + # TODO: reenable in the features branch + # warnings.warn( + # "usage of {owner!r}.{name} is deprecated, please use pytest.{name} instead".format( + # name=self.name, owner=type(owner).__name__), + # PendingDeprecationWarning, stacklevel=2) + return getattr(pytest, self.name) + - return property(fget) class NodeKeywords(MappingMixin): def __init__(self, node): @@ -269,19 +277,23 @@ """ fspath sensitive hook proxy used to call pytest hooks""" return self.session.gethookproxy(self.fspath) - Module = compatproperty("Module") - Class = compatproperty("Class") - Instance = compatproperty("Instance") - Function = compatproperty("Function") - File = compatproperty("File") - Item = compatproperty("Item") + Module = _CompatProperty("Module") + Class = _CompatProperty("Class") + Instance = _CompatProperty("Instance") + Function = _CompatProperty("Function") + File = _CompatProperty("File") + Item = _CompatProperty("Item") def _getcustomclass(self, name): - cls = getattr(self, name) - if cls != getattr(pytest, name): - py.log._apiwarn("2.0", "use of node.%s is deprecated, " - "use pytest_pycollect_makeitem(...) to create custom " - "collection nodes" % name) + maybe_compatprop = getattr(type(self), name) + if isinstance(maybe_compatprop, _CompatProperty): + return getattr(pytest, name) + else: + cls = getattr(self, name) + # TODO: reenable in the features branch + # warnings.warn("use of node.%s is deprecated, " + # "use pytest_pycollect_makeitem(...) to create custom " + # "collection nodes" % name, category=DeprecationWarning) return cls def __repr__(self): diff -Nru pytest-3.0.5/_pytest/monkeypatch.py pytest-3.0.6/_pytest/monkeypatch.py --- pytest-3.0.5/_pytest/monkeypatch.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/monkeypatch.py 2017-01-20 16:40:21.000000000 +0000 @@ -11,7 +11,7 @@ @pytest.fixture -def monkeypatch(request): +def monkeypatch(): """The returned ``monkeypatch`` fixture provides these helper methods to modify objects, dictionaries or os.environ:: @@ -30,8 +30,8 @@ will be raised if the set/deletion operation has no target. """ mpatch = MonkeyPatch() - request.addfinalizer(mpatch.undo) - return mpatch + yield mpatch + mpatch.undo() def resolve(name): diff -Nru pytest-3.0.5/_pytest/pytester.py pytest-3.0.6/_pytest/pytester.py --- pytest-3.0.5/_pytest/pytester.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/pytester.py 2017-01-20 16:40:36.000000000 +0000 @@ -367,6 +367,7 @@ for num, cat in outcomes: d[cat] = int(num) return d + raise ValueError("Pytest terminal report not found") def assert_outcomes(self, passed=0, skipped=0, failed=0): """ assert that the specified outcomes appear with the respective @@ -446,9 +447,9 @@ the module is re-imported. """ for name in set(sys.modules).difference(self._savemodulekeys): - # it seems zope.interfaces is keeping some state - # (used by twisted related tests) - if name != "zope.interface": + # zope.interface (used by twisted-related tests) keeps internal + # state and can't be deleted + if not name.startswith("zope.interface"): del sys.modules[name] def make_hook_recorder(self, pluginmanager): diff -Nru pytest-3.0.5/_pytest/recwarn.py pytest-3.0.6/_pytest/recwarn.py --- pytest-3.0.5/_pytest/recwarn.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/recwarn.py 2017-01-20 16:40:21.000000000 +0000 @@ -223,4 +223,7 @@ if self.expected_warning is not None: if not any(r.category in self.expected_warning for r in self): __tracebackhide__ = True - pytest.fail("DID NOT WARN") + pytest.fail("DID NOT WARN. No warnings of type {0} was emitted. " + "The list of emitted warnings is: {1}.".format( + self.expected_warning, + [each.message for each in self])) diff -Nru pytest-3.0.5/_pytest/skipping.py pytest-3.0.6/_pytest/skipping.py --- pytest-3.0.5/_pytest/skipping.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/_pytest/skipping.py 2017-01-22 17:44:30.000000000 +0000 @@ -46,7 +46,7 @@ ) config.addinivalue_line("markers", "xfail(condition, reason=None, run=True, raises=None, strict=False): " - "mark the the test function as an expected failure if eval(condition) " + "mark the test function as an expected failure if eval(condition) " "has a True value. Optionally specify a reason for better reporting " "and run=False if you don't even want to execute the test function. " "If only specific exception(s) are expected, you can list them in " diff -Nru pytest-3.0.5/pytest.egg-info/PKG-INFO pytest-3.0.6/pytest.egg-info/PKG-INFO --- pytest-3.0.5/pytest.egg-info/PKG-INFO 2016-12-05 12:22:39.000000000 +0000 +++ pytest-3.0.6/pytest.egg-info/PKG-INFO 2017-01-22 21:15:07.000000000 +0000 @@ -1,10 +1,10 @@ Metadata-Version: 1.1 Name: pytest -Version: 3.0.5 +Version: 3.0.6 Summary: pytest: simple powerful testing with Python Home-page: http://pytest.org Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others -Author-email: holger at merlinux.eu +Author-email: UNKNOWN License: MIT license Description: .. image:: http://docs.pytest.org/en/latest/_static/pytest1.png :target: http://docs.pytest.org diff -Nru pytest-3.0.5/pytest.egg-info/requires.txt pytest-3.0.6/pytest.egg-info/requires.txt --- pytest-3.0.5/pytest.egg-info/requires.txt 2016-12-05 12:22:39.000000000 +0000 +++ pytest-3.0.6/pytest.egg-info/requires.txt 2017-01-22 21:15:07.000000000 +0000 @@ -1,4 +1,5 @@ py>=1.4.29 +setuptools [:python_version=="2.6"] argparse diff -Nru pytest-3.0.5/pytest.egg-info/SOURCES.txt pytest-3.0.6/pytest.egg-info/SOURCES.txt --- pytest-3.0.5/pytest.egg-info/SOURCES.txt 2016-12-05 12:22:39.000000000 +0000 +++ pytest-3.0.6/pytest.egg-info/SOURCES.txt 2017-01-22 21:15:07.000000000 +0000 @@ -1,4 +1,6 @@ .coveragerc +.gitattributes +.gitignore AUTHORS CHANGELOG.rst CONTRIBUTING.rst @@ -96,6 +98,7 @@ doc/en/naming20.rst doc/en/nose.rst doc/en/parametrize.rst +doc/en/parametrize.rst.orig doc/en/plugins.rst doc/en/projects.rst doc/en/pytest.ini @@ -168,6 +171,7 @@ doc/en/announce/release-3.0.3.rst doc/en/announce/release-3.0.4.rst doc/en/announce/release-3.0.5.rst +doc/en/announce/release-3.0.6.rst doc/en/announce/sprint2016.rst doc/en/example/attic.rst doc/en/example/conftest.py @@ -246,6 +250,7 @@ testing/test_cache.py testing/test_capture.py testing/test_collection.py +testing/test_compat.py testing/test_config.py testing/test_conftest.py testing/test_doctest.py @@ -283,6 +288,7 @@ testing/python/fixture.py testing/python/integration.py testing/python/metafunc.py +testing/python/metafunc.py.orig testing/python/raises.py testing/python/setup_only.py testing/python/setup_plan.py diff -Nru pytest-3.0.5/setup.cfg pytest-3.0.6/setup.cfg --- pytest-3.0.5/setup.cfg 2016-12-05 12:22:39.000000000 +0000 +++ pytest-3.0.6/setup.cfg 2017-01-22 21:15:07.000000000 +0000 @@ -9,11 +9,13 @@ [bdist_wheel] universal = 1 +[metadata] +license_file = LICENSE + [devpi:upload] formats = sdist.tgz,bdist_wheel [egg_info] tag_build = tag_date = 0 -tag_svn_revision = 0 diff -Nru pytest-3.0.5/setup.py pytest-3.0.6/setup.py --- pytest-3.0.5/setup.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/setup.py 2017-01-22 21:14:36.000000000 +0000 @@ -48,7 +48,7 @@ def main(): - install_requires = ['py>=1.4.29'] # pluggy is vendored in _pytest.vendored_packages + install_requires = ['py>=1.4.29', 'setuptools'] # pluggy is vendored in _pytest.vendored_packages extras_require = {} if has_environment_marker_support(): extras_require[':python_version=="2.6"'] = ['argparse'] @@ -68,7 +68,6 @@ license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others', - author_email='holger at merlinux.eu', entry_points={'console_scripts': ['pytest=pytest:main', 'py.test=pytest:main']}, classifiers=classifiers, diff -Nru pytest-3.0.5/testing/python/metafunc.py.orig pytest-3.0.6/testing/python/metafunc.py.orig --- pytest-3.0.5/testing/python/metafunc.py.orig 1970-01-01 00:00:00.000000000 +0000 +++ pytest-3.0.6/testing/python/metafunc.py.orig 2017-01-19 09:24:23.000000000 +0000 @@ -0,0 +1,1494 @@ +# -*- coding: utf-8 -*- +import re +import sys + +import _pytest._code +import py +import pytest +from _pytest import python, fixtures + +import hypothesis +from hypothesis import strategies + +PY3 = sys.version_info >= (3, 0) + + +class TestMetafunc: + def Metafunc(self, func): + # the unit tests of this class check if things work correctly + # on the funcarg level, so we don't need a full blown + # initiliazation + class FixtureInfo: + name2fixturedefs = None + + def __init__(self, names): + self.names_closure = names + + names = fixtures.getfuncargnames(func) + fixtureinfo = FixtureInfo(names) + return python.Metafunc(func, fixtureinfo, None) + + def test_no_funcargs(self, testdir): + def function(): pass + metafunc = self.Metafunc(function) + assert not metafunc.fixturenames + repr(metafunc._calls) + + def test_function_basic(self): + def func(arg1, arg2="qwe"): pass + metafunc = self.Metafunc(func) + assert len(metafunc.fixturenames) == 1 + assert 'arg1' in metafunc.fixturenames + assert metafunc.function is func + assert metafunc.cls is None + + def test_addcall_no_args(self): + def func(arg1): pass + metafunc = self.Metafunc(func) + metafunc.addcall() + assert len(metafunc._calls) == 1 + call = metafunc._calls[0] + assert call.id == "0" + assert not hasattr(call, 'param') + + def test_addcall_id(self): + def func(arg1): pass + metafunc = self.Metafunc(func) + pytest.raises(ValueError, "metafunc.addcall(id=None)") + + metafunc.addcall(id=1) + pytest.raises(ValueError, "metafunc.addcall(id=1)") + pytest.raises(ValueError, "metafunc.addcall(id='1')") + metafunc.addcall(id=2) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].id == "1" + assert metafunc._calls[1].id == "2" + + def test_addcall_param(self): + def func(arg1): pass + metafunc = self.Metafunc(func) + + class obj: pass + + metafunc.addcall(param=obj) + metafunc.addcall(param=obj) + metafunc.addcall(param=1) + assert len(metafunc._calls) == 3 + assert metafunc._calls[0].getparam("arg1") == obj + assert metafunc._calls[1].getparam("arg1") == obj + assert metafunc._calls[2].getparam("arg1") == 1 + + def test_addcall_funcargs(self): + def func(x): pass + + metafunc = self.Metafunc(func) + + class obj: pass + + metafunc.addcall(funcargs={"x": 2}) + metafunc.addcall(funcargs={"x": 3}) + pytest.raises(pytest.fail.Exception, "metafunc.addcall({'xyz': 0})") + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {'x': 2} + assert metafunc._calls[1].funcargs == {'x': 3} + assert not hasattr(metafunc._calls[1], 'param') + + def test_parametrize_error(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize("x", [1,2]) + pytest.raises(ValueError, lambda: metafunc.parametrize("x", [5,6])) + pytest.raises(ValueError, lambda: metafunc.parametrize("x", [5,6])) + metafunc.parametrize("y", [1,2]) + pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6])) + pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6])) + + def test_parametrize_bad_scope(self, testdir): + def func(x): pass + metafunc = self.Metafunc(func) + try: + metafunc.parametrize("x", [1], scope='doggy') + except ValueError as ve: + assert "has an unsupported scope value 'doggy'" in str(ve) + + def test_parametrize_and_id(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + + metafunc.parametrize("x", [1,2], ids=['basic', 'advanced']) + metafunc.parametrize("y", ["abc", "def"]) + ids = [x.id for x in metafunc._calls] + assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"] + + def test_parametrize_and_id_unicode(self): + """Allow unicode strings for "ids" parameter in Python 2 (##1905)""" + def func(x): pass + metafunc = self.Metafunc(func) + metafunc.parametrize("x", [1, 2], ids=[u'basic', u'advanced']) + ids = [x.id for x in metafunc._calls] + assert ids == [u"basic", u"advanced"] + + def test_parametrize_with_wrong_number_of_ids(self, testdir): + def func(x, y): pass + metafunc = self.Metafunc(func) + + pytest.raises(ValueError, lambda: + metafunc.parametrize("x", [1,2], ids=['basic'])) + + pytest.raises(ValueError, lambda: + metafunc.parametrize(("x","y"), [("abc", "def"), + ("ghi", "jkl")], ids=["one"])) + + @pytest.mark.issue510 + def test_parametrize_empty_list(self): + def func( y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize("y", []) + assert 'skip' in metafunc._calls[0].keywords + + def test_parametrize_with_userobjects(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + + class A: + pass + + metafunc.parametrize("x", [A(), A()]) + metafunc.parametrize("y", list("ab")) + assert metafunc._calls[0].id == "x0-a" + assert metafunc._calls[1].id == "x0-b" + assert metafunc._calls[2].id == "x1-a" + assert metafunc._calls[3].id == "x1-b" + + @hypothesis.given(strategies.text() | strategies.binary()) + def test_idval_hypothesis(self, value): + from _pytest.python import _idval + escaped = _idval(value, 'a', 6, None) + assert isinstance(escaped, str) + if PY3: + escaped.encode('ascii') + else: + escaped.decode('ascii') + + def test_unicode_idval(self): + """This tests that Unicode strings outside the ASCII character set get + escaped, using byte escapes if they're in that range or unicode + escapes if they're not. + + """ + from _pytest.python import _idval + values = [ + (u'', ''), + (u'ascii', 'ascii'), + (u'ação', 'a\\xe7\\xe3o'), + (u'josé@blah.com', 'jos\\xe9@blah.com'), + (u'δοκ.ιμή@παράδειγμα.δοκιμή', '\\u03b4\\u03bf\\u03ba.\\u03b9\\u03bc\\u03ae@\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1.\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae'), + ] + for val, expected in values: + assert _idval(val, 'a', 6, None) == expected + + def test_bytes_idval(self): + """unittest for the expected behavior to obtain ids for parametrized + bytes values: + - python2: non-ascii strings are considered bytes and formatted using + "binary escape", where any byte < 127 is escaped into its hex form. + - python3: bytes objects are always escaped using "binary escape". + """ + from _pytest.python import _idval + values = [ + (b'', ''), + (b'\xc3\xb4\xff\xe4', '\\xc3\\xb4\\xff\\xe4'), + (b'ascii', 'ascii'), + (u'αρά'.encode('utf-8'), '\\xce\\xb1\\xcf\\x81\\xce\\xac'), + ] + for val, expected in values: + assert _idval(val, 'a', 6, None) == expected + + @pytest.mark.issue250 + def test_idmaker_autoname(self): + from _pytest.python import idmaker + result = idmaker(("a", "b"), [pytest.param("string", 1.0), + pytest.param("st-ring", 2.0)]) + assert result == ["string-1.0", "st-ring-2.0"] + + result = idmaker(("a", "b"), [pytest.param(object(), 1.0), + pytest.param(object(), object())]) + assert result == ["a0-1.0", "a1-b1"] + # unicode mixing, issue250 + result = idmaker((py.builtin._totext("a"), "b"), [pytest.param({}, b'\xc3\xb4')]) + assert result == ['a0-\\xc3\\xb4'] + + def test_idmaker_with_bytes_regex(self): + from _pytest.python import idmaker + result = idmaker(("a"), [pytest.param(re.compile(b'foo'), 1.0)]) + assert result == ["foo"] + + def test_idmaker_native_strings(self): + from _pytest.python import idmaker + totext = py.builtin._totext + result = idmaker(("a", "b"), [ + pytest.param(1.0, -1.1), + pytest.param(2, -202), + pytest.param("three", "three hundred"), + pytest.param(True, False), + pytest.param(None, None), + pytest.param(re.compile('foo'), re.compile('bar')), + pytest.param(str, int), + pytest.param(list("six"), [66, 66]), + pytest.param(set([7]), set("seven")), + pytest.param(tuple("eight"), (8, -8, 8)), + pytest.param(b'\xc3\xb4', b"name"), + pytest.param(b'\xc3\xb4', totext("other")), + ]) + assert result == ["1.0--1.1", + "2--202", + "three-three hundred", + "True-False", + "None-None", + "foo-bar", + "str-int", + "a7-b7", + "a8-b8", + "a9-b9", + "\\xc3\\xb4-name", + "\\xc3\\xb4-other", + ] + + def test_idmaker_enum(self): + from _pytest.python import idmaker + enum = pytest.importorskip("enum") + e = enum.Enum("Foo", "one, two") + result = idmaker(("a", "b"), [pytest.param(e.one, e.two)]) + assert result == ["Foo.one-Foo.two"] + + @pytest.mark.issue351 + def test_idmaker_idfn(self): + from _pytest.python import idmaker + + def ids(val): + if isinstance(val, Exception): + return repr(val) + + result = idmaker(("a", "b"), [pytest.param(10.0, IndexError()), + pytest.param(20, KeyError()), + pytest.param("three", [1, 2, 3]), + ], idfn=ids) + assert result == ["10.0-IndexError()", + "20-KeyError()", + "three-b2", + ] + + @pytest.mark.issue351 + def test_idmaker_idfn_unique_names(self): + from _pytest.python import idmaker + + def ids(val): + return 'a' + + result = idmaker(("a", "b"), [pytest.param(10.0, IndexError()), + pytest.param(20, KeyError()), + pytest.param("three", [1, 2, 3]), + ], idfn=ids) + assert result == ["a-a0", + "a-a1", + "a-a2", + ] + + @pytest.mark.issue351 + def test_idmaker_idfn_exception(self): + from _pytest.python import idmaker + from _pytest.recwarn import WarningsRecorder + + class BadIdsException(Exception): + pass + + def ids(val): + raise BadIdsException("ids raised") + + rec = WarningsRecorder() + with rec: + idmaker(("a", "b"), [(10.0, IndexError()), + (20, KeyError()), + ("three", [1, 2, 3]), + ], idfn=ids) + + assert [str(i.message) for i in rec.list] == [ + "Raised while trying to determine id of parameter a at position 0." + "\nUpdate your code as this will raise an error in pytest-4.0.", + "Raised while trying to determine id of parameter b at position 0." + "\nUpdate your code as this will raise an error in pytest-4.0.", + "Raised while trying to determine id of parameter a at position 1." + "\nUpdate your code as this will raise an error in pytest-4.0.", + "Raised while trying to determine id of parameter b at position 1." + "\nUpdate your code as this will raise an error in pytest-4.0.", + "Raised while trying to determine id of parameter a at position 2." + "\nUpdate your code as this will raise an error in pytest-4.0.", + "Raised while trying to determine id of parameter b at position 2." + "\nUpdate your code as this will raise an error in pytest-4.0.", + ] + +<<<<<<< HEAD + + def test_parametrize_ids_exception(self, testdir): + """ + :param testdir: the instance of Testdir class, a temporary + test directory. + """ + testdir.makepyfile(""" + import pytest + + def ids(arg): + raise Exception("bad ids") + + @pytest.mark.parametrize("arg", ["a", "b"], ids=ids) + def test_foo(arg): + pass + """) + result = testdir.runpytest("--collect-only") + result.stdout.fnmatch_lines([ + "", + " ", + " ", + ]) +======= + result = idmaker(("a", "b"), [pytest.param(10.0, IndexError()), + pytest.param(20, KeyError()), + pytest.param("three", [1, 2, 3]), + ], idfn=ids) + assert result == ["10.0-b0", + "20-b1", + "three-b2", + ] +>>>>>>> correct idmaker and calls to parameterset + + def test_idmaker_with_ids(self): + from _pytest.python import idmaker + result = idmaker(("a", "b"), [pytest.param(1, 2), + pytest.param(3, 4)], + ids=["a", None]) + assert result == ["a", "3-4"] + + def test_idmaker_with_ids_unique_names(self): + from _pytest.python import idmaker + result = idmaker(("a"), map(pytest.param, [1,2,3,4,5]), + ids=["a", "a", "b", "c", "b"]) + assert result == ["a0", "a1", "b0", "c", "b1"] + + def test_addcall_and_parametrize(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.addcall({'x': 1}) + metafunc.parametrize('y', [2,3]) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {'x': 1, 'y': 2} + assert metafunc._calls[1].funcargs == {'x': 1, 'y': 3} + assert metafunc._calls[0].id == "0-2" + assert metafunc._calls[1].id == "0-3" + + @pytest.mark.issue714 + def test_parametrize_indirect(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize('x', [1], indirect=True) + metafunc.parametrize('y', [2,3], indirect=True) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {} + assert metafunc._calls[1].funcargs == {} + assert metafunc._calls[0].params == dict(x=1,y=2) + assert metafunc._calls[1].params == dict(x=1,y=3) + + @pytest.mark.issue714 + def test_parametrize_indirect_list(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize('x, y', [('a', 'b')], indirect=['x']) + assert metafunc._calls[0].funcargs == dict(y='b') + assert metafunc._calls[0].params == dict(x='a') + + @pytest.mark.issue714 + def test_parametrize_indirect_list_all(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize('x, y', [('a', 'b')], indirect=['x', 'y']) + assert metafunc._calls[0].funcargs == {} + assert metafunc._calls[0].params == dict(x='a', y='b') + + @pytest.mark.issue714 + def test_parametrize_indirect_list_empty(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize('x, y', [('a', 'b')], indirect=[]) + assert metafunc._calls[0].funcargs == dict(x='a', y='b') + assert metafunc._calls[0].params == {} + + @pytest.mark.issue714 + def test_parametrize_indirect_list_functional(self, testdir): + """ + Test parametrization with 'indirect' parameter applied on + particular arguments. As y is is direct, its value should + be used directly rather than being passed to the fixture + y. + + :param testdir: the instance of Testdir class, a temporary + test directory. + """ + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope='function') + def x(request): + return request.param * 3 + @pytest.fixture(scope='function') + def y(request): + return request.param * 2 + @pytest.mark.parametrize('x, y', [('a', 'b')], indirect=['x']) + def test_simple(x,y): + assert len(x) == 3 + assert len(y) == 1 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*test_simple*a-b*", + "*1 passed*", + ]) + + @pytest.mark.issue714 + def test_parametrize_indirect_list_error(self, testdir): + def func(x, y): pass + metafunc = self.Metafunc(func) + with pytest.raises(ValueError): + metafunc.parametrize('x, y', [('a', 'b')], indirect=['x', 'z']) + + @pytest.mark.issue714 + def test_parametrize_uses_no_fixture_error_indirect_false(self, testdir): + """The 'uses no fixture' error tells the user at collection time + that the parametrize data they've set up doesn't correspond to the + fixtures in their test function, rather than silently ignoring this + and letting the test potentially pass. + """ + testdir.makepyfile(""" + import pytest + + @pytest.mark.parametrize('x, y', [('a', 'b')], indirect=False) + def test_simple(x): + assert len(x) == 3 + """) + result = testdir.runpytest("--collect-only") + result.stdout.fnmatch_lines([ + "*uses no argument 'y'*", + ]) + + @pytest.mark.issue714 + def test_parametrize_uses_no_fixture_error_indirect_true(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope='function') + def x(request): + return request.param * 3 + @pytest.fixture(scope='function') + def y(request): + return request.param * 2 + + @pytest.mark.parametrize('x, y', [('a', 'b')], indirect=True) + def test_simple(x): + assert len(x) == 3 + """) + result = testdir.runpytest("--collect-only") + result.stdout.fnmatch_lines([ + "*uses no fixture 'y'*", + ]) + + @pytest.mark.issue714 + def test_parametrize_indirect_uses_no_fixture_error_indirect_string(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope='function') + def x(request): + return request.param * 3 + + @pytest.mark.parametrize('x, y', [('a', 'b')], indirect='y') + def test_simple(x): + assert len(x) == 3 + """) + result = testdir.runpytest("--collect-only") + result.stdout.fnmatch_lines([ + "*uses no fixture 'y'*", + ]) + + @pytest.mark.issue714 + def test_parametrize_indirect_uses_no_fixture_error_indirect_list(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope='function') + def x(request): + return request.param * 3 + + @pytest.mark.parametrize('x, y', [('a', 'b')], indirect=['y']) + def test_simple(x): + assert len(x) == 3 + """) + result = testdir.runpytest("--collect-only") + result.stdout.fnmatch_lines([ + "*uses no fixture 'y'*", + ]) + + @pytest.mark.issue714 + def test_parametrize_argument_not_in_indirect_list(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope='function') + def x(request): + return request.param * 3 + + @pytest.mark.parametrize('x, y', [('a', 'b')], indirect=['x']) + def test_simple(x): + assert len(x) == 3 + """) + result = testdir.runpytest("--collect-only") + result.stdout.fnmatch_lines([ + "*uses no argument 'y'*", + ]) + + def test_addcalls_and_parametrize_indirect(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.addcall(param="123") + metafunc.parametrize('x', [1], indirect=True) + metafunc.parametrize('y', [2,3], indirect=True) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {} + assert metafunc._calls[1].funcargs == {} + assert metafunc._calls[0].params == dict(x=1,y=2) + assert metafunc._calls[1].params == dict(x=1,y=3) + + def test_parametrize_functional(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize('x', [1,2], indirect=True) + metafunc.parametrize('y', [2]) + @pytest.fixture + def x(request): + return request.param * 10 + + def test_simple(x,y): + assert x in (10,20) + assert y == 2 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*test_simple*1-2*", + "*test_simple*2-2*", + "*2 passed*", + ]) + + def test_parametrize_onearg(self): + metafunc = self.Metafunc(lambda x: None) + metafunc.parametrize("x", [1,2]) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == dict(x=1) + assert metafunc._calls[0].id == "1" + assert metafunc._calls[1].funcargs == dict(x=2) + assert metafunc._calls[1].id == "2" + + def test_parametrize_onearg_indirect(self): + metafunc = self.Metafunc(lambda x: None) + metafunc.parametrize("x", [1,2], indirect=True) + assert metafunc._calls[0].params == dict(x=1) + assert metafunc._calls[0].id == "1" + assert metafunc._calls[1].params == dict(x=2) + assert metafunc._calls[1].id == "2" + + def test_parametrize_twoargs(self): + metafunc = self.Metafunc(lambda x,y: None) + metafunc.parametrize(("x", "y"), [(1,2), (3,4)]) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == dict(x=1, y=2) + assert metafunc._calls[0].id == "1-2" + assert metafunc._calls[1].funcargs == dict(x=3, y=4) + assert metafunc._calls[1].id == "3-4" + + def test_parametrize_multiple_times(self, testdir): + testdir.makepyfile(""" + import pytest + pytestmark = pytest.mark.parametrize("x", [1,2]) + def test_func(x): + assert 0, x + class TestClass: + pytestmark = pytest.mark.parametrize("y", [3,4]) + def test_meth(self, x, y): + assert 0, x + """) + result = testdir.runpytest() + assert result.ret == 1 + result.assert_outcomes(failed=6) + + def test_parametrize_CSV(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize("x, y,", [(1,2), (2,3)]) + def test_func(x, y): + assert x+1 == y + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_parametrize_class_scenarios(self, testdir): + testdir.makepyfile(""" + # same as doc/en/example/parametrize scenario example + def pytest_generate_tests(metafunc): + idlist = [] + argvalues = [] + for scenario in metafunc.cls.scenarios: + idlist.append(scenario[0]) + items = scenario[1].items() + argnames = [x[0] for x in items] + argvalues.append(([x[1] for x in items])) + metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class") + + class Test(object): + scenarios = [['1', {'arg': {1: 2}, "arg2": "value2"}], + ['2', {'arg':'value2', "arg2": "value2"}]] + + def test_1(self, arg, arg2): + pass + + def test_2(self, arg2, arg): + pass + + def test_3(self, arg, arg2): + pass + """) + result = testdir.runpytest("-v") + assert result.ret == 0 + result.stdout.fnmatch_lines(""" + *test_1*1* + *test_2*1* + *test_3*1* + *test_1*2* + *test_2*2* + *test_3*2* + *6 passed* + """) + + def test_format_args(self): + def function1(): pass + assert fixtures._format_args(function1) == '()' + + def function2(arg1): pass + assert fixtures._format_args(function2) == "(arg1)" + + def function3(arg1, arg2="qwe"): pass + assert fixtures._format_args(function3) == "(arg1, arg2='qwe')" + + def function4(arg1, *args, **kwargs): pass + assert fixtures._format_args(function4) == "(arg1, *args, **kwargs)" + + +class TestMetafuncFunctional: + def test_attributes(self, testdir): + p = testdir.makepyfile(""" + # assumes that generate/provide runs in the same process + import py, pytest + def pytest_generate_tests(metafunc): + metafunc.addcall(param=metafunc) + + @pytest.fixture + def metafunc(request): + assert request._pyfuncitem._genid == "0" + return request.param + + def test_function(metafunc, pytestconfig): + assert metafunc.config == pytestconfig + assert metafunc.module.__name__ == __name__ + assert metafunc.function == test_function + assert metafunc.cls is None + + class TestClass: + def test_method(self, metafunc, pytestconfig): + assert metafunc.config == pytestconfig + assert metafunc.module.__name__ == __name__ + if py.std.sys.version_info > (3, 0): + unbound = TestClass.test_method + else: + unbound = TestClass.test_method.im_func + # XXX actually have an unbound test function here? + assert metafunc.function == unbound + assert metafunc.cls == TestClass + """) + result = testdir.runpytest(p, "-v") + result.assert_outcomes(passed=2) + + def test_addcall_with_two_funcargs_generators(self, testdir): + testdir.makeconftest(""" + def pytest_generate_tests(metafunc): + assert "arg1" in metafunc.fixturenames + metafunc.addcall(funcargs=dict(arg1=1, arg2=2)) + """) + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall(funcargs=dict(arg1=1, arg2=1)) + + class TestClass: + def test_myfunc(self, arg1, arg2): + assert arg1 == arg2 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_myfunc*0*PASS*", + "*test_myfunc*1*FAIL*", + "*1 failed, 1 passed*" + ]) + + def test_two_functions(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall(param=10) + metafunc.addcall(param=20) + + import pytest + @pytest.fixture + def arg1(request): + return request.param + + def test_func1(arg1): + assert arg1 == 10 + def test_func2(arg1): + assert arg1 in (10, 20) + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func1*0*PASS*", + "*test_func1*1*FAIL*", + "*test_func2*PASS*", + "*1 failed, 3 passed*" + ]) + + def test_noself_in_method(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + assert 'xyz' not in metafunc.fixturenames + + class TestHello: + def test_hello(xyz): + pass + """) + result = testdir.runpytest(p) + result.assert_outcomes(passed=1) + + + def test_generate_plugin_and_module(self, testdir): + testdir.makeconftest(""" + def pytest_generate_tests(metafunc): + assert "arg1" in metafunc.fixturenames + metafunc.addcall(id="world", param=(2,100)) + """) + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall(param=(1,1), id="hello") + + import pytest + @pytest.fixture + def arg1(request): + return request.param[0] + @pytest.fixture + def arg2(request): + return request.param[1] + + class TestClass: + def test_myfunc(self, arg1, arg2): + assert arg1 == arg2 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_myfunc*hello*PASS*", + "*test_myfunc*world*FAIL*", + "*1 failed, 1 passed*" + ]) + + def test_generate_tests_in_class(self, testdir): + p = testdir.makepyfile(""" + class TestClass: + def pytest_generate_tests(self, metafunc): + metafunc.addcall(funcargs={'hello': 'world'}, id="hello") + + def test_myfunc(self, hello): + assert hello == "world" + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_myfunc*hello*PASS*", + "*1 passed*" + ]) + + def test_two_functions_not_same_instance(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall({'arg1': 10}) + metafunc.addcall({'arg1': 20}) + + class TestClass: + def test_func(self, arg1): + assert not hasattr(self, 'x') + self.x = 1 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func*0*PASS*", + "*test_func*1*PASS*", + "*2 pass*", + ]) + + def test_issue28_setup_method_in_generate_tests(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall({'arg1': 1}) + + class TestClass: + def test_method(self, arg1): + assert arg1 == self.val + def setup_method(self, func): + self.val = 1 + """) + result = testdir.runpytest(p) + result.assert_outcomes(passed=1) + + def test_parametrize_functional2(self, testdir): + testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.parametrize("arg1", [1,2]) + metafunc.parametrize("arg2", [4,5]) + def test_hello(arg1, arg2): + assert 0, (arg1, arg2) + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*(1, 4)*", + "*(1, 5)*", + "*(2, 4)*", + "*(2, 5)*", + "*4 failed*", + ]) + + 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) + + import pytest + @pytest.fixture + def arg1(request): + x = request.getfixturevalue("arg2") + return x + request.param + + @pytest.fixture + def arg2(request): + return request.param + + def test_func1(arg1, arg2): + assert arg1 == 11 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func1*1*PASS*", + "*1 passed*" + ]) + + def test_parametrize_on_setup_arg(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + assert "arg1" in metafunc.fixturenames + metafunc.parametrize("arg1", [1], indirect=True) + + import pytest + @pytest.fixture + def arg1(request): + return request.param + + @pytest.fixture + def arg2(request, arg1): + return 10 * arg1 + + def test_func(arg2): + assert arg2 == 10 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func*1*PASS*", + "*1 passed*" + ]) + + def test_parametrize_with_ids(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize(("a", "b"), [(1,1), (1,2)], + ids=["basic", "advanced"]) + + def test_function(a, b): + assert a == b + """) + result = testdir.runpytest("-v") + assert result.ret == 1 + result.stdout.fnmatch_lines_random([ + "*test_function*basic*PASSED", + "*test_function*advanced*FAILED", + ]) + + def test_parametrize_without_ids(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize(("a", "b"), + [(1,object()), (1.3,object())]) + + def test_function(a, b): + assert 1 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines(""" + *test_function*1-b0* + *test_function*1.3-b1* + """) + + def test_parametrize_with_None_in_ids(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize(("a", "b"), [(1,1), (1,1), (1,2)], + ids=["basic", None, "advanced"]) + + def test_function(a, b): + assert a == b + """) + result = testdir.runpytest("-v") + assert result.ret == 1 + result.stdout.fnmatch_lines_random([ + "*test_function*basic*PASSED", + "*test_function*1-1*PASSED", + "*test_function*advanced*FAILED", + ]) + + def test_fixture_parametrized_empty_ids(self, testdir): + """Fixtures parametrized with empty ids cause an internal error (#1849).""" + testdir.makepyfile(''' + import pytest + + @pytest.fixture(scope="module", ids=[], params=[]) + def temp(request): + return request.param + + def test_temp(temp): + pass + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['* 1 skipped *']) + + def test_parametrized_empty_ids(self, testdir): + """Tests parametrized with empty ids cause an internal error (#1849).""" + testdir.makepyfile(''' + import pytest + + @pytest.mark.parametrize('temp', [], ids=list()) + def test_temp(temp): + pass + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['* 1 skipped *']) + + def test_parametrized_ids_invalid_type(self, testdir): + """Tests parametrized with ids as non-strings (#1857).""" + testdir.makepyfile(''' + import pytest + + @pytest.mark.parametrize("x, expected", [(10, 20), (40, 80)], ids=(None, 2)) + def test_ids_numbers(x,expected): + assert x * 2 == expected + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['*ids must be list of strings, found: 2 (type: int)*']) + + def test_parametrize_with_identical_ids_get_unique_names(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize(("a", "b"), [(1,1), (1,2)], + ids=["a", "a"]) + + def test_function(a, b): + assert a == b + """) + result = testdir.runpytest("-v") + assert result.ret == 1 + result.stdout.fnmatch_lines_random([ + "*test_function*a0*PASSED", + "*test_function*a1*FAILED" + ]) + + @pytest.mark.parametrize(("scope", "length"), + [("module", 2), ("function", 4)]) + def test_parametrize_scope_overrides(self, testdir, scope, length): + testdir.makepyfile(""" + import pytest + l = [] + def pytest_generate_tests(metafunc): + if "arg" in metafunc.funcargnames: + metafunc.parametrize("arg", [1,2], indirect=True, + scope=%r) + @pytest.fixture + def arg(request): + l.append(request.param) + return request.param + def test_hello(arg): + assert arg in (1,2) + def test_world(arg): + assert arg in (1,2) + def test_checklength(): + assert len(l) == %d + """ % (scope, length)) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=5) + + def test_parametrize_issue323(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(scope='module', params=range(966)) + def foo(request): + return request.param + + def test_it(foo): + pass + def test_it2(foo): + pass + """) + reprec = testdir.inline_run("--collect-only") + assert not reprec.getcalls("pytest_internalerror") + + def test_usefixtures_seen_in_generate_tests(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + assert "abc" in metafunc.fixturenames + metafunc.parametrize("abc", [1]) + + @pytest.mark.usefixtures("abc") + def test_function(): + pass + """) + reprec = testdir.runpytest() + reprec.assert_outcomes(passed=1) + + def test_generate_tests_only_done_in_subdir(self, testdir): + sub1 = testdir.mkpydir("sub1") + sub2 = testdir.mkpydir("sub2") + sub1.join("conftest.py").write(_pytest._code.Source(""" + def pytest_generate_tests(metafunc): + assert metafunc.function.__name__ == "test_1" + """)) + sub2.join("conftest.py").write(_pytest._code.Source(""" + def pytest_generate_tests(metafunc): + assert metafunc.function.__name__ == "test_2" + """)) + sub1.join("test_in_sub1.py").write("def test_1(): pass") + sub2.join("test_in_sub2.py").write("def test_2(): pass") + result = testdir.runpytest("--keep-duplicates", "-v", "-s", sub1, sub2, sub1) + result.assert_outcomes(passed=3) + + def test_generate_same_function_names_issue403(self, testdir): + testdir.makepyfile(""" + import pytest + + def make_tests(): + @pytest.mark.parametrize("x", range(2)) + def test_foo(x): + pass + return test_foo + + test_x = make_tests() + test_y = make_tests() + """) + reprec = testdir.runpytest() + reprec.assert_outcomes(passed=4) + + @pytest.mark.issue463 + @pytest.mark.parametrize('attr', ['parametrise', 'parameterize', + 'parameterise']) + def test_parametrize_misspelling(self, testdir, attr): + testdir.makepyfile(""" + import pytest + + @pytest.mark.{0}("x", range(2)) + def test_foo(x): + pass + """.format(attr)) + reprec = testdir.inline_run('--collectonly') + failures = reprec.getfailures() + assert len(failures) == 1 + expectederror = "MarkerError: test_foo has '{0}', spelling should be 'parametrize'".format(attr) + assert expectederror in failures[0].longrepr.reprcrash.message + + +class TestMetafuncFunctionalAuto: + """ + Tests related to automatically find out the correct scope for parametrized tests (#1832). + """ + + def test_parametrize_auto_scope(self, testdir): + testdir.makepyfile(''' + import pytest + + @pytest.fixture(scope='session', autouse=True) + def fixture(): + return 1 + + @pytest.mark.parametrize('animal', ["dog", "cat"]) + def test_1(animal): + assert animal in ('dog', 'cat') + + @pytest.mark.parametrize('animal', ['fish']) + def test_2(animal): + assert animal == 'fish' + + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['* 3 passed *']) + + def test_parametrize_auto_scope_indirect(self, testdir): + testdir.makepyfile(''' + import pytest + + @pytest.fixture(scope='session') + def echo(request): + return request.param + + @pytest.mark.parametrize('animal, echo', [("dog", 1), ("cat", 2)], indirect=['echo']) + def test_1(animal, echo): + assert animal in ('dog', 'cat') + assert echo in (1, 2, 3) + + @pytest.mark.parametrize('animal, echo', [('fish', 3)], indirect=['echo']) + def test_2(animal, echo): + assert animal == 'fish' + assert echo in (1, 2, 3) + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['* 3 passed *']) + + def test_parametrize_auto_scope_override_fixture(self, testdir): + testdir.makepyfile(''' + import pytest + + @pytest.fixture(scope='session', autouse=True) + def animal(): + return 'fox' + + @pytest.mark.parametrize('animal', ["dog", "cat"]) + def test_1(animal): + assert animal in ('dog', 'cat') + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['* 2 passed *']) + + def test_parametrize_all_indirects(self, testdir): + testdir.makepyfile(''' + import pytest + + @pytest.fixture() + def animal(request): + return request.param + + @pytest.fixture(scope='session') + def echo(request): + return request.param + + @pytest.mark.parametrize('animal, echo', [("dog", 1), ("cat", 2)], indirect=True) + def test_1(animal, echo): + assert animal in ('dog', 'cat') + assert echo in (1, 2, 3) + + @pytest.mark.parametrize('animal, echo', [("fish", 3)], indirect=True) + def test_2(animal, echo): + assert animal == 'fish' + assert echo in (1, 2, 3) + ''') + result = testdir.runpytest() + result.stdout.fnmatch_lines(['* 3 passed *']) + + 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 + + +class TestMarkersWithParametrization: + pytestmark = pytest.mark.issue308 + def test_simple_mark(self, testdir): + s = """ + import pytest + + @pytest.mark.foo + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.bar((1, 3)), + (2, 3), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + items = testdir.getitems(s) + assert len(items) == 3 + for item in items: + assert 'foo' in item.keywords + assert 'bar' not in items[0].keywords + assert 'bar' in items[1].keywords + assert 'bar' not in items[2].keywords + + def test_select_based_on_mark(self, testdir): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.foo((2, 3)), + (3, 4), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + testdir.makepyfile(s) + rec = testdir.inline_run("-m", 'foo') + passed, skipped, fail = rec.listoutcomes() + assert len(passed) == 1 + assert len(skipped) == 0 + assert len(fail) == 0 + + @pytest.mark.xfail(reason="is this important to support??") + def test_nested_marks(self, testdir): + s = """ + import pytest + mastermark = pytest.mark.foo(pytest.mark.bar) + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + mastermark((1, 3)), + (2, 3), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + items = testdir.getitems(s) + assert len(items) == 3 + for mark in ['foo', 'bar']: + assert mark not in items[0].keywords + assert mark in items[1].keywords + assert mark not in items[2].keywords + + def test_simple_xfail(self, testdir): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.xfail((1, 3)), + (2, 3), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + testdir.makepyfile(s) + reprec = testdir.inline_run() + # xfail is skip?? + reprec.assertoutcome(passed=2, skipped=1) + + def test_simple_xfail_single_argname(self, testdir): + s = """ + import pytest + + @pytest.mark.parametrize("n", [ + 2, + pytest.mark.xfail(3), + 4, + ]) + def test_isEven(n): + assert n % 2 == 0 + """ + testdir.makepyfile(s) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2, skipped=1) + + def test_xfail_with_arg(self, testdir): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.xfail("True")((1, 3)), + (2, 3), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + testdir.makepyfile(s) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2, skipped=1) + + def test_xfail_with_kwarg(self, testdir): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.xfail(reason="some bug")((1, 3)), + (2, 3), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + testdir.makepyfile(s) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2, skipped=1) + + def test_xfail_with_arg_and_kwarg(self, testdir): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.xfail("True", reason="some bug")((1, 3)), + (2, 3), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """ + testdir.makepyfile(s) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2, skipped=1) + + @pytest.mark.parametrize('strict', [True, False]) + def test_xfail_passing_is_xpass(self, testdir, strict): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + (1, 2), + pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict})((2, 3)), + (3, 4), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """.format(strict=strict) + testdir.makepyfile(s) + reprec = testdir.inline_run() + passed, failed = (2, 1) if strict else (3, 0) + reprec.assertoutcome(passed=passed, failed=failed) + + def test_parametrize_called_in_generate_tests(self, testdir): + s = """ + import pytest + + + def pytest_generate_tests(metafunc): + passingTestData = [(1, 2), + (2, 3)] + failingTestData = [(1, 3), + (2, 2)] + + testData = passingTestData + [pytest.mark.xfail(d) + for d in failingTestData] + metafunc.parametrize(("n", "expected"), testData) + + + def test_increment(n, expected): + assert n + 1 == expected + """ + testdir.makepyfile(s) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2, skipped=2) + + + @pytest.mark.issue290 + def test_parametrize_ID_generation_string_int_works(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture + def myfixture(): + return 'example' + @pytest.mark.parametrize( + 'limit', (0, '0')) + def test_limit(limit, myfixture): + return + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + + @pytest.mark.parametrize('strict', [True, False]) + def test_parametrize_marked_value(self, testdir, strict): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + pytest.param( + 2,3, + marks=pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict}), + ), + pytest.param( + 2,3, + marks=[pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict})], + ), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """.format(strict=strict) + testdir.makepyfile(s) + reprec = testdir.inline_run() + passed, failed = (0, 2) if strict else (2, 0) + reprec.assertoutcome(passed=passed, failed=failed) + + + def test_pytest_make_parametrize_id(self, testdir): + testdir.makeconftest(""" + def pytest_make_parametrize_id(config, val): + return str(val * 2) + """) + testdir.makepyfile(""" + import pytest + + @pytest.mark.parametrize("x", range(2)) + def test_func(x): + pass + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*test_func*0*PASS*", + "*test_func*2*PASS*", + ]) diff -Nru pytest-3.0.5/testing/test_assertion.py pytest-3.0.6/testing/test_assertion.py --- pytest-3.0.5/testing/test_assertion.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_assertion.py 2017-01-20 16:40:36.000000000 +0000 @@ -58,6 +58,23 @@ assert 0 result.stdout.fnmatch_lines([expected]) + def test_rewrite_assertions_pytester_plugin(self, testdir): + """ + Assertions in the pytester plugin must also benefit from assertion + rewriting (#1920). + """ + testdir.makepyfile(""" + pytest_plugins = ['pytester'] + def test_dummy_failure(testdir): # how meta! + testdir.makepyfile('def test(): assert 0') + r = testdir.inline_run() + r.assertoutcome(passed=1) + """) + result = testdir.runpytest_subprocess() + result.stdout.fnmatch_lines([ + '*assert 1 == 0*', + ]) + @pytest.mark.parametrize('mode', ['plain', 'rewrite']) def test_pytest_plugins_rewrite(self, testdir, mode): contents = { diff -Nru pytest-3.0.5/testing/test_assertrewrite.py pytest-3.0.6/testing/test_assertrewrite.py --- pytest-3.0.5/testing/test_assertrewrite.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_assertrewrite.py 2017-01-20 16:40:21.000000000 +0000 @@ -682,7 +682,7 @@ hook.mark_rewrite('test_remember_rewritten_modules') assert warnings == [] - def test_rewrite_warning_using_pytest_plugins(self, testdir, monkeypatch): + def test_rewrite_warning_using_pytest_plugins(self, testdir): testdir.makepyfile(**{ 'conftest.py': "pytest_plugins = ['core', 'gui', 'sci']", 'core.py': "", @@ -692,6 +692,22 @@ }) testdir.chdir() result = testdir.runpytest_subprocess() + result.stdout.fnmatch_lines(['*= 1 passed in *=*']) + assert 'pytest-warning summary' not in result.stdout.str() + + def test_rewrite_warning_using_pytest_plugins_env_var(self, testdir, monkeypatch): + monkeypatch.setenv('PYTEST_PLUGINS', 'plugin') + testdir.makepyfile(**{ + 'plugin.py': "", + 'test_rewrite_warning_using_pytest_plugins_env_var.py': """ + import plugin + pytest_plugins = ['plugin'] + def test(): + pass + """, + }) + testdir.chdir() + result = testdir.runpytest_subprocess() result.stdout.fnmatch_lines(['*= 1 passed in *=*']) assert 'pytest-warning summary' not in result.stdout.str() diff -Nru pytest-3.0.5/testing/test_compat.py pytest-3.0.6/testing/test_compat.py --- pytest-3.0.5/testing/test_compat.py 1970-01-01 00:00:00.000000000 +0000 +++ pytest-3.0.6/testing/test_compat.py 2017-01-20 16:40:21.000000000 +0000 @@ -0,0 +1,50 @@ +import sys + +import pytest +from _pytest.compat import is_generator + + +def test_is_generator(): + def zap(): + yield + + def foo(): + pass + + assert is_generator(zap) + assert not is_generator(foo) + + +@pytest.mark.skipif(sys.version_info < (3, 4), reason='asyncio available in Python 3.4+') +def test_is_generator_asyncio(testdir): + testdir.makepyfile(""" + from _pytest.compat import is_generator + import asyncio + @asyncio.coroutine + def baz(): + yield from [1,2,3] + + def test_is_generator_asyncio(): + assert not is_generator(baz) + """) + # avoid importing asyncio into pytest's own process, which in turn imports logging (#8) + result = testdir.runpytest_subprocess() + result.stdout.fnmatch_lines(['*1 passed*']) + + +@pytest.mark.skipif(sys.version_info < (3, 5), reason='async syntax available in Python 3.5+') +def test_is_generator_async_syntax(testdir): + testdir.makepyfile(""" + from _pytest.compat import is_generator + def test_is_generator_py35(): + async def foo(): + await foo() + + async def bar(): + pass + + assert not is_generator(foo) + assert not is_generator(bar) + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines(['*1 passed*']) diff -Nru pytest-3.0.5/testing/test_config.py pytest-3.0.6/testing/test_config.py --- pytest-3.0.5/testing/test_config.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_config.py 2017-01-20 16:40:21.000000000 +0000 @@ -527,6 +527,29 @@ result = testdir.runpytest("-m", "hello" * 500) assert result.ret == EXIT_NOTESTSCOLLECTED +def test_config_in_subdirectory_colon_command_line_issue2148(testdir): + conftest_source = ''' + def pytest_addoption(parser): + parser.addini('foo', 'foo') + ''' + + testdir.makefile('.ini', **{ + 'pytest': '[pytest]\nfoo = root', + 'subdir/pytest': '[pytest]\nfoo = subdir', + }) + + testdir.makepyfile(**{ + 'conftest': conftest_source, + 'subdir/conftest': conftest_source, + 'subdir/test_foo': ''' + def test_foo(pytestconfig): + assert pytestconfig.getini('foo') == 'subdir' + '''}) + + result = testdir.runpytest('subdir/test_foo.py::test_foo') + assert result.ret == 0 + + def test_notify_exception(testdir, capfd): config = testdir.parseconfig() excinfo = pytest.raises(ValueError, "raise ValueError(1)") @@ -564,6 +587,21 @@ assert [x.function.__module__ for x in l] == expected +def test_get_plugin_specs_as_list(): + from _pytest.config import _get_plugin_specs_as_list + with pytest.raises(pytest.UsageError): + _get_plugin_specs_as_list(set(['foo'])) + with pytest.raises(pytest.UsageError): + _get_plugin_specs_as_list(dict()) + + assert _get_plugin_specs_as_list(None) == [] + assert _get_plugin_specs_as_list('') == [] + assert _get_plugin_specs_as_list('foo') == ['foo'] + assert _get_plugin_specs_as_list('foo,bar') == ['foo', 'bar'] + assert _get_plugin_specs_as_list(['foo', 'bar']) == ['foo', 'bar'] + assert _get_plugin_specs_as_list(('foo', 'bar')) == ['foo', 'bar'] + + class TestWarning: def test_warn_config(self, testdir): testdir.makeconftest(""" diff -Nru pytest-3.0.5/testing/test_doctest.py pytest-3.0.6/testing/test_doctest.py --- pytest-3.0.5/testing/test_doctest.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_doctest.py 2017-01-20 16:40:21.000000000 +0000 @@ -1,9 +1,11 @@ # encoding: utf-8 import sys import _pytest._code +from _pytest.compat import MODULE_NOT_FOUND_ERROR from _pytest.doctest import DoctestItem, DoctestModule, DoctestTextfile import pytest + class TestDoctests: def test_collect_testtextfile(self, testdir): @@ -211,8 +213,8 @@ # doctest is never executed because of error during hello.py collection result.stdout.fnmatch_lines([ "*>>> import asdals*", - "*UNEXPECTED*ImportError*", - "ImportError: No module named *asdal*", + "*UNEXPECTED*{e}*".format(e=MODULE_NOT_FOUND_ERROR), + "{e}: No module named *asdal*".format(e=MODULE_NOT_FOUND_ERROR), ]) def test_doctest_unex_importerror_with_module(self, testdir): @@ -227,7 +229,7 @@ # doctest is never executed because of error during hello.py collection result.stdout.fnmatch_lines([ "*ERROR collecting hello.py*", - "*ImportError: No module named *asdals*", + "*{e}: No module named *asdals*".format(e=MODULE_NOT_FOUND_ERROR), "*Interrupted: 1 errors during collection*", ]) diff -Nru pytest-3.0.5/testing/test_monkeypatch.py pytest-3.0.6/testing/test_monkeypatch.py --- pytest-3.0.5/testing/test_monkeypatch.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_monkeypatch.py 2017-01-20 16:40:21.000000000 +0000 @@ -7,16 +7,12 @@ @pytest.fixture -def mp(request): +def mp(): cwd = os.getcwd() sys_path = list(sys.path) - - def cleanup(): - sys.path[:] = sys_path - os.chdir(cwd) - - request.addfinalizer(cleanup) - return MonkeyPatch() + yield MonkeyPatch() + sys.path[:] = sys_path + os.chdir(cwd) def test_setattr(): @@ -329,5 +325,3 @@ monkeypatch.delattr('requests.sessions.Session.request') finally: monkeypatch.undo() - - diff -Nru pytest-3.0.5/testing/test_pytester.py pytest-3.0.6/testing/test_pytester.py --- pytest-3.0.5/testing/test_pytester.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_pytester.py 2017-01-20 16:40:36.000000000 +0000 @@ -124,3 +124,10 @@ test_mod.write("def test_foo(): assert False") result2 = testdir.inline_run(str(test_mod)) assert result2.ret == EXIT_TESTSFAILED + +def test_assert_outcomes_after_pytest_erro(testdir): + testdir.makepyfile("def test_foo(): assert True") + + result = testdir.runpytest('--unexpected-argument') + with pytest.raises(ValueError, message="Pytest terminal report not found"): + result.assert_outcomes(passed=0) diff -Nru pytest-3.0.5/testing/test_recwarn.py pytest-3.0.6/testing/test_recwarn.py --- pytest-3.0.5/testing/test_recwarn.py 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/testing/test_recwarn.py 2017-01-20 16:40:21.000000000 +0000 @@ -1,4 +1,5 @@ import warnings +import re import py import pytest from _pytest.recwarn import WarningsRecorder @@ -114,7 +115,7 @@ with pytest.raises(pytest.fail.Exception) as ex: with pytest.deprecated_call(): self.dep(1) - assert str(ex.value) == "DID NOT WARN" + assert str(ex.value).startswith("DID NOT WARN") def test_deprecated_call_as_context_manager(self): with pytest.deprecated_call(): @@ -185,16 +186,38 @@ with pytest.warns(RuntimeWarning): warnings.warn("runtime", RuntimeWarning) - with pytest.raises(pytest.fail.Exception): + with pytest.warns(UserWarning): + warnings.warn("user", UserWarning) + + with pytest.raises(pytest.fail.Exception) as excinfo: with pytest.warns(RuntimeWarning): warnings.warn("user", UserWarning) + excinfo.match(r"DID NOT WARN. No warnings of type \(.+RuntimeWarning.+,\) was emitted. " + r"The list of emitted warnings is: \[UserWarning\('user',\)\].") - with pytest.raises(pytest.fail.Exception): + with pytest.raises(pytest.fail.Exception) as excinfo: with pytest.warns(UserWarning): warnings.warn("runtime", RuntimeWarning) + excinfo.match(r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) was emitted. " + r"The list of emitted warnings is: \[RuntimeWarning\('runtime',\)\].") + + with pytest.raises(pytest.fail.Exception) as excinfo: + with pytest.warns(UserWarning): + pass + excinfo.match(r"DID NOT WARN. No warnings of type \(.+UserWarning.+,\) was emitted. " + r"The list of emitted warnings is: \[\].") + + warning_classes = (UserWarning, FutureWarning) + with pytest.raises(pytest.fail.Exception) as excinfo: + with pytest.warns(warning_classes) as warninfo: + warnings.warn("runtime", RuntimeWarning) + warnings.warn("import", ImportWarning) + + message_template = ("DID NOT WARN. No warnings of type {0} was emitted. " + "The list of emitted warnings is: {1}.") + excinfo.match(re.escape(message_template.format(warning_classes, + [each.message for each in warninfo]))) - with pytest.warns(UserWarning): - warnings.warn("user", UserWarning) def test_record(self): with pytest.warns(UserWarning) as record: diff -Nru pytest-3.0.5/tox.ini pytest-3.0.6/tox.ini --- pytest-3.0.5/tox.ini 2016-12-05 12:22:38.000000000 +0000 +++ pytest-3.0.6/tox.ini 2017-01-22 17:44:30.000000000 +0000 @@ -9,6 +9,7 @@ py33 py34 py35 + py36 pypy {py27,py35}-{pexpect,xdist,trial} py27-nobyte @@ -117,11 +118,13 @@ basepython = python usedevelop=True skipsdist=True +# ensure the given pyargs cant mean anytrhing else +changedir=doc/ deps= PyYAML commands= - pytest -rfsxX doc/en - pytest --doctest-modules {toxinidir}/_pytest + pytest -rfsxX en + pytest --doctest-modules --pyargs _pytest [testenv:regen] changedir=doc/en