add feature to view fixture source location in invocations with --fixtures-per-test option (#8626)

* add feature to view fixture source location in invocations with --fixtures-per-test option

* remove unrelated changes to show_fixtures_per_test::test_doctest_items

* eshew the extraneous else in _show_fixtures_per_test.write_fixture

* enable the accommodation of multi-line docstring with --fixtures-per-test option

* add feature to view fixture source location in invocations with --fixtures

* add colour encoding to fixture location paths

* add changelog for #8606 fixing

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Rahul Kumaresan 2021-05-14 18:08:55 +05:30 committed by GitHub
parent 33c6ad5bf7
commit c516dba69a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 108 additions and 33 deletions

View File

@ -0,0 +1,5 @@
pytest invocations with ``--fixtures-per-test`` and ``--fixtures`` have been enabled with:
- Fixture location path printed with the fixture name.
- First section of the fixture's docstring printed under the fixture name.
- Whole of fixture's docstring printed under the fixture name using ``--verbose`` option.

View File

@ -1428,15 +1428,15 @@ def _show_fixtures_per_test(config: Config, session: Session) -> None:
argname = fixture_def.argname argname = fixture_def.argname
if verbose <= 0 and argname.startswith("_"): if verbose <= 0 and argname.startswith("_"):
return return
if verbose > 0:
bestrel = get_best_relpath(fixture_def.func) bestrel = get_best_relpath(fixture_def.func)
funcargspec = f"{argname} -- {bestrel}" tw.write(f"{argname}", green=True)
else: tw.write(f" -- {bestrel}", yellow=True)
funcargspec = argname tw.write("\n")
tw.line(funcargspec, green=True)
fixture_doc = inspect.getdoc(fixture_def.func) fixture_doc = inspect.getdoc(fixture_def.func)
if fixture_doc: if fixture_doc:
write_docstring(tw, fixture_doc) write_docstring(
tw, fixture_doc.split("\n\n")[0] if verbose <= 0 else fixture_doc
)
else: else:
tw.line(" no docstring available", red=True) tw.line(" no docstring available", red=True)
@ -1508,18 +1508,17 @@ def _showfixtures_main(config: Config, session: Session) -> None:
tw.line() tw.line()
tw.sep("-", f"fixtures defined from {module}") tw.sep("-", f"fixtures defined from {module}")
currentmodule = module currentmodule = module
if verbose <= 0 and argname[0] == "_": if verbose <= 0 and argname.startswith("_"):
continue continue
tw.write(argname, green=True) tw.write(f"{argname}", green=True)
if fixturedef.scope != "function": if fixturedef.scope != "function":
tw.write(" [%s scope]" % fixturedef.scope, cyan=True) tw.write(" [%s scope]" % fixturedef.scope, cyan=True)
if verbose > 0: tw.write(f" -- {bestrel}", yellow=True)
tw.write(" -- %s" % bestrel, yellow=True)
tw.write("\n") tw.write("\n")
loc = getlocation(fixturedef.func, str(curdir)) loc = getlocation(fixturedef.func, str(curdir))
doc = inspect.getdoc(fixturedef.func) doc = inspect.getdoc(fixturedef.func)
if doc: if doc:
write_docstring(tw, doc) write_docstring(tw, doc.split("\n\n")[0] if verbose <= 0 else doc)
else: else:
tw.line(f" {loc}: no docstring available", red=True) tw.line(f" {loc}: no docstring available", red=True)
tw.line() tw.line()

View File

@ -3334,9 +3334,9 @@ class TestShowFixtures:
result = pytester.runpytest("--fixtures") result = pytester.runpytest("--fixtures")
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
[ [
"tmp_path_factory [[]session scope[]]", "tmp_path_factory [[]session scope[]] -- *tmpdir.py*",
"*for the test session*", "*for the test session*",
"tmp_path", "tmp_path -- *",
"*temporary directory*", "*temporary directory*",
] ]
) )
@ -3367,9 +3367,9 @@ class TestShowFixtures:
result = pytester.runpytest("--fixtures", p) result = pytester.runpytest("--fixtures", p)
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
*tmp_path *tmp_path -- *
*fixtures defined from* *fixtures defined from*
*arg1* *arg1 -- test_show_fixtures_testmodule.py:6*
*hello world* *hello world*
""" """
) )
@ -3429,10 +3429,10 @@ class TestShowFixtures:
textwrap.dedent( textwrap.dedent(
"""\ """\
* fixtures defined from test_show_fixtures_trimmed_doc * * fixtures defined from test_show_fixtures_trimmed_doc *
arg2 arg2 -- test_show_fixtures_trimmed_doc.py:10
line1 line1
line2 line2
arg1 arg1 -- test_show_fixtures_trimmed_doc.py:3
line1 line1
line2 line2
""" """
@ -3458,7 +3458,7 @@ class TestShowFixtures:
textwrap.dedent( textwrap.dedent(
"""\ """\
* fixtures defined from test_show_fixtures_indented_doc * * fixtures defined from test_show_fixtures_indented_doc *
fixture1 fixture1 -- test_show_fixtures_indented_doc.py:3
line1 line1
indented line indented line
""" """
@ -3486,7 +3486,7 @@ class TestShowFixtures:
textwrap.dedent( textwrap.dedent(
"""\ """\
* fixtures defined from test_show_fixtures_indented_doc_first_line_unindented * * fixtures defined from test_show_fixtures_indented_doc_first_line_unindented *
fixture1 fixture1 -- test_show_fixtures_indented_doc_first_line_unindented.py:3
line1 line1
line2 line2
indented line indented line
@ -3514,7 +3514,7 @@ class TestShowFixtures:
textwrap.dedent( textwrap.dedent(
"""\ """\
* fixtures defined from test_show_fixtures_indented_in_class * * fixtures defined from test_show_fixtures_indented_in_class *
fixture1 fixture1 -- test_show_fixtures_indented_in_class.py:4
line1 line1
line2 line2
indented line indented line
@ -3554,11 +3554,11 @@ class TestShowFixtures:
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
* fixtures defined from test_a * * fixtures defined from test_a *
fix_a fix_a -- test_a.py:4
Fixture A Fixture A
* fixtures defined from test_b * * fixtures defined from test_b *
fix_b fix_b -- test_b.py:4
Fixture B Fixture B
""" """
) )
@ -3594,11 +3594,11 @@ class TestShowFixtures:
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
""" """
* fixtures defined from conftest * * fixtures defined from conftest *
arg1 arg1 -- conftest.py:3
Hello World in conftest.py Hello World in conftest.py
* fixtures defined from test_show_fixtures_with_same_name * * fixtures defined from test_show_fixtures_with_same_name *
arg1 arg1 -- test_show_fixtures_with_same_name.py:3
Hi from test module Hi from test module
""" """
) )

View File

@ -29,7 +29,7 @@ def test_fixtures_in_module(pytester: Pytester) -> None:
[ [
"*fixtures used by test_arg1*", "*fixtures used by test_arg1*",
"*(test_fixtures_in_module.py:9)*", "*(test_fixtures_in_module.py:9)*",
"arg1", "arg1 -- test_fixtures_in_module.py:6",
" arg1 docstring", " arg1 docstring",
] ]
) )
@ -68,17 +68,16 @@ def test_fixtures_in_conftest(pytester: Pytester) -> None:
[ [
"*fixtures used by test_arg2*", "*fixtures used by test_arg2*",
"*(test_fixtures_in_conftest.py:2)*", "*(test_fixtures_in_conftest.py:2)*",
"arg2", "arg2 -- conftest.py:6",
" arg2 docstring", " arg2 docstring",
"*fixtures used by test_arg3*", "*fixtures used by test_arg3*",
"*(test_fixtures_in_conftest.py:4)*", "*(test_fixtures_in_conftest.py:4)*",
"arg1", "arg1 -- conftest.py:3",
" arg1 docstring", " arg1 docstring",
"arg2", "arg2 -- conftest.py:6",
" arg2 docstring", " arg2 docstring",
"arg3", "arg3 -- conftest.py:9",
" arg3", " arg3",
" docstring",
] ]
) )
@ -112,9 +111,9 @@ def test_should_show_fixtures_used_by_test(pytester: Pytester) -> None:
[ [
"*fixtures used by test_args*", "*fixtures used by test_args*",
"*(test_should_show_fixtures_used_by_test.py:6)*", "*(test_should_show_fixtures_used_by_test.py:6)*",
"arg1", "arg1 -- test_should_show_fixtures_used_by_test.py:3",
" arg1 from testmodule", " arg1 from testmodule",
"arg2", "arg2 -- conftest.py:6",
" arg2 from conftest", " arg2 from conftest",
] ]
) )
@ -181,3 +180,75 @@ def test_doctest_items(pytester: Pytester) -> None:
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*collected 2 items*"]) result.stdout.fnmatch_lines(["*collected 2 items*"])
def test_multiline_docstring_in_module(pytester: Pytester) -> None:
p = pytester.makepyfile(
'''
import pytest
@pytest.fixture
def arg1():
"""Docstring content that spans across multiple lines,
through second line,
and through third line.
Docstring content that extends into a second paragraph.
Docstring content that extends into a third paragraph.
"""
def test_arg1(arg1):
pass
'''
)
result = pytester.runpytest("--fixtures-per-test", p)
assert result.ret == 0
result.stdout.fnmatch_lines(
[
"*fixtures used by test_arg1*",
"*(test_multiline_docstring_in_module.py:13)*",
"arg1 -- test_multiline_docstring_in_module.py:3",
" Docstring content that spans across multiple lines,",
" through second line,",
" and through third line.",
]
)
def test_verbose_include_multiline_docstring(pytester: Pytester) -> None:
p = pytester.makepyfile(
'''
import pytest
@pytest.fixture
def arg1():
"""Docstring content that spans across multiple lines,
through second line,
and through third line.
Docstring content that extends into a second paragraph.
Docstring content that extends into a third paragraph.
"""
def test_arg1(arg1):
pass
'''
)
result = pytester.runpytest("--fixtures-per-test", "-v", p)
assert result.ret == 0
result.stdout.fnmatch_lines(
[
"*fixtures used by test_arg1*",
"*(test_verbose_include_multiline_docstring.py:13)*",
"arg1 -- test_verbose_include_multiline_docstring.py:3",
" Docstring content that spans across multiple lines,",
" through second line,",
" and through third line.",
" ",
" Docstring content that extends into a second paragraph.",
" ",
" Docstring content that extends into a third paragraph.",
]
)