diff --git a/_pytest/pytester.py b/_pytest/pytester.py index dc9236089..7566085be 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -661,6 +661,12 @@ class LineMatcher: else: raise ValueError("line %r not found in output" % line) + def get_lines_after(self, fnline): + for i, line in enumerate(self.lines): + if fnline == line or fnmatch(line, fnline): + return self.lines[i+1:] + raise ValueError("line %r not found in output" % fnline) + def fnmatch_lines(self, lines2): def show(arg1, arg2): py.builtin.print_(arg1, arg2, file=py.std.sys.stderr) diff --git a/doc/en/Makefile b/doc/en/Makefile index 7a05008ac..17fab6115 100644 --- a/doc/en/Makefile +++ b/doc/en/Makefile @@ -12,7 +12,7 @@ PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -SITETARGET=dev +SITETARGET=latest .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest diff --git a/doc/en/announce/index.txt b/doc/en/announce/index.txt index 333542b98..06e1a5065 100644 --- a/doc/en/announce/index.txt +++ b/doc/en/announce/index.txt @@ -5,6 +5,7 @@ Release announcements .. toctree:: :maxdepth: 2 + release-2.4.0 release-2.3.5 release-2.3.4 release-2.3.3 diff --git a/doc/en/announce/release-2.4.0.txt b/doc/en/announce/release-2.4.0.txt new file mode 100644 index 000000000..5e4eec61e --- /dev/null +++ b/doc/en/announce/release-2.4.0.txt @@ -0,0 +1,225 @@ +pytest-2.4.0: new fixture features/hooks and bug fixes +=========================================================================== + +The just released pytest-2.4.0 brings many improvements and numerous +bug fixes while remaining plugin- and test-suite compatible apart +from a few supposedly very minor incompatibilities. See below for +a full list of details. A few feature highlights: + +- new yield-style fixtures `pytest.yield_fixture + `_, allowing to use + existing with-style context managers in fixture functions. + +- improved pdb support: ``import pdb ; pdb.set_trace()`` now works + without requiring prior disabling of stdout/stderr capturing. + Also the ``--pdb`` options works now on collection and internal errors + and we introduced a new experimental hook for IDEs/plugins to + intercept debugging: ``pytest_exception_interact(node, call, report)``. + +- shorter monkeypatch variant to allow specifying an import path as + a target, for example: ``monkeypatch.setattr("requests.get", myfunc)`` + +- better unittest/nose compatibility: all teardown methods are now only + called if the corresponding setup method succeeded. + +- integrate tab-completion on command line options if you + have `argcomplete `_ + configured. + +- allow boolean expression directly with skipif/xfail + if a "reason" is also specified. + +- a new hook ``pytest_load_initial_conftests`` allows plugins like + `pytest-django `_ to + influence the environment before conftest files import ``django``. + +- reporting: color the last line red or green depending if + failures/errors occured or everything passed. + +The documentation has been updated to accomodate the changes, +see `http://pytest.org `_ + +To install or upgrade pytest:: + + pip install -U pytest # or + easy_install -U pytest + + +**Many thanks to all who helped, including Floris Bruynooghe, +Brianna Laugher, Andreas Pelme, Anthon van der Neut, Anatoly Bubenkoff, +Vladimir Keleshev, Mathieu Agopian, Ronny Pfannschmidt, Christian +Theunert and many others.** + +may passing tests be with you, + +holger krekel + +Changes between 2.3.5 and 2.4 +----------------------------------- + +known incompatibilities: + +- if calling --genscript from python2.7 or above, you only get a + standalone script which works on python2.7 or above. Use Python2.6 + to also get a python2.5 compatible version. + +- all xunit-style teardown methods (nose-style, pytest-style, + unittest-style) will not be called if the corresponding setup method failed, + see issue322 below. + +- the pytest_plugin_unregister hook wasn't ever properly called + and there is no known implementation of the hook - so it got removed. + +- pytest.fixture-decorated functions cannot be generators (i.e. use + yield) anymore. This change might be reversed in 2.4.1 if it causes + unforeseen real-life issues. However, you can always write and return + an inner function/generator and change the fixture consumer to iterate + over the returned generator. This change was done in lieu of the new + ``pytest.yield_fixture`` decorator, see below. + +new features: + +- experimentally introduce a new ``pytest.yield_fixture`` decorator + which accepts exactly the same parameters as pytest.fixture but + mandates a ``yield`` statement instead of a ``return statement`` from + fixture functions. This allows direct integration with "with-style" + context managers in fixture functions and generally avoids registering + of finalization callbacks in favour of treating the "after-yield" as + teardown code. Thanks Andreas Pelme, Vladimir Keleshev, Floris + Bruynooghe, Ronny Pfannschmidt and many others for discussions. + +- allow boolean expression directly with skipif/xfail + if a "reason" is also specified. Rework skipping documentation + to recommend "condition as booleans" because it prevents surprises + when importing markers between modules. Specifying conditions + as strings will remain fully supported. + +- reporting: color the last line red or green depending if + failures/errors occured or everything passed. thanks Christian + Theunert. + +- make "import pdb ; pdb.set_trace()" work natively wrt capturing (no + "-s" needed anymore), making ``pytest.set_trace()`` a mere shortcut. + +- fix issue181: --pdb now also works on collect errors (and + on internal errors) . This was implemented by a slight internal + refactoring and the introduction of a new hook + ``pytest_exception_interact`` hook (see next item). + +- fix issue341: introduce new experimental hook for IDEs/terminals to + intercept debugging: ``pytest_exception_interact(node, call, report)``. + +- new monkeypatch.setattr() variant to provide a shorter + invocation for patching out classes/functions from modules: + + monkeypatch.setattr("requests.get", myfunc) + + will replace the "get" function of the "requests" module with ``myfunc``. + +- 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 + 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. + +- simplify pytest.mark.parametrize() signature: allow to pass a + CSV-separated string to specify argnames. For example: + ``pytest.mark.parametrize("input,expected", [(1,2), (2,3)])`` + works as well as the previous: + ``pytest.mark.parametrize(("input", "expected"), ...)``. + +- add support for setUpModule/tearDownModule detection, thanks Brian Okken. + +- integrate tab-completion on options through use of "argcomplete". + Thanks Anthon van der Neut for the PR. + +- change option names to be hyphen-separated long options but keep the + old spelling backward compatible. py.test -h will only show the + hyphenated version, for example "--collect-only" but "--collectonly" + will remain valid as well (for backward-compat reasons). Many thanks to + Anthon van der Neut for the implementation and to Hynek Schlawack for + pushing us. + +- fix issue 308 - allow to mark/xfail/skip individual parameter sets + when parametrizing. Thanks Brianna Laugher. + +- call new experimental pytest_load_initial_conftests hook to allow + 3rd party plugins to do something before a conftest is loaded. + +Bug fixes: + +- fix issue358 - capturing options are now parsed more properly + by using a new parser.parse_known_args method. + +- pytest now uses argparse instead of optparse (thanks Anthon) which + means that "argparse" is added as a dependency if installing into python2.6 + environments or below. + +- fix issue333: fix a case of bad unittest/pytest hook interaction. + +- PR27: correctly handle nose.SkipTest during collection. Thanks + Antonio Cuni, Ronny Pfannschmidt. + +- fix issue355: junitxml puts name="pytest" attribute to testsuite tag. + +- fix issue336: autouse fixture in plugins should work again. + +- fix issue279: improve object comparisons on assertion failure + for standard datatypes and recognise collections.abc. Thanks to + Brianna Laugher and Mathieu Agopian. + +- fix issue317: assertion rewriter support for the is_package method + +- fix issue335: document py.code.ExceptionInfo() object returned + from pytest.raises(), thanks Mathieu Agopian. + +- remove implicit distribute_setup support from setup.py. + +- fix issue305: ignore any problems when writing pyc files. + +- SO-17664702: call fixture finalizers even if the fixture function + partially failed (finalizers would not always be called before) + +- fix issue320 - fix class scope for fixtures when mixed with + module-level functions. Thanks Anatloy Bubenkoff. + +- you can specify "-q" or "-qq" to get different levels of "quieter" + reporting (thanks Katarzyna Jachim) + +- fix issue300 - Fix order of conftest loading when starting py.test + in a subdirectory. + +- fix issue323 - sorting of many module-scoped arg parametrizations + +- make sessionfinish hooks execute with the same cwd-context as at + session start (helps fix plugin behaviour which write output files + with relative path such as pytest-cov) + +- fix issue316 - properly reference collection hooks in docs + +- fix issue 306 - cleanup of -k/-m options to only match markers/test + names/keywords respectively. Thanks Wouter van Ackooy. + +- improved doctest counting for doctests in python modules -- + files without any doctest items will not show up anymore + and doctest examples are counted as separate test items. + thanks Danilo Bellini. + +- fix issue245 by depending on the released py-1.4.14 + which fixes py.io.dupfile to work with files with no + mode. Thanks Jason R. Coombs. + +- fix junitxml generation when test output contains control characters, + addressing issue267, thanks Jaap Broekhuizen + +- fix issue338: honor --tb style for setup/teardown errors as well. Thanks Maho. + +- fix issue307 - use yaml.safe_load in example, thanks Mark Eichin. + +- better parametrize error messages, thanks Brianna Laugher + +- pytest_terminal_summary(terminalreporter) hooks can now use + ".section(title)" and ".line(msg)" methods to print extra + information at the end of a test run. + diff --git a/doc/en/conf.py b/doc/en/conf.py index ee0559754..e3a00b69b 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.4.0.dev" +version = release = "2.4.0" import sys, os diff --git a/doc/en/faq.txt b/doc/en/faq.txt index 534c05eaf..9dc2169fd 100644 --- a/doc/en/faq.txt +++ b/doc/en/faq.txt @@ -3,9 +3,10 @@ Some Issues and Questions .. note:: - If you don't find an answer here, you may checkout + This FAQ is here only mostly for historic reasons. Checkout `pytest Q&A at Stackoverflow `_ - or other :ref:`contact channels` to get help. + for many questions and answers related to pytest and/or use + :ref:`contact channels` to get help. On naming, nosetests, licensing and magic ------------------------------------------------ @@ -94,12 +95,12 @@ but since many people have gotten used to the old name and there is another tool named "pytest" we just decided to stick with ``py.test`` for now. -Function arguments, parametrized tests and setup +pytest fixtures, parametrized tests ------------------------------------------------------- .. _funcargs: funcargs.html -Is using funcarg- versus xUnit setup a style question? +Is using pytest fixtures versus xUnit setup a style question? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ For simple applications and for people experienced with nose_ or @@ -117,20 +118,6 @@ in a managed class/module/function scope. .. _`why pytest_pyfuncarg__ methods?`: -Why the ``pytest_funcarg__*`` name for funcarg factories? -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -We like `Convention over Configuration`_ and didn't see much point -in allowing a more flexible or abstract mechanism. Moreover, -it is nice to be able to search for ``pytest_funcarg__MYARG`` in -source code and safely find all factory functions for -the ``MYARG`` function argument. - -.. note:: - - With pytest-2.3 you can use the :ref:`@pytest.fixture` decorator - to mark a function as a fixture function. - .. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration Can I yield multiple values from a fixture function function? @@ -139,16 +126,16 @@ Can I yield multiple values from a fixture function function? There are two conceptual reasons why yielding from a factory function is not possible: -* Calling factories for obtaining test function arguments - is part of setting up and running a test. At that - point it is not possible to add new test calls to - the test collection anymore. - * If multiple factories yielded values there would be no natural place to determine the combination policy - in real-world examples some combinations often should not run. +* Calling factories for obtaining test function arguments + is part of setting up and running a test. At that + point it is not possible to add new test calls to + the test collection anymore. + However, with pytest-2.3 you can use the :ref:`@pytest.fixture` decorator and specify ``params`` so that all tests depending on the factory-created resource will run multiple times with different parameters. diff --git a/doc/en/fixture.txt b/doc/en/fixture.txt index c04f5818c..7aed5973b 100644 --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -34,6 +34,12 @@ both styles, moving incrementally from classic to new style, as you prefer. You can also start out from existing :ref:`unittest.TestCase style ` or :ref:`nose based ` projects. +.. note:: + + pytest-2.4 introduced an additional experimental + :ref:`yield fixture mechanism ` for easier context manager + integration and more linear writing of teardown code. + .. _`funcargs`: .. _`funcarg mechanism`: .. _`fixture function`: @@ -275,9 +281,6 @@ occur around each single test. In either case the test module itself does not need to change or know about these details of fixture setup. -Note that pytest-2.4 introduced an experimental alternative -:ref:`yield fixture mechanism ` for easier context manager -integration and more linear writing of teardown code. .. _`request-context`: diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 1abf0dd62..f0240f866 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -504,7 +504,7 @@ class TestInvocationVariants: class TestDurations: source = """ import time - frag = 0.02 + frag = 0.002 def test_something(): pass def test_2(): @@ -519,7 +519,7 @@ class TestDurations: testdir.makepyfile(self.source) result = testdir.runpytest("--durations=10") assert result.ret == 0 - result.stdout.fnmatch_lines([ + result.stdout.fnmatch_lines_random([ "*durations*", "*call*test_3*", "*call*test_2*", @@ -530,12 +530,8 @@ class TestDurations: testdir.makepyfile(self.source) result = testdir.runpytest("--durations=2") assert result.ret == 0 - result.stdout.fnmatch_lines([ - "*durations*", - "*call*test_3*", - "*call*test_2*", - ]) - assert "test_1" not in result.stdout.str() + lines = result.stdout.get_lines_after("*slowest*durations*") + assert "4 passed" in lines[2] def test_calls_showall(self, testdir): testdir.makepyfile(self.source) @@ -573,7 +569,7 @@ class TestDurations: class TestDurationWithFixture: source = """ import time - frag = 0.01 + frag = 0.001 def setup_function(func): time.sleep(frag * 3) def test_1(): diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 24beff5a8..78596f27f 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,4 +1,4 @@ - +import pytest from xml.dom import minidom import py, sys, os @@ -427,16 +427,16 @@ def test_invalid_xml_escape(): def test_logxml_path_expansion(tmpdir, monkeypatch): from _pytest.junitxml import LogXML - home_tilde = os.path.normpath(os.path.expanduser('~/test.xml')) + home_tilde = py.path.local(os.path.expanduser('~')).join('test.xml') - xml_tilde = LogXML('~/test.xml', None) + xml_tilde = LogXML('~%stest.xml' % tmpdir.sep, None) assert xml_tilde.logfile == home_tilde # this is here for when $HOME is not set correct monkeypatch.setenv("HOME", tmpdir) home_var = os.path.normpath(os.path.expandvars('$HOME/test.xml')) - xml_var = LogXML('$HOME/test.xml', None) + xml_var = LogXML('$HOME%stest.xml' % tmpdir.sep, None) assert xml_var.logfile == home_var def test_logxml_changingdir(testdir):