单元测试框架的用途:提供用例组织与执行、提供丰富断言方法、提供丰富的日志
unittest的4个重要概念:
1. TestCase :一个TestCase的实例就是一个测试用例,一个完整的测试流程,包括测试前准备环境的搭建(setUp)、实现测试过程的代码(以"test"开头的方法)、测试后环境的还原(tearDown)
2. TestSuite: 一个功能的验证往往需要多个测试用例,可以把多个测试用例集合在一起执行,这就形成了测试集合(TestSuite).Test Suite用来组装单个测试用例。可以通过addTest()方法加载TestCase 到 TestSuite中,从而返回一个TestSuite实例
3. TestRunner : 测试用例的 执行,通过TextTestRunner类提供的run()方法来执行 test suite、test case. test runner可以使用图形界面、文本界面,或返回一个特殊值等方式来表示测试执行的结果。
4. Test Fixture: 测试用例环境的搭建和销毁。通过覆盖TestCase的setUp() 和 tearDown() 方法来实现。比如,在测试用例中需要访问数据库,可以在setUp()中通过建立数据库连接来进行初始化,在 tearDown()中清除数据库产生的数据,然后关闭连接。
被测文件Calculator.py
#coding=utf-8
class Count(object):
def __init__(self,a,b):
self.a = int(a)
self.b = int(b)
def add(self):
return self.a + self.b
def sub(self):
return self.a - self.b
def is_prime(b):
if b<= 1:
return False
for i in range(2,b):
if b%i == 0:
return False
return True
测试代码 test_calculator.py
#coding=utf-8
import unittest
from calculator import Count,is_prime
class TestAdd(unittest.TestCase):
def setUp(self):
print('test add start')
def tearDown(self):
print('test add end')
def test_add(self):
j = Count(2,3)
self.assertEqual(j.add(),5)
def test_add2(self):
j = Count(41,76)
self.assertEqual(j.add(),117)
class Test_prime(unittest.TestCase):
def setUp(self):
print('test prime start')
def tearDown(self):
print('test prime end')
def test_prime(self):
self.assertTrue(is_prime(7),msg='Is not prime')
class TestSub(unittest.TestCase):
def setUp(self):
print("test sub start")
def tearDown(self):
print("test sub end")
def test_sub(self):
s = Count(4,3)
self.assertGreater(3,s.sub())
def test_sub2(self):
s = Count(3,5)
self.assertEqual(s.sub(),-2)
if __name__=='__main__':
# # 构造测试集(按照构造顺序执行测试用例)
# suite = unittest.TestSuite()
# suite.addTest(TestAdd('test_add2'))
# suite.addTest(TestSub('test_sub2'))
# suite.addTest(Test_prime('test_prime'))
#
# # 执行测试
# runner = unittest.TextTestRunner()
# runner.run(suite)
# 按照默认顺序执行该测试文件中所有的测试用例
unittest.main()
通过TestLoader类的discover方法执行匹配的测试用例 runtest.py
#coding=utf-8
import unittest
import test_add,test_sub
# # 构造测试集
# suite = unittest.TestSuite()
# suite.addTest(test_add.TestAdd('test_add'))
# suite.addTest(test_add.TestAdd('test_add2'))
#
# suite.addTest(test_sub.TestSub('test_sub'))
# suite.addTest(test_sub.TestSub('test_sub2'))
#
# runner = unittest.TextTestRunner()
# runner.run(suite)
# 通过TestLoader类的discover()方法自动识别测试用例
# discover(start_dir,pattern='test*.py',top_level_dir=None)
test_dir = "./"
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')
runner = unittest.TextTestRunner()
runner.run(discover)
跳过测试和预期失败 skip_expected_failures.py
#coding=utf-8
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
@unittest.skip('直接跳过测试')
def test_skip(self):
print("test skip")
@unittest.skipIf(3>2,"当条件为True时跳过测试")
def test_skip_if(self):
print("test skip if")
@unittest.skipUnless(3>2,"当条件为True时执行测试")
def test_skip_unless(self):
print("test skip unless")
@unittest.expectedFailure
def test_expected_failure(self):
self.assertEqual(2,3)
if __name__=="__main__":
unittest.main()
fixtures介绍:fixture.py
#coding=utf-8
import unittest
'''
setUpModule/tearDownModule:在整个模块开始与结束时被执行
setUpClass/tearDownClass: 在测试类的开始与结束时被执行
setUp/tearDown: 在用例的开始与结束时被执行
'''
def setUpModule():
print("test module start>>>>")
def tearDownModule():
print("test module end>>>>")
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("test setUpClass-----------------")
@classmethod
def tearDownClass(cls):
print("test tearDownClass-----------------")
def setUp(self):
print("test setUp********")
def tearDown(self):
print("test tearDown*******")
def test_case(self):
print('test case1')
def test_case2(self):
print('test case2')
if __name__=="__main__":
unittest.main()