PageRenderTime 31ms CodeModel.GetById 8ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/unit_tests/test_xunit.py

https://bitbucket.org/jpellerin/nose/
Python | 343 lines | 335 code | 8 blank | 0 comment | 5 complexity | b5aeb525449a60a794b3dc25ec95456c MD5 | raw file
  1
  2import sys
  3import os
  4import optparse
  5import re
  6import unittest
  7from xml.sax import saxutils
  8
  9from nose.pyversion import UNICODE_STRINGS
 10from nose.tools import eq_
 11from nose.plugins.xunit import Xunit, escape_cdata, id_split
 12from nose.exc import SkipTest
 13from nose.config import Config
 14
 15def mktest():
 16    class TC(unittest.TestCase):
 17        def runTest(self):
 18            pass
 19    test = TC()
 20    return test
 21
 22mktest.__test__ = False
 23
 24time_taken = re.compile(r'\d\.\d\d')
 25
 26class TestEscaping(unittest.TestCase):
 27
 28    def setUp(self):
 29        self.x = Xunit()
 30
 31    def test_all(self):
 32        eq_(self.x._quoteattr(
 33            '''<baz src="http://foo?f=1&b=2" quote="inix hubris 'maximus'?" />'''),
 34            ('"&lt;baz src=&quot;http://foo?f=1&amp;b=2&quot; '
 35                'quote=&quot;inix hubris \'maximus\'?&quot; /&gt;"'))
 36
 37    def test_unicode_is_utf8_by_default(self):
 38        if not UNICODE_STRINGS:
 39            eq_(self.x._quoteattr(u'Ivan Krsti\u0107'),
 40                '"Ivan Krsti\xc4\x87"')
 41
 42    def test_unicode_custom_utf16_madness(self):
 43        self.x.encoding = 'utf-16'
 44        utf16 = self.x._quoteattr(u'Ivan Krsti\u0107')[1:-1]
 45
 46        if UNICODE_STRINGS:
 47	    # If all internal strings are unicode, then _quoteattr shouldn't
 48	    # have changed anything.
 49            eq_(utf16, u'Ivan Krsti\u0107')
 50        else:
 51            # to avoid big/little endian bytes, assert that we can put it back:
 52            eq_(utf16.decode('utf16'), u'Ivan Krsti\u0107')
 53
 54    def test_control_characters(self):
 55        # quoting of \n, \r varies in diff. python versions
 56        n = saxutils.quoteattr('\n')[1:-1]
 57        r = saxutils.quoteattr('\r')[1:-1]
 58        eq_(self.x._quoteattr('foo\n\b\f\r'), '"foo%s??%s"' % (n, r))
 59        eq_(escape_cdata('foo\n\b\f\r'), 'foo\n??\r')
 60
 61class TestSplitId(unittest.TestCase):
 62
 63    def check_id_split(self, cls, name):
 64        split = id_split('%s.%s' % (cls, name))
 65        eq_(split[0], cls)
 66        eq_(split[1], name)
 67
 68    def test_no_parenthesis(self):
 69        self.check_id_split("test_parset", "test_args")
 70
 71    def test_no_dot_in_args(self):
 72        self.check_id_split("test_parset", "test_args(('x', [1, 2]),)")
 73
 74    def test_dot_in_args(self):
 75        self.check_id_split("test_parset", "test_args(('x.y', 1),)")
 76
 77    def test_grandchild_has_dot_in_args(self):
 78        self.check_id_split("test_grandparset.test_parset",
 79                            "test_args(('x.y', 1),)")
 80
 81class TestOptions(unittest.TestCase):
 82
 83    def test_defaults(self):
 84        parser = optparse.OptionParser()
 85        x = Xunit()
 86        x.add_options(parser, env={})
 87        (options, args) = parser.parse_args([])
 88        eq_(options.xunit_file, "nosetests.xml")
 89
 90    def test_file_from_environ(self):
 91        parser = optparse.OptionParser()
 92        x = Xunit()
 93        x.add_options(parser, env={'NOSE_XUNIT_FILE': "kangaroo.xml"})
 94        (options, args) = parser.parse_args([])
 95        eq_(options.xunit_file, "kangaroo.xml")
 96
 97    def test_file_from_opt(self):
 98        parser = optparse.OptionParser()
 99        x = Xunit()
100        x.add_options(parser, env={})
101        (options, args) = parser.parse_args(["--xunit-file=blagojevich.xml"])
102        eq_(options.xunit_file, "blagojevich.xml")
103
104class TestXMLOutputWithXML(unittest.TestCase):
105
106    def setUp(self):
107        self.xmlfile = os.path.abspath(
108            os.path.join(os.path.dirname(__file__), 
109                            'support', 'xunit.xml'))
110        parser = optparse.OptionParser()
111        self.x = Xunit()
112        self.x.add_options(parser, env={})
113        (options, args) = parser.parse_args([
114            "--with-xunit",
115            "--xunit-file=%s" % self.xmlfile
116        ])
117        self.x.configure(options, Config())
118
119        try:
120            import xml.etree.ElementTree
121        except ImportError:
122            self.ET = False
123        else:
124            self.ET = xml.etree.ElementTree
125
126    def tearDown(self):
127        os.unlink(self.xmlfile)
128
129    def get_xml_report(self):
130        class DummyStream:
131            pass
132        self.x.report(DummyStream())
133        f = open(self.xmlfile, 'rb')
134        return f.read()
135        f.close()
136
137    def test_addFailure(self):
138        test = mktest()
139        self.x.startTest(test)
140        try:
141            raise AssertionError("one is not 'equal' to two")
142        except AssertionError:
143            some_err = sys.exc_info()
144
145        self.x.addFailure(test, some_err)
146
147        result = self.get_xml_report()
148        print result
149
150        if self.ET:
151            tree = self.ET.fromstring(result)
152            eq_(tree.attrib['name'], "nosetests")
153            eq_(tree.attrib['tests'], "1")
154            eq_(tree.attrib['errors'], "0")
155            eq_(tree.attrib['failures'], "1")
156            eq_(tree.attrib['skip'], "0")
157
158            tc = tree.find("testcase")
159            eq_(tc.attrib['classname'], "test_xunit.TC")
160            eq_(tc.attrib['name'], "runTest")
161            assert time_taken.match(tc.attrib['time']), (
162                        'Expected decimal time: %s' % tc.attrib['time'])
163
164            err = tc.find("failure")
165            eq_(err.attrib['type'], "%s.AssertionError" % (AssertionError.__module__,))
166            err_lines = err.text.strip().split("\n")
167            eq_(err_lines[0], 'Traceback (most recent call last):')
168            eq_(err_lines[-1], 'AssertionError: one is not \'equal\' to two')
169            eq_(err_lines[-2], '    raise AssertionError("one is not \'equal\' to two")')
170        else:
171            # this is a dumb test for 2.4-
172            assert '<?xml version="1.0" encoding="UTF-8"?>' in result
173            assert '<testsuite name="nosetests" tests="1" errors="0" failures="1" skip="0">' in result
174            assert '<testcase classname="test_xunit.TC" name="runTest"' in result
175            assert '<failure type="exceptions.AssertionError"' in result
176            assert "AssertionError: one is not 'equal' to two" in result
177            assert "AssertionError(\"one is not 'equal' to two\")" in result
178            assert '</failure></testcase></testsuite>' in result
179
180    def test_addFailure_early(self):
181        test = mktest()
182        try:
183            raise AssertionError("one is not equal to two")
184        except AssertionError:
185            some_err = sys.exc_info()
186
187        # add failure without startTest, due to custom TestResult munging?
188        self.x.addFailure(test, some_err)
189
190        result = self.get_xml_report()
191        print result
192
193        if self.ET:
194            tree = self.ET.fromstring(result)
195            tc = tree.find("testcase")
196            assert time_taken.match(tc.attrib['time']), (
197                        'Expected decimal time: %s' % tc.attrib['time'])
198        else:
199            # this is a dumb test for 2.4-
200            assert '<?xml version="1.0" encoding="UTF-8"?>' in result
201            assert ('<testcase classname="test_xunit.TC" '
202                    'name="runTest" time="0') in result
203
204    def test_addError(self):
205        test = mktest()
206        self.x.startTest(test)
207        try:
208            raise RuntimeError("some error happened")
209        except RuntimeError:
210            some_err = sys.exc_info()
211
212        self.x.addError(test, some_err)
213
214        result = self.get_xml_report()
215        print result
216
217        if self.ET:
218            tree = self.ET.fromstring(result)
219            eq_(tree.attrib['name'], "nosetests")
220            eq_(tree.attrib['tests'], "1")
221            eq_(tree.attrib['errors'], "1")
222            eq_(tree.attrib['failures'], "0")
223            eq_(tree.attrib['skip'], "0")
224
225            tc = tree.find("testcase")
226            eq_(tc.attrib['classname'], "test_xunit.TC")
227            eq_(tc.attrib['name'], "runTest")
228            assert time_taken.match(tc.attrib['time']), (
229                        'Expected decimal time: %s' % tc.attrib['time'])
230
231            err = tc.find("error")
232            eq_(err.attrib['type'], "%s.RuntimeError" % (RuntimeError.__module__,))
233            err_lines = err.text.strip().split("\n")
234            eq_(err_lines[0], 'Traceback (most recent call last):')
235            eq_(err_lines[-1], 'RuntimeError: some error happened')
236            eq_(err_lines[-2], '    raise RuntimeError("some error happened")')
237        else:
238            # this is a dumb test for 2.4-
239            assert '<?xml version="1.0" encoding="UTF-8"?>' in result
240            assert '<testsuite name="nosetests" tests="1" errors="1" failures="0" skip="0">' in result
241            assert '<testcase classname="test_xunit.TC" name="runTest"' in result
242            assert '<error type="exceptions.RuntimeError"' in result
243            assert 'RuntimeError: some error happened' in result
244            assert '</error></testcase></testsuite>' in result
245
246    def test_non_utf8_error(self):
247        # See http://code.google.com/p/python-nose/issues/detail?id=395
248        test = mktest()
249        self.x.startTest(test)
250        try:
251            raise RuntimeError(chr(128)) # cannot encode as utf8 
252        except RuntimeError:
253            some_err = sys.exc_info()
254        self.x.addError(test, some_err)
255        result = self.get_xml_report()
256        print repr(result)
257        if self.ET:
258            tree = self.ET.fromstring(result)
259            tc = tree.find("testcase")
260            err = tc.find("error")
261            if UNICODE_STRINGS:
262                eq_(err.attrib['message'],
263                    '\x80')
264            else:
265                eq_(err.attrib['message'],
266                    u'\ufffd')
267        else:
268            # this is a dumb test for 2.4-
269            assert 'RuntimeError: \xef\xbf\xbd' in result
270
271    def test_addError_early(self):
272        test = mktest()
273        try:
274            raise RuntimeError("some error happened")
275        except RuntimeError:
276            some_err = sys.exc_info()
277
278        # call addError without startTest
279        # which can happen if setup() raises an error
280        self.x.addError(test, some_err)
281
282        result = self.get_xml_report()
283        print result
284
285        if self.ET:
286            tree = self.ET.fromstring(result)
287            tc = tree.find("testcase")
288            assert time_taken.match(tc.attrib['time']), (
289                        'Expected decimal time: %s' % tc.attrib['time'])
290        else:
291            # this is a dumb test for 2.4-
292            assert '<?xml version="1.0" encoding="UTF-8"?>' in result
293            assert ('<testcase classname="test_xunit.TC" '
294                    'name="runTest" time="0') in result
295
296    def test_addSuccess(self):
297        test = mktest()
298        self.x.startTest(test)
299        self.x.addSuccess(test, (None,None,None))
300
301        result = self.get_xml_report()
302        print result
303
304        if self.ET:
305            tree = self.ET.fromstring(result)
306            eq_(tree.attrib['name'], "nosetests")
307            eq_(tree.attrib['tests'], "1")
308            eq_(tree.attrib['errors'], "0")
309            eq_(tree.attrib['failures'], "0")
310            eq_(tree.attrib['skip'], "0")
311
312            tc = tree.find("testcase")
313            eq_(tc.attrib['classname'], "test_xunit.TC")
314            eq_(tc.attrib['name'], "runTest")
315            assert time_taken.match(tc.attrib['time']), (
316                        'Expected decimal time: %s' % tc.attrib['time'])
317        else:
318            # this is a dumb test for 2.4-
319            assert '<?xml version="1.0" encoding="UTF-8"?>' in result
320            assert '<testsuite name="nosetests" tests="1" errors="0" failures="0" skip="0">' in result
321            assert '<testcase classname="test_xunit.TC" name="runTest"' in result
322            assert '</testsuite>' in result
323
324    def test_addSuccess_early(self):
325        test = mktest()
326        # call addSuccess without startTest
327        # which can happen (?) -- did happen with JsLint plugin
328        self.x.addSuccess(test, (None,None,None))
329
330        result = self.get_xml_report()
331        print result
332
333        if self.ET:
334            tree = self.ET.fromstring(result)
335            tc = tree.find("testcase")
336            assert time_taken.match(tc.attrib['time']), (
337                        'Expected decimal time: %s' % tc.attrib['time'])
338        else:
339            # this is a dumb test for 2.4-
340            assert '<?xml version="1.0" encoding="UTF-8"?>' in result
341            assert ('<testcase classname="test_xunit.TC" '
342                    'name="runTest" time="0') in result
343