Unittest单元测试框架


  • 什么是单元测试?

单元测试是对最小的软件设计单元(模块、类)进行验证,它使用开发文档中对模块的描述作为指南,对重要的程序分支进行测试以发现模块中的错误。

  •  单元测试框架可以解决说明问题?

1、提供用例组织与执行

2、提供丰富的断言方法

3、提供丰富的日志

 

  • 重要概念

1.Test Case 测试用例

继承unittest.TestCase的子类里的每个名为test*的函数都被视为单个测试用例,前后执行setUp()和tearDown()

 

 

2.Test Suite 测试用例集合——把多个测试用例集合在一起执行,可以通过addTest加载TestCase到TestSuite中。

  -单元测试的加载方式有2种:一种是通过unittest.main()来启动单元测试的测试模块(文件);1.被测试类继承了unittest.TestCase;2.被测试的函数名为test*

  -一种是添加到testsuite集合中再加载所有的被测试对象,而testsuit里存放的就是单元测试的用例。

  (另一种TestLoader类的dicover方法直接加载文件中所有被测试对象,其实也应用了testsuite原理)

 

 1 # -*-coding:utf-8-*-
 2 
 3 import unittest
 4 
 5 def setUpModule():  # 模块的前后执行
 6     print("测试模块开始-------")
 7 def tearDownModule():
 8     print("测试模块结束=======")
 9 
10 class Test(unittest.TestCase):
11 
12     @classmethod
13     def setUpClass(cls):    # 类的前后执行
14         print("测试类开始------")
15     @classmethod
16     def tearDownClass(cls):
17         print("测试类结束=======")
18 
19     def setUp(self):    # 函数的前后执行
20         print("测试用例开始------")
21     def tearDown(self):
22         print("测试用例结束======")
23     def test_case(self):
24         print("我是用例")
25 
26 unittest.main()
示例代码

 

 

3.Test Runner 执行

通过TextTestRunner类提供的run()方法来执行test suite/test case,test runner可以使用图形界面、文本界面,或返回一个特殊的值方法来表示测试执行的结果。

  runner = unittest.TextTestRunner()

  runner.run(xxx)

4.Test Fixture 执行前后的操作setUp()和tearDown() 

 1 # -*-coding:utf-8-*-
 2 
 3 import unittest
 4 
 5 def setUpModule():
 6 print("测试模块开始-------")
 7 def tearDownModule():
 8 print("测试模块结束=======")
 9 
10 class Test(unittest.TestCase):
11 
12 @classmethod
13 def setUpClass(cls):
14 print("测试类开始------")
15 @classmethod
16 def tearDownClass(cls):
17 print("测试类结束=======")
18 
19 def setUp(self):
20 print("测试用例开始------")
21 def tearDown(self):
22 print("测试用例结束======")
23 def test_case(self):
24 print("我是用例")
25 
26 unittest.main()
View Code

 

 

 

  • 断言方法

unittest的TestCase类提供下面方法用于测试结果的判断:

断言语法 解释
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)  断言a是b的一个实例

assertNotIsInstance(a, b) 

not isinstance(a, b)  断言a不是b的实例

 python的unittest单元测试框架断言整理汇总  

 

 

  - assertEqual(a , b , msg=None)

断言第一个参数a和第二个参数b是否相等,如果不等则测试失败Fail。msg为可选参数,用于定义测试失败时打印的信息。

 

 

  • TestLoader类

  discover以py文件(模块)化方式一次执行模块里所有名为test*的函数。替代了suite.addTest()。

  正常情况下,不需要创建这个类的实例。unittest提供了可以共享的defaultTestLoader类,可以直接使用。

  - unittest.defaultTestLoad.discover(star_dir, pattern='test*.py', top_level_dir=None)

    - 注意:每个文件夹中必须创建__init__.py文件,discover才能识别文件夹里名为test*.py的文件。

 

 1 import unittest
 2 
 3 # discover()方法会匹配指定当前目录下./的所有test*.py的用例文件,并将查找到的测试用例组装到测试套件赋在discover中
 4 
 5 test_dir = './'
 6 discover = unittest.defaultTestLoader.discover(test_dir, pattern='test*.py')
 7 
 8 # 直接通过run()方法执行
 9 
10 if __name__ == '__main__':
11 runner = unittest.TextTestRunner()
12 runner.run(discover)
View Code
 
 
 
  • 用例执行顺序

unnitest框架默认根据同级目录下模块或文件名的ASCII码的顺序来加载测试用例,所以只能通过命名来改变执行顺序。除非用TestSuite类的addTest()方法按照别的顺序加载。

文件 > 类 >函数

A~Z,a~z,0~9,

例:(当用discover时)

aaa文件夹-testsub.py

testadd.py

  -aaa文件与testadd.py同级,但aaa的ASCII码<testadd的ASCII码,所以aaa文件夹-testsub.py要优先于testadd.py!

 

  • unittest如何识别多层目录?

在每个目录加上__init__.py文件,就可以识别当前目录以下的所有文件——一个包是一个带有特殊文件 __init__.py 的目录。__init__.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。如果 __init__.py 不存在,这个目录就仅仅是一个目录,而不是一个包,它就不能被导入或者包含其它的模块和嵌套包。

Python中__init__.py文件的作用详解 http://www.jb51.net/article/92863.htm

 

 

  • 跳过测试和预期失败

 

 1 # -*-coding:utf-8-*-
 2 import unittest
 3 
 4 class MyTest(unittest.TestCase):
 5     @unittest.skip("必输入reason") # 无条件跳过测试,说明原因
 6     def test_skip1(self):
 7         print('直接跳过测试~')
 8     @unittest.skipIf(3>2,"必输入reason") # 如果条件为真,跳过测试
 9     def test_skip2_if(self):
10         print('条件为真,则跳过测试~')
11     @unittest.skipUnless(3>2,"必输入reason") # 如果条件为假,跳过测试
12     def test_skip3_unless(self):
13         print('条件为假,则跳过测试')
14     @unittest.expectedFailure   # 不管结果如何,不抛错
15     def test_excepted_failure(self):
16         self.assertEqual(2, 2)
17 
18 
19 unittest.main()
View Code

 

 

 

  •  保存测试结果报告

打开cmd,到runtest.py模块的当前目录,新建文件夹report,输入:

> python runtest.py >> report/log.txt 2>&1

发现生成了一个report文件夹里的log.txt为结果报告。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM