"""unittest module for logilab.comon.testlib"""
__revision__ = '$Id: unittest_testlib.py,v 1.5 2006-02-09 22:37:46 nico Exp $'
import unittest
import os
import sys
from os.path import join, dirname, isdir, isfile
from cStringIO import StringIO
import tempfile
import shutil
from logilab.common.compat import sorted
try:
__file__
except NameError:
__file__ = sys.argv[0]
from logilab.common.testlib import TestCase, unittest_main, SkipAwareTextTestRunner
from logilab.common.testlib import mock_object, NonStrictTestLoader, create_files
from logilab.common.testlib import capture_stdout
class MockTestCase(TestCase):
def __init__(self):
# Do not call unittest.TestCase's __init__
pass
def fail(self, msg):
raise AssertionError(msg)
class UtilTC(TestCase):
def test_mockobject(self):
obj = mock_object(foo='bar', baz='bam')
self.assertEquals(obj.foo, 'bar')
self.assertEquals(obj.baz, 'bam')
def test_create_files(self):
chroot = tempfile.mkdtemp()
path_to = lambda path: join(chroot, path)
dircontent = lambda path: sorted(os.listdir(join(chroot, path)))
try:
self.failIf(isdir(path_to('a/')))
create_files(['a/b/foo.py', 'a/b/c/', 'a/b/c/d/e.py'], chroot)
# make sure directories exist
self.failUnless(isdir(path_to('a')))
self.failUnless(isdir(path_to('a/b')))
self.failUnless(isdir(path_to('a/b/c')))
self.failUnless(isdir(path_to('a/b/c/d')))
# make sure files exist
self.failUnless(isfile(path_to('a/b/foo.py')))
self.failUnless(isfile(path_to('a/b/c/d/e.py')))
# make sure only asked files were created
self.assertEquals(dircontent('a'), ['b'])
self.assertEquals(dircontent('a/b'), ['c', 'foo.py'])
self.assertEquals(dircontent('a/b/c'), ['d'])
self.assertEquals(dircontent('a/b/c/d'), ['e.py'])
finally:
shutil.rmtree(chroot)
class TestlibTC(TestCase):
def setUp(self):
self.tc = MockTestCase()
def test_dict_equals(self):
"""tests TestCase.assertDictEquals"""
d1 = {'a' : 1, 'b' : 2}
d2 = {'a' : 1, 'b' : 3}
d3 = dict(d1)
self.assertRaises(AssertionError, self.tc.assertDictEquals, d1, d2)
self.tc.assertDictEquals(d1, d3)
self.tc.assertDictEquals(d3, d1)
self.tc.assertDictEquals(d1, d1)
def test_list_equals(self):
"""tests TestCase.assertListEquals"""
l1 = range(10)
l2 = range(5)
l3 = range(10)
self.assertRaises(AssertionError, self.tc.assertListEquals, l1, l2)
self.tc.assertListEquals(l1, l1)
self.tc.assertListEquals(l1, l3)
self.tc.assertListEquals(l3, l1)
def test_lines_equals(self):
"""tests assertLineEquals"""
t1 = """some
text
"""
t2 = """some
text"""
t3 = """some
text"""
self.assertRaises(AssertionError, self.tc.assertLinesEquals, t1, t2)
self.tc.assertLinesEquals(t1, t3)
self.tc.assertLinesEquals(t3, t1)
self.tc.assertLinesEquals(t1, t1)
def test_xml_valid(self):
"""tests xml is valid"""
valid = """
Logilab
"""
invalid = """
"""
self.tc.assertXMLStringWellFormed(valid)
self.assertRaises(AssertionError, self.tc.assertXMLStringWellFormed, invalid)
invalid = """
"""
self.assertRaises(AssertionError, self.tc.assertXMLStringWellFormed, invalid)
def test_set_equality_for_lists(self):
l1 = [0, 1, 2]
l2 = [1, 2, 3]
self.assertRaises(AssertionError, self.tc.assertSetEqual, l1, l2)
self.tc.assertSetEqual(l1, l1)
self.tc.assertSetEqual([], [])
l1 = [0, 1, 1]
l2 = [0, 1]
self.assertRaises(AssertionError, self.tc.assertSetEqual, l1, l2)
self.tc.assertSetEqual(l1, l1)
def test_set_equality_for_dicts(self):
d1 = {'a' : 1, 'b' : 2}
d2 = {'a' : 1}
self.assertRaises(AssertionError, self.tc.assertSetEqual, d1, d2)
self.tc.assertSetEqual(d1, d1)
self.tc.assertSetEqual({}, {})
def test_set_equality_for_iterables(self):
self.assertRaises(AssertionError, self.tc.assertSetEqual, xrange(5), xrange(6))
self.tc.assertSetEqual(xrange(5), range(5))
self.tc.assertSetEqual([], ())
def test_file_equality(self):
foo = join(dirname(__file__), 'data', 'foo.txt')
spam = join(dirname(__file__), 'data', 'spam.txt')
self.assertRaises(AssertionError, self.tc.assertFileEqual, foo, spam)
self.tc.assertFileEqual(foo, foo)
def test_stream_equality(self):
foo = join(dirname(__file__), 'data', 'foo.txt')
spam = join(dirname(__file__), 'data', 'spam.txt')
stream1 = file(foo)
self.tc.assertStreamEqual(stream1, stream1)
stream1 = file(foo)
stream2 = file(spam)
self.assertRaises(AssertionError, self.tc.assertStreamEqual, stream1, stream2)
def test_text_equality(self):
foo = join(dirname(__file__), 'data', 'foo.txt')
spam = join(dirname(__file__), 'data', 'spam.txt')
text1 = file(foo).read()
self.tc.assertTextEqual(text1, text1)
text2 = file(spam).read()
self.assertRaises(AssertionError, self.tc.assertTextEqual, text1, text2)
class GenerativeTestsTC(TestCase):
def setUp(self):
output = StringIO()
self.runner = SkipAwareTextTestRunner(stream=output)
def test_generative_ok(self):
class FooTC(TestCase):
def test_generative(self):
for i in xrange(10):
yield self.assertEquals, i, i
result = self.runner.run(FooTC('test_generative'))
self.assertEquals(result.testsRun, 10)
self.assertEquals(len(result.failures), 0)
self.assertEquals(len(result.errors), 0)
def test_generative_half_bad(self):
class FooTC(TestCase):
def test_generative(self):
for i in xrange(10):
yield self.assertEquals, i%2, 0
result = self.runner.run(FooTC('test_generative'))
self.assertEquals(result.testsRun, 10)
self.assertEquals(len(result.failures), 5)
self.assertEquals(len(result.errors), 0)
def test_generative_error(self):
class FooTC(TestCase):
def test_generative(self):
for i in xrange(10):
if i == 5:
raise ValueError('STOP !')
yield self.assertEquals, i, i
result = self.runner.run(FooTC('test_generative'))
self.assertEquals(result.testsRun, 5)
self.assertEquals(len(result.failures), 0)
self.assertEquals(len(result.errors), 1)
def test_generative_error2(self):
class FooTC(TestCase):
def test_generative(self):
for i in xrange(10):
if i == 5:
yield self.ouch
yield self.assertEquals, i, i
def ouch(self): raise ValueError('stop !')
result = self.runner.run(FooTC('test_generative'))
self.assertEquals(result.testsRun, 6)
self.assertEquals(len(result.failures), 0)
self.assertEquals(len(result.errors), 1)
def test_generative_setup(self):
class FooTC(TestCase):
def setUp(self):
raise ValueError('STOP !')
def test_generative(self):
for i in xrange(10):
yield self.assertEquals, i, i
result = self.runner.run(FooTC('test_generative'))
self.assertEquals(result.testsRun, 1)
self.assertEquals(len(result.failures), 0)
self.assertEquals(len(result.errors), 1)
class ExitFirstTC(TestCase):
def setUp(self):
output = StringIO()
self.runner = SkipAwareTextTestRunner(stream=output, exitfirst=True)
def test_failure_exit_first(self):
class FooTC(TestCase):
def test_1(self): pass
def test_2(self): assert False
def test_3(self): pass
tests = [FooTC('test_1'), FooTC('test_2')]
result = self.runner.run(unittest.TestSuite(tests))
self.assertEquals(result.testsRun, 2)
self.assertEquals(len(result.failures), 1)
self.assertEquals(len(result.errors), 0)
def test_error_exit_first(self):
class FooTC(TestCase):
def test_1(self): pass
def test_2(self): raise ValueError()
def test_3(self): pass
tests = [FooTC('test_1'), FooTC('test_2'), FooTC('test_3')]
result = self.runner.run(unittest.TestSuite(tests))
self.assertEquals(result.testsRun, 2)
self.assertEquals(len(result.failures), 0)
self.assertEquals(len(result.errors), 1)
def test_generative_exit_first(self):
class FooTC(TestCase):
def test_generative(self):
for i in xrange(10):
yield self.assert_, False
result = self.runner.run(FooTC('test_generative'))
self.assertEquals(result.testsRun, 1)
self.assertEquals(len(result.failures), 1)
self.assertEquals(len(result.errors), 0)
class TestLoaderTC(TestCase):
## internal classes for test purposes ########
class FooTC(TestCase):
def test_foo1(self): pass
def test_foo2(self): pass
def test_bar1(self): pass
class BarTC(TestCase):
def test_bar2(self): pass
##############################################
def setUp(self):
self.loader = NonStrictTestLoader()
self.module = TestLoaderTC # mock_object(FooTC=TestLoaderTC.FooTC, BarTC=TestLoaderTC.BarTC)
def test_collect_everything(self):
"""make sure we don't change the default behaviour
for loadTestsFromModule() and loadTestsFromTestCase
"""
testsuite = self.loader.loadTestsFromModule(self.module)
self.assertEquals(len(testsuite._tests), 2)
suite1, suite2 = testsuite._tests
self.assertEquals(len(suite1._tests) + len(suite2._tests), 4)
def test_collect_with_classname(self):
collected = self.loader.loadTestsFromName('FooTC', self.module)
self.assertEquals(len(collected), 3)
collected = self.loader.loadTestsFromName('BarTC', self.module)
self.assertEquals(len(collected), 1)
def test_collect_with_classname_and_pattern(self):
data = [('FooTC.test_foo1', 1), ('FooTC.test_foo', 2), ('FooTC.test_fo', 2),
('FooTC.foo1', 1), ('FooTC.foo', 2), ('FooTC.whatever', 0)
]
for pattern, expected_count in data:
collected = self.loader.loadTestsFromName(pattern, self.module)
yield self.assertEquals, len(collected), expected_count
def test_collect_with_pattern(self):
data = [('test_foo1', 1), ('test_foo', 2), ('test_bar', 2),
('foo1', 1), ('foo', 2), ('bar', 2), ('ba', 2),
('test', 4), ('ab', 0),
]
for pattern, expected_count in data:
collected = self.loader.loadTestsFromName(pattern, self.module)
yield self.assertEquals, len(collected), expected_count
def bootstrap_print(msg, output=sys.stdout):
"""sys.stdout will be evaluated at function parsing time"""
# print msg
output.write(msg)
class OutErrCaptureTC(TestCase):
def setUp(self):
sys.stdout = sys.stderr = StringIO()
self.runner = SkipAwareTextTestRunner(stream=StringIO(), exitfirst=True, capture=True)
def tearDown(self):
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
def test_stdout_capture(self):
class FooTC(TestCase):
def test_stdout(self):
print "foo"
self.assert_(False)
test = FooTC('test_stdout')
result = self.runner.run(test)
captured_out, captured_err = test.captured_output()
self.assertEqual(captured_out.strip(), "foo")
self.assertEqual(captured_err.strip(), "")
def test_stderr_capture(self):
class FooTC(TestCase):
def test_stderr(self):
print >> sys.stderr, "foo"
self.assert_(False)
test = FooTC('test_stderr')
result = self.runner.run(test)
captured_out, captured_err = test.captured_output()
self.assertEqual(captured_out.strip(), "")
self.assertEqual(captured_err.strip(), "foo")
def test_both_capture(self):
class FooTC(TestCase):
def test_stderr(self):
print >> sys.stderr, "foo"
print "bar"
self.assert_(False)
test = FooTC('test_stderr')
result = self.runner.run(test)
captured_out, captured_err = test.captured_output()
self.assertEqual(captured_out.strip(), "bar")
self.assertEqual(captured_err.strip(), "foo")
def test_no_capture(self):
class FooTC(TestCase):
def test_stderr(self):
print >> sys.stderr, "foo"
print "bar"
self.assert_(False)
test = FooTC('test_stderr')
# this runner should not capture stdout / stderr
runner = SkipAwareTextTestRunner(stream=StringIO(), exitfirst=True)
result = runner.run(test)
captured_out, captured_err = test.captured_output()
self.assertEqual(captured_out.strip(), "")
self.assertEqual(captured_err.strip(), "")
def test_capture_core(self):
# output = capture_stdout()
# bootstrap_print("hello", output=sys.stdout)
# self.assertEquals(output.restore(), "hello")
output = capture_stdout()
bootstrap_print("hello")
self.assertEquals(output.restore(), "hello")
if __name__ == '__main__':
unittest_main()