Merged hpk42/pytest into default

This commit is contained in:
Brianna Laugher 2013-05-21 11:18:37 +10:00
commit f2175146a9
3 changed files with 119 additions and 10 deletions

View File

@ -11,6 +11,11 @@ Changes between 2.3.5 and 2.4.DEV
when importing markers between modules. Specifying conditions when importing markers between modules. Specifying conditions
as strings will remain fully supported. as strings will remain fully supported.
- improved doctest counting for doctests in python modules --
files without any doctest items will not show up anymore
and doctest examples are counted as separate test items.
thanks Danilo Bellini.
- fix issue245 by depending on the released py-1.4.14 - fix issue245 by depending on the released py-1.4.14
which fixes py.io.dupfile to work with files with no which fixes py.io.dupfile to work with files with no
mode. Thanks Jason R. Coombs. mode. Thanks Jason R. Coombs.

View File

@ -34,6 +34,14 @@ class ReprFailDoctest(TerminalRepr):
self.reprlocation.toterminal(tw) self.reprlocation.toterminal(tw)
class DoctestItem(pytest.Item): class DoctestItem(pytest.Item):
def __init__(self, name, parent, runner=None, dtest=None):
super(DoctestItem, self).__init__(name, parent)
self.runner = runner
self.dtest = dtest
def runtest(self):
self.runner.run(self.dtest)
def repr_failure(self, excinfo): def repr_failure(self, excinfo):
doctest = py.std.doctest doctest = py.std.doctest
if excinfo.errisinstance((doctest.DocTestFailure, if excinfo.errisinstance((doctest.DocTestFailure,
@ -76,7 +84,7 @@ class DoctestItem(pytest.Item):
return super(DoctestItem, self).repr_failure(excinfo) return super(DoctestItem, self).repr_failure(excinfo)
def reportinfo(self): def reportinfo(self):
return self.fspath, None, "[doctest]" return self.fspath, None, "[doctest] %s" % self.name
class DoctestTextfile(DoctestItem, pytest.File): class DoctestTextfile(DoctestItem, pytest.File):
def runtest(self): def runtest(self):
@ -91,8 +99,8 @@ class DoctestTextfile(DoctestItem, pytest.File):
extraglobs=dict(getfixture=fixture_request.getfuncargvalue), extraglobs=dict(getfixture=fixture_request.getfuncargvalue),
raise_on_error=True, verbose=0) raise_on_error=True, verbose=0)
class DoctestModule(DoctestItem, pytest.File): class DoctestModule(pytest.File):
def runtest(self): def collect(self):
doctest = py.std.doctest doctest = py.std.doctest
if self.fspath.basename == "conftest.py": if self.fspath.basename == "conftest.py":
module = self.config._conftest.importconftest(self.fspath) module = self.config._conftest.importconftest(self.fspath)
@ -102,7 +110,11 @@ class DoctestModule(DoctestItem, pytest.File):
self.funcargs = {} self.funcargs = {}
self._fixtureinfo = FuncFixtureInfo((), [], {}) self._fixtureinfo = FuncFixtureInfo((), [], {})
fixture_request = FixtureRequest(self) fixture_request = FixtureRequest(self)
failed, tot = doctest.testmod( doctest_globals = dict(getfixture=fixture_request.getfuncargvalue)
module, raise_on_error=True, verbose=0, # uses internal doctest module parsing mechanism
extraglobs=dict(getfixture=fixture_request.getfuncargvalue), finder = doctest.DocTestFinder()
optionflags=doctest.ELLIPSIS) runner = doctest.DebugRunner(verbose=0, optionflags=doctest.ELLIPSIS)
for test in finder.find(module, module.__name__,
extraglobs=doctest_globals):
if test.examples: # skip empty doctests
yield DoctestItem(test.name, self, runner, test)

View File

@ -1,4 +1,4 @@
from _pytest.doctest import DoctestModule, DoctestTextfile from _pytest.doctest import DoctestItem, DoctestModule, DoctestTextfile
import py, pytest import py, pytest
class TestDoctests: class TestDoctests:
@ -19,13 +19,61 @@ class TestDoctests:
items, reprec = testdir.inline_genitems(w) items, reprec = testdir.inline_genitems(w)
assert len(items) == 1 assert len(items) == 1
def test_collect_module(self, testdir): def test_collect_module_empty(self, testdir):
path = testdir.makepyfile(whatever="#") path = testdir.makepyfile(whatever="#")
for p in (path, testdir.tmpdir):
items, reprec = testdir.inline_genitems(p,
'--doctest-modules')
assert len(items) == 0
def test_collect_module_single_modulelevel_doctest(self, testdir):
path = testdir.makepyfile(whatever='""">>> pass"""')
for p in (path, testdir.tmpdir): for p in (path, testdir.tmpdir):
items, reprec = testdir.inline_genitems(p, items, reprec = testdir.inline_genitems(p,
'--doctest-modules') '--doctest-modules')
assert len(items) == 1 assert len(items) == 1
assert isinstance(items[0], DoctestModule) assert isinstance(items[0], DoctestItem)
assert isinstance(items[0].parent, DoctestModule)
def test_collect_module_two_doctest_one_modulelevel(self, testdir):
path = testdir.makepyfile(whatever="""
'>>> x = None'
def my_func():
">>> magic = 42 "
""")
for p in (path, testdir.tmpdir):
items, reprec = testdir.inline_genitems(p,
'--doctest-modules')
assert len(items) == 2
assert isinstance(items[0], DoctestItem)
assert isinstance(items[1], DoctestItem)
assert isinstance(items[0].parent, DoctestModule)
assert items[0].parent is items[1].parent
def test_collect_module_two_doctest_no_modulelevel(self, testdir):
path = testdir.makepyfile(whatever="""
'# Empty'
def my_func():
">>> magic = 42 "
def unuseful():
'''
# This is a function
# >>> # it doesn't have any doctest
'''
def another():
'''
# This is another function
>>> import os # this one does have a doctest
'''
""")
for p in (path, testdir.tmpdir):
items, reprec = testdir.inline_genitems(p,
'--doctest-modules')
assert len(items) == 2
assert isinstance(items[0], DoctestItem)
assert isinstance(items[1], DoctestItem)
assert isinstance(items[0].parent, DoctestModule)
assert items[0].parent is items[1].parent
def test_simple_doctestfile(self, testdir): def test_simple_doctestfile(self, testdir):
p = testdir.maketxtfile(test_doc=""" p = testdir.maketxtfile(test_doc="""
@ -164,3 +212,47 @@ class TestDoctests:
""") """)
reprec = testdir.inline_run(p, "--doctest-modules") reprec = testdir.inline_run(p, "--doctest-modules")
reprec.assertoutcome(passed=1) reprec.assertoutcome(passed=1)
def test_doctestmodule_three_tests(self, testdir):
p = testdir.makepyfile("""
'''
>>> dir = getfixture('tmpdir')
>>> type(dir).__name__
'LocalPath'
'''
def my_func():
'''
>>> magic = 42
>>> magic - 42
0
'''
def unuseful():
pass
def another():
'''
>>> import os
>>> os is os
True
'''
""")
reprec = testdir.inline_run(p, "--doctest-modules")
reprec.assertoutcome(passed=3)
def test_doctestmodule_two_tests_one_fail(self, testdir):
p = testdir.makepyfile("""
class MyClass:
def bad_meth(self):
'''
>>> magic = 42
>>> magic
0
'''
def nice_meth(self):
'''
>>> magic = 42
>>> magic - 42
0
'''
""")
reprec = testdir.inline_run(p, "--doctest-modules")
reprec.assertoutcome(failed=1, passed=1)