Merge remote-tracking branch 'upstream/master' into release-5.3.0

This commit is contained in:
Bruno Oliveira 2019-11-19 12:42:11 -03:00
commit 21622d0df4
9 changed files with 109 additions and 7 deletions

View File

@ -135,6 +135,7 @@ Jordan Guymon
Jordan Moldow Jordan Moldow
Jordan Speicher Jordan Speicher
Joseph Hunkeler Joseph Hunkeler
Josh Karpel
Joshua Bronson Joshua Bronson
Jurko Gospodnetić Jurko Gospodnetić
Justyna Janczyszyn Justyna Janczyszyn
@ -264,6 +265,7 @@ Virgil Dupras
Vitaly Lashmanov Vitaly Lashmanov
Vlad Dragos Vlad Dragos
Volodymyr Piskun Volodymyr Piskun
Wei Lin
Wil Cooley Wil Cooley
William Lee William Lee
Wim Glenn Wim Glenn

View File

@ -1901,7 +1901,8 @@ Features
live-logging is enabled and/or when they are logged to a file. live-logging is enabled and/or when they are logged to a file.
- `#3985 <https://github.com/pytest-dev/pytest/issues/3985>`_: Introduce ``tmp_path`` as a fixture providing a Path object. - `#3985 <https://github.com/pytest-dev/pytest/issues/3985>`_: Introduce ``tmp_path`` as a fixture providing a Path object. Also introduce ``tmp_path_factory`` as
a session-scoped fixture for creating arbitrary temporary directories from any other fixture or test.
- `#4013 <https://github.com/pytest-dev/pytest/issues/4013>`_: Deprecation warnings are now shown even if you customize the warnings filters yourself. In the previous version - `#4013 <https://github.com/pytest-dev/pytest/issues/4013>`_: Deprecation warnings are now shown even if you customize the warnings filters yourself. In the previous version

View File

@ -0,0 +1 @@
Fix ``-setup-plan`` showing inaccurate information about fixture lifetimes.

View File

@ -0,0 +1 @@
Fix incorrect result of ``getmodpath`` method.

View File

@ -287,8 +287,7 @@ class PyobjMixin(PyobjContext):
break break
parts.append(name) parts.append(name)
parts.reverse() parts.reverse()
s = ".".join(parts) return ".".join(parts)
return s.replace(".[", "[")
def reportinfo(self) -> Tuple[str, int, str]: def reportinfo(self) -> Tuple[str, int, str]:
# XXX caching? # XXX caching?

View File

@ -16,7 +16,8 @@ def pytest_addoption(parser):
def pytest_fixture_setup(fixturedef, request): def pytest_fixture_setup(fixturedef, request):
# Will return a dummy fixture if the setuponly option is provided. # Will return a dummy fixture if the setuponly option is provided.
if request.config.option.setupplan: if request.config.option.setupplan:
fixturedef.cached_result = (None, None, None) my_cache_key = fixturedef.cache_key(request)
fixturedef.cached_result = (None, my_cache_key, None)
return fixturedef.cached_result return fixturedef.cached_result

View File

@ -760,7 +760,6 @@ class TestInvocationVariants:
result = testdir.runpytest(str(p) + "::test", "--doctest-modules") result = testdir.runpytest(str(p) + "::test", "--doctest-modules")
result.stdout.fnmatch_lines(["*1 passed*"]) result.stdout.fnmatch_lines(["*1 passed*"])
@pytest.mark.skipif(not hasattr(os, "symlink"), reason="requires symlinks")
def test_cmdline_python_package_symlink(self, testdir, monkeypatch): def test_cmdline_python_package_symlink(self, testdir, monkeypatch):
""" """
test --pyargs option with packages with path containing symlink can test --pyargs option with packages with path containing symlink can

View File

