定义
unittest是python标准库自带的测试模块
参考资料:
https://docs.python.org/zh-cn/3/library/unittest.html#unittest.TestCase.assertMultiLineEqual
示例
测试文件为test_example.py
import unittest
class TestStringMethods(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
self.assertTrue('FOO'.isupper())
def test_split(self):
s = 'hello world'
self.assertEqual(s.split(),['hello','world'])
with self.assertRaises(TypeError):
s.split(2)
if __name__ =='__main__':
unittest.main()
- 有setUp()和tearDown()
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
widget = Widget('The widget')
def test_default_widget_size(self):
self.assertEqual(widget.size(),(50,50),'incorrect default size')
def test_widget_resize(self):
self.widget.resize(100,150)
self.assertEqual(self.widget.size(),(100, 150),'wrong size after resize')
def tearDown():
self.widget.dispose()
def suite():
suite = unittest.TestCase()
suite.addTest(WidgetTestCase('test_default_widget_size'))
suite.addTest(WidgetTestCase('test_widget_resize'))
return suite
if __name__ == '__main__':
# unittest.main()
runner = unittest.TextTestRunner()
runner.run(suite())
注意点
- 测试的方法名称必须以字符串test开始,否则不会执行;
- 测试代码模块(文件)名称默认需要满足test*.py,但也可以从命令行中提供–pattern关键字参数来指定任意模式。
- 运行命令
运行整个文件
python -m unittest test_example
运行测试文件里的某一个类
python -m unittest test_example.MyTest
- setup():是前置条件,当每一个测试用例前必须要经过一个步骤,就可以把这个步骤放在setup()里面;
- 如果SetUp(),引发异常,那么测试框架会认为测试发生了错误,将不会运行。
- tearDown()方法在测试运行后进行清理工作
- 如果setUp()运行成功,那么无论中间的方法是否能成功,都会运行tearDown()。
- 被跳过的skip()的setUp和tearDown()都不会被执行。
- 自定义测试套件 test suite,以unitetest的类TestSuite为代表的,大部分情况下,调用unittetse.main()就可以,它会集合所有的模块测试用例并且执行:
def suite():
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase('test_default_widget_size'))
suite.addTest(WidgetTestCase('test_widget_resize'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
- 复用已有的测试用例,unittest提供了FunctionTest类,并且提供了前置和后置函数,此方法不推荐,应当花些时间创建更合适的测试子类
- 跳过失败与预计的失败:可以使用 装饰类skip(),类也可以被跳过;
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
def test_not_run(self):
pass
@unittest.skip(reason)
跳过被此装饰器装饰的测试。 reason 为测试被跳过的原因。
@unittest.skipIf(condition, reason)
当 condition 为真时,跳过被装饰的测试。
@unittest.skipUnless(condition, reason)
跳过被装饰的测试,除非 condition 为真。
@unittest.expectedFailure
把测试标记为预计失败。如果测试不通过,会被认为测试成功;如果测试通过了,则被认为是测试失败。
exception unittest.SkipTest(reason)
引发此异常以跳过一个测试。
- 常用的 断言
assertEqual(a,b) : a==b
assertNotEqual(a,b): a!=b
assertTrue(x): bool(x) is True
assertFalse(x):bool(x) is False
assertIs(a,b): a is b
assertIsNot(a,b): a is not b
assertIsNone(x): x is none
assertIsNotNone(x): x is not none
assertIn(a,b): a in b
assertNotIn(a,b): a not in b
assertIsInstance(a,b):: isinstance(a,b)
assertNotIsInstance(a,b): not isinstance(a,b)
assertAlmostEqual(a,b):
assertNotAlmostEqual(a,b):
assertGreater(a,b): a>b
assertGreaterEqual(a,b): a>=b
assertLess(a,b):a<b
assertLessEqual(a,b):a<=b
assertRegex(s,r): r.search(s)
assertNotRegex(s,r):not r.search(s)
assertCountEqual(a,b):a,b中含有相同元素的数量