1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 from unittest
import TextTestRunner
as _TestRunner
, TestResult
as _TestResult
8 from StringIO
import StringIO
11 '''Helper to make python unit tests report the way that the Mozilla
12 unit test infrastructure expects tests to report.
19 if __name__ == '__main__':
23 class _MozTestResult(_TestResult
):
24 def __init__(self
, stream
, descriptions
):
25 _TestResult
.__init
__(self
)
27 self
.descriptions
= descriptions
29 def getDescription(self
, test
):
31 return test
.shortDescription() or str(test
)
35 def addSuccess(self
, test
):
36 _TestResult
.addSuccess(self
, test
)
37 filename
= inspect
.getfile(test
.__class
__)
38 testname
= test
._testMethodName
39 self
.stream
.writeln("TEST-PASS | {0} | {1}".format(filename
, testname
))
41 def addError(self
, test
, err
):
42 _TestResult
.addError(self
, test
, err
)
43 self
.printFail(test
, err
)
45 def addFailure(self
, test
, err
):
46 _TestResult
.addFailure(self
, test
, err
)
47 self
.printFail(test
,err
)
49 def printFail(self
, test
, err
):
50 exctype
, value
, tb
= err
51 # Skip test runner traceback levels
52 while tb
and self
._is
_relevant
_tb
_level
(tb
):
55 self
.stream
.writeln("TEST-UNEXPECTED-FAIL | NO TRACEBACK |")
56 _f
, _ln
, _t
= inspect
.getframeinfo(tb
)[:3]
57 self
.stream
.writeln("TEST-UNEXPECTED-FAIL | {0} | line {1}, {2}: {3}"
58 .format(_f
, _ln
, _t
, value
.message
))
60 def printErrorList(self
):
61 for test
, err
in self
.errors
:
62 self
.stream
.writeln("ERROR: {0}".format(self
.getDescription(test
)))
63 self
.stream
.writeln("{0}".format(err
))
66 class MozTestRunner(_TestRunner
):
67 def _makeResult(self
):
68 return _MozTestResult(self
.stream
, self
.descriptions
)
70 result
= self
._makeResult
()
72 result
.printErrorList()
75 class MockedFile(StringIO
):
76 def __init__(self
, context
, filename
, content
= ''):
77 self
.context
= context
79 StringIO
.__init
__(self
, content
)
82 self
.context
.files
[self
.name
] = self
.getvalue()
88 def __exit__(self
, type, value
, traceback
):
91 class MockedOpen(object):
93 Context manager diverting the open builtin such that opening files
94 can open "virtual" file instances given when creating a MockedOpen.
96 with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
99 will thus open the virtual file instance for the file 'foo' to f.
101 MockedOpen also masks writes, so that creating or replacing files
102 doesn't touch the file system, while subsequently opening the file
103 will return the recorded content.
108 self.assertRaises(Exception,f.open('foo', 'r'))
110 def __init__(self
, files
= {}):
112 for name
, content
in files
.iteritems():
113 self
.files
[os
.path
.abspath(name
)] = content
115 def __call__(self
, name
, mode
= 'r'):
116 absname
= os
.path
.abspath(name
)
118 file = MockedFile(self
, absname
)
119 elif absname
in self
.files
:
120 file = MockedFile(self
, absname
, self
.files
[absname
])
122 file = MockedFile(self
, absname
, self
.open(name
, 'r').read())
124 file = self
.open(name
, mode
)
126 file.seek(0, os
.SEEK_END
)
131 self
.open = __builtin__
.open
132 __builtin__
.open = self
134 def __exit__(self
, type, value
, traceback
):
136 __builtin__
.open = self
.open
139 unittest
.main(testRunner
=MozTestRunner(),*args
)