diff --git a/_pytest/doctest.py b/_pytest/doctest.py index cc505c8d0..4c05acddf 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -120,7 +120,7 @@ class DoctestItem(pytest.Item): lines = ["%03d %s" % (i + test.lineno + 1, x) for (i, x) in enumerate(lines)] # trim docstring error lines to 10 - lines = lines[example.lineno - 9:example.lineno + 1] + lines = lines[max(example.lineno - 9, 0):example.lineno + 1] else: lines = ['EXAMPLE LOCATION UNKNOWN, not showing all tests of that example'] indent = '>>>' diff --git a/changelog/2882.bugfix b/changelog/2882.bugfix new file mode 100644 index 000000000..2bda24c01 --- /dev/null +++ b/changelog/2882.bugfix @@ -0,0 +1 @@ +Show full context of doctest source in the pytest output, if the lineno of failed example in the docstring is < 9. \ No newline at end of file diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 8a81ea0ed..6616d2eae 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -173,7 +173,7 @@ class TestDoctests(object): "*UNEXPECTED*ZeroDivision*", ]) - def test_docstring_context_around_error(self, testdir): + def test_docstring_partial_context_around_error(self, testdir): """Test that we show some context before the actual line of a failing doctest. """ @@ -199,7 +199,7 @@ class TestDoctests(object): ''') result = testdir.runpytest('--doctest-modules') result.stdout.fnmatch_lines([ - '*docstring_context_around_error*', + '*docstring_partial_context_around_error*', '005*text-line-3', '006*text-line-4', '013*text-line-11', @@ -213,6 +213,32 @@ class TestDoctests(object): assert 'text-line-2' not in result.stdout.str() assert 'text-line-after' not in result.stdout.str() + def test_docstring_full_context_around_error(self, testdir): + """Test that we show the whole context before the actual line of a failing + doctest, provided that the context is up to 10 lines long. + """ + testdir.makepyfile(''' + def foo(): + """ + text-line-1 + text-line-2 + + >>> 1 + 1 + 3 + """ + ''') + result = testdir.runpytest('--doctest-modules') + result.stdout.fnmatch_lines([ + '*docstring_full_context_around_error*', + '003*text-line-1', + '004*text-line-2', + '006*>>> 1 + 1', + 'Expected:', + ' 3', + 'Got:', + ' 2', + ]) + def test_doctest_linedata_missing(self, testdir): testdir.tmpdir.join('hello.py').write(_pytest._code.Source(""" class Fun(object):