2
# Copyright (c) 2006, 2007 Canonical
4
# Written by Gustavo Niemeyer <gustavo@niemeyer.net>
6
# This file is part of Storm Object Relational Mapper.
8
# Storm is free software; you can redistribute it and/or modify
9
# it under the terms of the GNU Lesser General Public License as
10
# published by the Free Software Foundation; either version 2.1 of
11
# the License, or (at your option) any later version.
13
# Storm is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU Lesser General Public License for more details.
18
# You should have received a copy of the GNU Lesser General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
Machinery to make py.test interpret standard unittest.TestCase classes.
24
from unittest import TestCase, TestResult
28
import py.test.collect
33
class PyTestResult(TestResult):
34
def addFailure(self, test, exc_info):
35
traceback = exc_info[2]
36
while traceback.tb_next:
37
traceback = traceback.tb_next
38
locals = traceback.tb_frame.f_locals
39
if "msg" in locals or "excClass" in locals:
40
locals["__tracebackhide__"] = True
41
msg = str(exc_info[1])
43
if "expr" in locals and "msg" in locals:
44
msg = repr(locals["expr"])
47
raise py.test.Item.Failed, py.test.Item.Failed(msg=msg), exc_info[2]
50
class PyTestCase(TestCase):
51
def __init__(self, methodName="setUp"):
52
super(PyTestCase, self).__init__(methodName)
54
class Function(py.test.Function):
55
def execute(self, target, *args):
56
__tracebackhide__ = True
58
self.__init__(target.__name__)
59
self.run(PyTestResult())
61
class PyDocTest(py.test.collect.Module):
62
def __init__(self, fspath, parent=None):
63
super(PyDocTest, self).__init__(fspath.basename, parent)
71
return self.Function(name, parent=self, obj=self.fspath)
73
class Function(py.test.Function):
74
def getpathlineno(self):
75
code = py.code.Code(self.failed)
76
return code.path, code.firstlineno
78
def failed(self, msg):
79
raise self.Failed(msg)
81
def execute(self, fspath):
82
failures, total = doctest.testfile(str(fspath),
83
module_relative=False,
84
optionflags=doctest.ELLIPSIS)
86
__tracebackhide__ = True
87
self.failed("%d doctest cases" % failures)
89
class UnitTestModule(py.test.collect.Module):
90
def buildname2items(self):
92
for name in dir(self.obj):
94
obj = getattr(self.obj, name)
97
if issubclass(obj, (TestCase, PyTestCase)):
103
d[name] = self.Class(name, parent=self)
104
if not issubclass(testclass, PyTestCase):
107
testclass = queue.pop(0)
108
if TestCase in testclass.__bases__:
109
bases = list(testclass.__bases__)
110
bases[bases.index(TestCase)] = PyTestCase
111
testclass.__bases__ = tuple(bases)
113
queue.extend(testclass.__bases__)
116
class UnitTestDirectory(py.test.collect.Directory):
117
def __init__(self, *args, **kwargs):
118
if getattr(self.__class__, "__first_run__", True):
119
self.__class__.__first_run__ = False
120
super(UnitTestDirectory, self).__init__(*args, **kwargs)
122
def filefilter(self, path):
123
return path.check(fnmatch="*.py") and path.basename != "conftest.py"
125
def makeitem(self, basename, filefilter=None, recfilter=None):
126
path = self.fspath.join(basename)
127
if path.check(fnmatch="*.txt"):
128
return PyDocTest(path, parent=self)
129
return super(UnitTestDirectory, self).makeitem(basename,
130
filefilter, recfilter)
132
Module = UnitTestModule
133
Directory = UnitTestDirectory