@ -685,6 +685,8 @@ class Test_genitems:
def test_example_items1(self, testdir): def test_example_items1(self, testdir):
p = testdir.makepyfile( p = testdir.makepyfile(
""" """
import pytest
def testone(): def testone():
pass pass
@ -693,19 +695,24 @@ class Test_genitems:
pass pass
class TestY(TestX): class TestY(TestX):
pass @pytest.mark.parametrize("arg0", [".["])
def testmethod_two(self, arg0):
pass
""" """
) )
items, reprec = testdir.inline_genitems(p) items, reprec = testdir.inline_genitems(p)
assert len(items) == 3 assert len(items) == 4
assert items[0].name == "testone" assert items[0].name == "testone"
assert items[1].name == "testmethod_one" assert items[1].name == "testmethod_one"
assert items[2].name == "testmethod_one" assert items[2].name == "testmethod_one"
assert items[3].name == "testmethod_two[.[]"
# let's also test getmodpath here # let's also test getmodpath here
assert items[0].getmodpath() == "testone" assert items[0].getmodpath() == "testone"
assert items[1].getmodpath() == "TestX.testmethod_one" assert items[1].getmodpath() == "TestX.testmethod_one"
assert items[2].getmodpath() == "TestY.testmethod_one" assert items[2].getmodpath() == "TestY.testmethod_one"
# PR #6202: Fix incorrect result of getmodpath method. (Resolves issue #6189)
assert items[3].getmodpath() == "TestY.testmethod_two[.[]"
s = items[0].getmodpath(stopatmodule=False) s = items[0].getmodpath(stopatmodule=False)
assert s.endswith("test_example_items1.testone") assert s.endswith("test_example_items1.testone")

View File

@ -17,3 +17,94 @@ def test_show_fixtures_and_test(testdir, dummy_yaml_custom_test):
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
["*SETUP F arg*", "*test_arg (fixtures used: arg)", "*TEARDOWN F arg*"] ["*SETUP F arg*", "*test_arg (fixtures used: arg)", "*TEARDOWN F arg*"]
) )
def test_show_multi_test_fixture_setup_and_teardown_correctly_simple(testdir):
"""
Verify that when a fixture lives for longer than a single test, --setup-plan
correctly displays the SETUP/TEARDOWN indicators the right number of times.
As reported in https://github.com/pytest-dev/pytest/issues/2049
--setup-plan was showing SETUP/TEARDOWN on every test, even when the fixture
should persist through multiple tests.
(Note that this bug never affected actual test execution, which used the
correct fixture lifetimes. It was purely a display bug for --setup-plan, and
did not affect the related --setup-show or --setup-only.)
"""
testdir.makepyfile(
"""
import pytest
@pytest.fixture(scope = 'class')
def fix():
return object()
class TestClass:
def test_one(self, fix):
assert False
def test_two(self, fix):
assert False
"""
)
result = testdir.runpytest("--setup-plan")
assert result.ret == 0
setup_fragment = "SETUP C fix"
setup_count = 0
teardown_fragment = "TEARDOWN C fix"
teardown_count = 0
for line in result.stdout.lines:
if setup_fragment in line:
setup_count += 1
if teardown_fragment in line:
teardown_count += 1
# before the fix this tests, there would have been a setup/teardown
# message for each test, so the counts would each have been 2
assert setup_count == 1
assert teardown_count == 1
def test_show_multi_test_fixture_setup_and_teardown_same_as_setup_show(testdir):
"""
Verify that SETUP/TEARDOWN messages match what comes out of --setup-show.
"""
testdir.makepyfile(
"""
import pytest
@pytest.fixture(scope = 'session')
def sess():
return True
@pytest.fixture(scope = 'module')
def mod():
return True
@pytest.fixture(scope = 'class')
def cls():
return True
@pytest.fixture(scope = 'function')
def func():
return True
def test_outside(sess, mod, cls, func):
assert True
class TestCls:
def test_one(self, sess, mod, cls, func):
assert True
def test_two(self, sess, mod, cls, func):
assert True
"""
)
plan_result = testdir.runpytest("--setup-plan")
show_result = testdir.runpytest("--setup-show")
# the number and text of these lines should be identical
plan_lines = [
l for l in plan_result.stdout.lines if "SETUP" in l or "TEARDOWN" in l
]
show_lines = [
l for l in show_result.stdout.lines if "SETUP" in l or "TEARDOWN" in l
]
assert plan_lines == show_lines