From 6c519b12802347b257840c4d286ca0bf94cd92a5 Mon Sep 17 00:00:00 2001 From: Jeffrey Rackauckas Date: Wed, 23 May 2018 19:34:45 -0700 Subject: [PATCH 1/8] Fixed a bug where stdout and stderr were logged twice by junitxml. --- _pytest/junitxml.py | 2 +- changelog/3491.bugfix.rst | 1 + testing/test_junitxml.py | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 changelog/3491.bugfix.rst diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py index 3a0e4a071..a4603529b 100644 --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -224,7 +224,7 @@ class _NodeReporter(object): Junit.skipped("%s:%s: %s" % (filename, lineno, skipreason), type="pytest.skip", message=skipreason)) - self.write_captured_output(report) + self.write_captured_output(report) def finalize(self): data = self.to_xml().unicode(indent=0) diff --git a/changelog/3491.bugfix.rst b/changelog/3491.bugfix.rst new file mode 100644 index 000000000..7c8bd191c --- /dev/null +++ b/changelog/3491.bugfix.rst @@ -0,0 +1 @@ +Fixed a bug where stdout and stderr were logged twice by junitxml. \ No newline at end of file diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index a8f5b9fec..255a68a52 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -458,6 +458,23 @@ class TestPython(object): fnode.assert_attr(message="expected test failure") # assert "ValueError" in fnode.toxml() + def test_xfail_captures_output_once(self, testdir): + testdir.makepyfile(""" + import sys + import pytest + + @pytest.mark.xfail() + def test_fail(): + sys.stdout.write('XFAIL This is stdout') + sys.stderr.write('XFAIL This is stderr') + assert 0 + """) + result, dom = runandparse(testdir) + node = dom.find_first_by_tag("testsuite") + tnode = node.find_first_by_tag("testcase") + assert len(tnode.find_by_tag('system-err')) == 1 + assert len(tnode.find_by_tag('system-out')) == 1 + def test_xfailure_xpass(self, testdir): testdir.makepyfile(""" import pytest From 210ad22dbe6d61a4dcfb9a1f431058e6a8c26bad Mon Sep 17 00:00:00 2001 From: Jeffrey Rackauckas Date: Wed, 23 May 2018 19:43:06 -0700 Subject: [PATCH 2/8] Updating changelog text --- changelog/3491.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/3491.bugfix.rst b/changelog/3491.bugfix.rst index 7c8bd191c..2ac733cbc 100644 --- a/changelog/3491.bugfix.rst +++ b/changelog/3491.bugfix.rst @@ -1 +1 @@ -Fixed a bug where stdout and stderr were logged twice by junitxml. \ No newline at end of file +Fixed a bug where stdout and stderr were logged twice by junitxml when a test was marked xfail. \ No newline at end of file From b4e02656226ca74fd0676668926e20e5bceeebf0 Mon Sep 17 00:00:00 2001 From: Jeffrey Rackauckas Date: Wed, 23 May 2018 20:15:28 -0700 Subject: [PATCH 3/8] Removed whitespace from empty line. --- testing/test_junitxml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 255a68a52..889a2f007 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -474,7 +474,7 @@ class TestPython(object): tnode = node.find_first_by_tag("testcase") assert len(tnode.find_by_tag('system-err')) == 1 assert len(tnode.find_by_tag('system-out')) == 1 - + def test_xfailure_xpass(self, testdir): testdir.makepyfile(""" import pytest From 74cfdc5feb9b07ff538b6c85d864437aadeb314e Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 24 May 2018 07:30:38 +0200 Subject: [PATCH 4/8] add failing test for #3498 --- testing/test_unittest.py | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/testing/test_unittest.py b/testing/test_unittest.py index e19773587..685ca1b7a 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -828,3 +828,50 @@ def test_class_method_containing_test_issue1558(testdir): """) reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + + +@pytest.mark.issue(3498) +@pytest.mark.parametrize("base", [ + 'six.moves.builtins.object', + 'unittest.TestCase', + 'unittest2.TestCase', +]) +def test_usefixtures_marker_on_unittest(base, testdir): + module = base.rsplit('.', 1)[0] + pytest.importorskip(module) + testdir.makepyfile(conftest=""" + import pytest + + @pytest.fixture(scope='function') + def fixture1(request, monkeypatch): + monkeypatch.setattr(request.instance, 'fixture1', True ) + + + @pytest.fixture(scope='function') + def fixture2(request, monkeypatch): + monkeypatch.setattr(request.instance, 'fixture2', True ) + """) + + testdir.makepyfile(""" + import pytest + import {module} + + class Tests({base}): + fixture1 = False + fixture2 = False + + @pytest.mark.usefixtures("fixture1") + def test_one(self): + assert self.fixture1 + assert not self.fixture2 + + @pytest.mark.usefixtures("fixture1", "fixture2") + def test_two(self): + assert self.fixture1 + assert self.fixture2 + + + """.format(module=module, base=base)) + + result = testdir.runpytest() + result.assert_outcomes(passed=2) From da2c2e8492c85b315d3cc0892a69ff2fc9c259e8 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 24 May 2018 09:58:36 +0200 Subject: [PATCH 5/8] more debugging for #3498 --- testing/test_unittest.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 685ca1b7a..202b20c19 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -850,6 +850,20 @@ def test_usefixtures_marker_on_unittest(base, testdir): @pytest.fixture(scope='function') def fixture2(request, monkeypatch): monkeypatch.setattr(request.instance, 'fixture2', True ) + + def node_and_marks(item): + print(item.nodeid) + for mark in item.iter_markers(): + print(" ", mark) + + @pytest.fixture(autouse=True) + def my_marks(request): + node_and_marks(request.node) + + def pytest_collection_modifyitems(items): + for item in items: + node_and_marks(item) + """) testdir.makepyfile(""" @@ -873,5 +887,5 @@ def test_usefixtures_marker_on_unittest(base, testdir): """.format(module=module, base=base)) - result = testdir.runpytest() + result = testdir.runpytest('-s') result.assert_outcomes(passed=2) From 5a0c9aca639596b9d0bf5d909462b0435afda244 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Thu, 24 May 2018 10:29:42 +0200 Subject: [PATCH 6/8] correctly instantiate fixtureinfo for unittest tests, fixes #3498 --- _pytest/fixtures.py | 2 +- _pytest/python.py | 2 +- _pytest/unittest.py | 3 ++- changelog/3498.bugfix | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 changelog/3498.bugfix diff --git a/_pytest/fixtures.py b/_pytest/fixtures.py index 7b109ec11..6617c24a2 100644 --- a/_pytest/fixtures.py +++ b/_pytest/fixtures.py @@ -984,7 +984,7 @@ class FixtureManager(object): session.config.pluginmanager.register(self, "funcmanage") def getfixtureinfo(self, node, func, cls, funcargs=True): - if funcargs and not hasattr(node, "nofuncargs"): + if funcargs and not getattr(node, "nofuncargs", False): argnames = getfuncargnames(func, cls=cls) else: argnames = () diff --git a/_pytest/python.py b/_pytest/python.py index 8bcb051a2..2b37067d5 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1155,7 +1155,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr): if fixtureinfo is None: fixtureinfo = self.session._fixturemanager.getfixtureinfo( - self.parent, self.obj, self.cls, + self, self.obj, self.cls, funcargs=not self._isyieldedfunction()) self._fixtureinfo = fixtureinfo self.fixturenames = fixtureinfo.names_closure diff --git a/_pytest/unittest.py b/_pytest/unittest.py index 3ddb39495..17c94bca4 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -54,7 +54,7 @@ class UnitTestCase(Class): continue funcobj = getattr(x, 'im_func', x) transfer_markers(funcobj, cls, module) - yield TestCaseFunction(name, parent=self) + yield TestCaseFunction(name, parent=self, callobj=funcobj) foundsomething = True if not foundsomething: @@ -66,6 +66,7 @@ class UnitTestCase(Class): class TestCaseFunction(Function): + nofuncargs = True _excinfo = None def setup(self): diff --git a/changelog/3498.bugfix b/changelog/3498.bugfix new file mode 100644 index 000000000..7260879c4 --- /dev/null +++ b/changelog/3498.bugfix @@ -0,0 +1 @@ +correctly instantiate fixtureinfo for unittest tests. \ No newline at end of file From bc25d51b2f59a92df28c37b436b21aa311a30913 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 24 May 2018 07:27:40 -0300 Subject: [PATCH 7/8] Re-word changelog --- changelog/3498.bugfix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/3498.bugfix b/changelog/3498.bugfix index 7260879c4..344038bee 100644 --- a/changelog/3498.bugfix +++ b/changelog/3498.bugfix @@ -1 +1 @@ -correctly instantiate fixtureinfo for unittest tests. \ No newline at end of file +Fix ``usefixtures`` mark applyed to unittest tests by correctly instantiating ``FixtureInfo``. From c55635d42a6e6bab35307f5d728dfff0b3161901 Mon Sep 17 00:00:00 2001 From: Oliver Bestwalter Date: Fri, 25 May 2018 09:54:03 +0200 Subject: [PATCH 8/8] Fix tox spelling (all lower case). --- doc/en/goodpractices.rst | 4 ++-- doc/en/nose.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/en/goodpractices.rst b/doc/en/goodpractices.rst index d9f0fff11..1e22c10f2 100644 --- a/doc/en/goodpractices.rst +++ b/doc/en/goodpractices.rst @@ -174,7 +174,7 @@ Note that this layout also works in conjunction with the ``src`` layout mentione .. _`use tox`: -Tox +tox ------ For development, we recommend to use virtualenv_ environments and pip_ @@ -194,7 +194,7 @@ Once you are done with your work 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 +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 against your source code checkout, helping to detect packaging diff --git a/doc/en/nose.rst b/doc/en/nose.rst index 10a10633a..31dffeb3f 100644 --- a/doc/en/nose.rst +++ b/doc/en/nose.rst @@ -58,7 +58,7 @@ Unsupported idioms / known issues You may find yourself wanting to do this if you ran ``python setup.py install`` to set up your project, as opposed to ``python setup.py develop`` or any of the package manager equivalents. Installing with develop in a - virtual environment like Tox is recommended over this pattern. + virtual environment like tox is recommended over this pattern. - nose-style doctests are not collected and executed correctly, also doctest fixtures don't work.