B001:python单元测试框架unittest

python单元测试框架unittest

单元测试的加载方式有2种:一种是通过unittest.main()来启动单元测试的测试模块;一种是添加到testsuite集合中再加载所有的被测试对象,而testsuit里存放的就是单元测试的用例,下面分别列出了2种方法的使用。

1.通过unittest.main()来跑

1.1 测试模块中的函数:

被测模块:

[python] view plaincopy

1. #!/usr/bin/env python  

2. #encoding: utf-8  

3.       

4. def sum( x, y):  

5.         return x+y  

6.       

7.       

8. def sub( x, y):  

9.         return x-y   

单元测试模块:

[python] view plaincopy

1. #!/usr/bin/env python  

2. #encoding: utf-8  

3.   

4. import unittest  

5. import myclass  

6.   

7. class mytest(unittest.TestCase):  

8.       

9.     ##初始化工作  

10.    def setUp(self):  

11.        pass  

12.      

13.    #退出清理工作  

14.    def tearDown(self):  

15.        pass  

16.      

17.    #具体的测试用例,一定要以test开头  

18.    def testsum(self):  

19.        self.assertEqual(myclass.sum(1, 2), 2, 'test sum fail')  

20.          

21.          

22.    def testsub(self):  

23.        self.assertEqual(myclass.sub(2, 1), 1, 'test sub fail')     

24.          

25.          

26.if __name__ =='__main__':  

27.    unittest.main()  

测试结果:【F表示一个fail, F前的点表示一个通过,有E的话表示程序自身异常】

 

1.2 测试模块类中的函数:

被测模块:

[python] view plaincopy

1. #!/usr/bin/env python  

2. #encoding: utf-8  

3.   

4. class myclass:  

5.     def __init__(self):  

6.         pass  

7.       

8.       

9.     def sum(self, x, y):  

10.        return x+y  

11.      

12.      

13.    def sub(self, x, y):  

14.        return x-y   

单元测试模块:

[python] view plaincopy

1. #!/usr/bin/env python  

2. #encoding: utf-8  

3.   

4. import unittest  

5. import myclass  

6.   

7. class mytest(unittest.TestCase):  

8.       

9.     ##初始化工作  

10.    def setUp(self):  

11.        self.tclass = myclass.myclass()   ##实例化了被测试模块中的类  

12.      

13.    #退出清理工作  

14.    def tearDown(self):  

15.        pass  

16.      

17.    #具体的测试用例,一定要以test开头  

18.    def testsum(self):  

19.        self.assertEqual(self.tclass.sum(1, 2), 3)  

20.          

21.          

22.if __name__ =='__main__':  

23.    unittest.main()  

运行结果:

[python] view plaincopy

1. .  

2. ----------------------------------------------------------------------  

3. Ran 1 test in 0.000s  

4.   

5. OK  

这种方式执行单个测试文件时使用-v参数可以获得更多的测试结果信息。如:mytest.py -v 

 

 方法1总结:

继承自unittest.TestCase的测试用例类,定义setUptearDown名字以test开头测试用例方法,测试中主要是调用assertEqualassertRaises等断言方法判断程序执行结果和预期值是否相符。

调用unittest.main()启动测试.

 

2 加载测试套件

好吧,在运用测试套件进行单元测试之前,我想还是稍微研究一下unittest模块的内容有哪些,其大概的运行方式是什么样的。

首先,自然是查看unittest模块有哪些成员啦!

[python] view plaincopy

1. >>import unittest  

2. >>dir(unittest)  

可以看到其自身的成员也不是很多,大概包括有:
['FunctionTestCase', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult',
 'TestSuite','TextTestRunner', '_CmpToKey', '_TextTestResult', '_WritelnDecorator',
 'defaultTestLoader','findTestCases', 'getTestCaseNames', 'main','makeSuite']
 
 好吧,我们大概看看具体都是干什么的

[python] view plaincopy

1. >>memblist = ['FunctionTestCase''TestCase''TestLoader''TestProgram''TestResult',\  

2. 'TestSuite','TextTestRunner''defaultTestLoader','findTestCases''getTestCaseNames', \  

3. 'main''makeSuite']  

4. >>for memb in memblist:  

5. ..  cur = getattr(unittest, memb)  

6. ..  print help(cur)  

'FunctionTestCase':函数测试用例,即给一个函数作为参数,返回一个testcase实例,可选参数有set-up,tear-down方法
 'TestCase':所有测试用例的基本类,给一个测试方法的名字,返回一个测试用例实例
 'TestLoader':测试用例加载器,其包括多个加载测试用例的方法。返回一个测试套件
 loadTestsFromModule(self, module)--根据给定的模块实例来获取测试用例套件
 loadTestsFromName(self, name, module=None)
 --根据给定的字符串来获取测试用例套件,字符串可以是模块名,测试类名,测试类中的测试方法名,或者一个可调用的是实例对象
 这个实例对象返回一个测试用例或一个测试套件
 loadTestsFromNames(self, names, module=None) --和上面功能相同,只不过接受的是字符串列表
 loadTestsFromTestCase(self, testCaseClass)--根据给定的测试类,获取其中的所有测试方法,并返回一个测试套件
'TestProgram':命令行进行单元测试的调用方法,作用是执行一个测试用例。其实unittest.main()方法执行的就是这个命令,
而这个类实例时默认加载当前执行的作为测试对象,
原型为 __init__(self,module='__main__', defaultTest=None, argv=None, testRunner=xx, testLoader=xx)
其中module='__main__'就是默认加载自身
'TestResult':测试用例的结果保存实例,通常有测试框架调用
 'TestSuite':组织测试用例的实例,支持测试用例的添加和删除,最终将传递给testRunner进行测试执行
 'TextTestRunner':进行测试用例执行的实例,其中Text的意思是以文本形式显示测试结果。显示测试名称,即完成的测试结果,其过同执行单元测试脚本时添加-v参数
 'defaultTestLoader':其实就是TestLoader
 'findTestCases', 'getTestCaseNames':这个2个就不用解释了
 'main': 其实就是TestProgram
 'makeSuite':通常是由单元测试框架调用的,用于生产testsuite对象的实例
 
至此,我们知道了其实整个单元测试框架的逻辑。分三步:

第一步testloader根据传入的参数(名字,类,模块等)获得相应的测试用例,即对应具体的测试方法,(默认也会生成);
然后makesuite在把所有测试用例组装成testsuite中,

最后把testsiute传给testrunner执行。


而我们通常执行的unittest.main(),其实就是unittest.testprom方法,其执行的功能就是上面分析的三步:

在第一步中其传入的参数是自身的模块__main__;
在第二步中把自身模块中的所有测试类中中的测试方法提取出来,并生成测试套件;

最后再把测试套件传递给testrunner进行具体的测试。
 
最后给出一个完整的单元测试组织代码,把该代码放到单元测试用例文件的同一个目录后执行该脚本,即可执行所有的测试用例文件。
 【测试用例文件必须为test开头,如:testxxx.py, 当然这个文件本身是一个单元测试的文件】

 

[python] view plaincopy

1. #!/usr/bin/env python  

2.  

3. # test for class functions  

4. suit =unittest.TestLoader().loadTestFromTestCase(class_name)

5. unittest.TextTestRunner(verbosity=2).run(suit)

6.  

7. # test for differentclass  

8. suit1 =unittest.TestLoader().loadTestFromTestCase(class_name1)

9. suit2 =unittest.TestLoader().loadTestFromTestCase(class_name2)

10.allTest = unittest.testSuit([suit1, suit2])

11.  

12.  

复杂的一个例子:

 

[python] view plaincopy

13.  

14.def testAllinCurrent():  

15.    path = os.path.abspath(os.path.dirname(sys.argv[0]))     

16.    files = os.listdir(path)                                 

17.    test = re.compile("test\.py{1}quot;, re.IGNORECASE)            

18.    files = filter(test.search, files)                       

19.    filenameToModuleName = lambda f: os.path.splitext(f)[0]  

20.    moduleNames = map(filenameToModuleName, files)           

21.    modules = map(__import__, moduleNames)     

22.                    

23.    load = unittest.defaultTestLoader.loadTestsFromModule    

24.    return unittest.TestSuite(map(load, modules))  

25.  

26.if __name__ == "__main__":                     

27.    unittest.main(defaultTest="regressionTest")  

 

 

 

 参考:

http://blog.csdn.net/five3/article/details/7104466

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值