Choose the doctest output format in case of failure, still work in progress as a few checks fail (related to #1749)

This commit is contained in:
Romain Dorgueil 2016-07-23 14:40:25 +02:00
parent 625b603f1f
commit fd8e019cc1
5 changed files with 109 additions and 8 deletions

View File

@ -94,6 +94,7 @@ Punyashloka Biswal
Quentin Pradet
Ralf Schmitt
Raphael Pierzina
Romain Dorgueil
Roman Bolshakov
Ronny Pfannschmidt
Ross Lawley

View File

@ -70,6 +70,9 @@ time or change existing behaviors in order to make them less surprising/more use
namespace in which doctests run.
Thanks `@milliams`_ for the complete PR (`#1428`_).
* New ``--doctest-report`` option available to change the output format of diffs
when running (failing) doctests. Implements `#1749`_.
* New ``name`` argument to ``pytest.fixture`` decorator which allows a custom name
for a fixture (to solve the funcarg-shadowing-fixture problem).
Thanks `@novas0x2a`_ for the complete PR (`#1444`_).

View File

@ -18,7 +18,9 @@ def pytest_addoption(parser):
help="run doctests in all .py modules",
dest="doctestmodules")
group.addoption("--doctest-report",
type=str, default="UDIFF", choices=_get_report_choices().keys(),
type=str.lower, default="udiff",
help="choose another output format for diffs on doctest failure",
choices=sorted(_get_report_choices().keys()),
dest="doctestreport")
group.addoption("--doctest-glob",
action="append", default=[], metavar="pat",
@ -62,7 +64,6 @@ class ReprFailDoctest(TerminalRepr):
class DoctestItem(pytest.Item):
def __init__(self, name, parent, runner=None, dtest=None):
super(DoctestItem, self).__init__(name, parent)
self.runner = runner
@ -297,11 +298,11 @@ def _get_allow_bytes_flag():
def _get_report_choices():
import doctest
return dict(
UDIFF=doctest.REPORT_UDIFF,
CDIFF=doctest.REPORT_CDIFF,
NDIFF=doctest.REPORT_NDIFF,
ONLY_FIRST_FAILURE=doctest.REPORT_ONLY_FIRST_FAILURE,
NONE=0,
udiff=doctest.REPORT_UDIFF,
cdiff=doctest.REPORT_CDIFF,
ndiff=doctest.REPORT_NDIFF,
only_first_failure=doctest.REPORT_ONLY_FIRST_FAILURE,
none=0,
)

View File

@ -16,7 +16,6 @@ from docstrings in all python modules (including regular
python test modules)::
pytest --doctest-modules
You can make these changes permanent in your project by
putting them into a pytest.ini file like this:
@ -102,6 +101,7 @@ itself::
>>> get_unicode_greeting() # doctest: +ALLOW_UNICODE
'Hello'
The 'doctest_namespace' fixture
-------------------------------
@ -130,3 +130,20 @@ which can then be used in your doctests directly::
10
"""
pass
Output format
-------------
You can change the diff output format on failure for your doctests
by using one of standard doctest modules format in options
(see :data:`python:doctest.REPORT_UDIFF`, :data:`python:doctest.REPORT_CDIFF`,
:data:`python:doctest.REPORT_NDIFF`, :data:`python:doctest.REPORT_ONLY_FIRST_FAILURE`)::
pytest --doctest-modules --doctest-report none
pytest --doctest-modules --doctest-report udiff
pytest --doctest-modules --doctest-report cdiff
pytest --doctest-modules --doctest-report ndiff
pytest --doctest-modules --doctest-report only_first_failure

View File

@ -475,6 +475,85 @@ class TestDoctests:
"--junit-xml=junit.xml")
reprec.assertoutcome(failed=1)
def _run_doctest_report(self, testdir, format):
testdir.makepyfile("""
def foo():
'''
>>> foo()
a b
0 1 4
1 2 4
2 3 6
'''
print(' a b\\n'
'0 1 4\\n'
'1 2 5\\n'
'2 3 6')
""")
return testdir.runpytest("--doctest-modules", "--doctest-report", format)
def test_doctest_report_udiff(self, testdir, format='udiff'):
result = self._run_doctest_report(testdir, format)
result.stdout.fnmatch_lines([
' 0 1 4',
' -1 2 4',
' +1 2 5',
' 2 3 6',
])
def test_doctest_report_cdiff(self, testdir):
result = self._run_doctest_report(testdir, 'cdiff')
result.stdout.fnmatch_lines([
' a b',
' 0 1 4',
' ! 1 2 4',
' 2 3 6',
' --- 1,4 ----',
' a b',
' 0 1 4',
' ! 1 2 5',
' 2 3 6',
])
def test_doctest_report_ndiff(self, testdir):
result = self._run_doctest_report(testdir, 'ndiff')
result.stdout.fnmatch_lines([
' a b',
' 0 1 4',
' - 1 2 4',
' ? ^',
' + 1 2 5',
' ? ^',
' 2 3 6',
])
def test_doctest_report_none_or_only_first_failure(self, testdir):
for format in 'none', 'only_first_failure':
result = self._run_doctest_report(testdir, format)
result.stdout.fnmatch_lines([
'Expected:',
' a b',
' 0 1 4',
' 1 2 4',
' 2 3 6',
'Got:',
' a b',
' 0 1 4',
' 1 2 5',
' 2 3 6',
])
def test_doctest_report_case_insensitive(self, testdir):
for format in 'udiff', 'UDIFF', 'uDiFf':
self.test_doctest_report_udiff(testdir, format)
def test_doctest_report_invalid(self, testdir):
result = self._run_doctest_report(testdir, 'obviously_invalid_format')
result.stderr.fnmatch_lines([
"*error: argument --doctest-report: invalid choice: 'obviously_invalid_format' (choose from*"
])
class TestLiterals: