千家信息网

python单元测试中unittest是怎样的

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,python单元测试中unittest是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。单元测试作为任何语言的开发者
千家信息网最后更新 2024年09月22日python单元测试中unittest是怎样的

python单元测试中unittest是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

单元测试作为任何语言的开发者都应该是必要的,因为时隔数月后再回来调试自己的复杂程序时,其实也是很崩溃的事情。虽然会很快熟悉内容,但是修改和调试将是一件痛苦的事情,如果你在修改了代码后出现问题的话,而单元测试可以帮助我们很快准确的定位到问题的位置,出现问题的模块和单元。所以这是一件很愉快的事情,因为我们知道其它修改或没有修改的地方仍然是正常工作的,而我们目前的唯一问题就是搞定眼前这个有点问题的"家伙"。所以工作会在轻松中开始,并且很快将会结束,因为你已经知道很多信息了。

单元测试自然是对程序中最小的可测试模块--函数来进行测试;因为单元测试的对象是函数,也就是说你得被测试对象一定要有输出结果,哪怕就是异常输出,也得有输出,以便单元测试模块能够捕获返回值,并且与预期值进行比较,从而得出测试通过与否。

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

1.1 测试模块中的函数:

被测模块:

[python] view
plaincopy

  1. #!/usr/bin/env python

  2. #encoding: utf-8


  3. def sum( x, y):

  4. return x+y



  5. def sub( x, y):

  6. return x-y

单元测试模块:

[python] view
plaincopy

  1. #!/usr/bin/env python

  2. #encoding: utf-8


  3. import unittest

  4. import myclass


  5. class mytest(unittest.TestCase):


  6. ##初始化工作

  7. def setUp(self):

  8. pass


  9. #退出清理工作

  10. def tearDown(self):

  11. pass


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

  13. def testsum(self):

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



  15. def testsub(self):

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



  17. if __name__ =='__main__':

  18. unittest.main()

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

[python] view
plaincopy

  1. .F

  2. ======================================================================

  3. FAIL: testsum (__main__.mytest)

  4. ----------------------------------------------------------------------

  5. Traceback (most recent call last):

  6. File "C:\Users\xiaowu\workspace\mypython\unitTest.py", line 19, in testsum

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

  8. AssertionError: test sum fail


  9. ----------------------------------------------------------------------

  10. Ran 2 tests in 0.001s


  11. FAILED (failures=1)

1.2 测试模块类中的函数:

被测模块:

[python] view
plaincopy

  1. #!/usr/bin/env python

  2. #encoding: utf-8


  3. class myclass:

  4. def __init__(self):

  5. pass



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

  7. return x+y



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

  9. return x-y

单元测试模块:

[python] view
plaincopy

  1. #!/usr/bin/env python

  2. #encoding: utf-8


  3. import unittest

  4. import myclass


  5. class mytest(unittest.TestCase):


  6. ##初始化工作

  7. def setUp(self):

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


  9. #退出清理工作

  10. def tearDown(self):

  11. pass


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

  13. def testsum(self):

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



  15. if __name__ =='__main__':

  16. unittest.main()

运行结果:

[python] view
plaincopy

  1. .

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

  3. Ran 1 test in 0.000s


  4. OK

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

2 加载测试套件

好吧,在运用测试套件进行单元测试之前,我想还是稍微研究一下unittest模块的内容有哪些,其大概的运行方式是什么样的。而后在给出根据各种情况如何制定单元测试套件。

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

[python] view
plaincopy

  1. >>import unittest

  2. >>dir(unittest)

  3. ['FunctionTestCase', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'Tes

  4. tSuite', 'TextTestRunner', '_CmpToKey', '_TextTestResult', '_WritelnDecorator',

  5. '__all__', '__author__', '__builtins__', '__doc__', '__email__', '__file__', '__

  6. metaclass__', '__name__', '__package__', '__unittest', '__version__', '_makeLoad

  7. er', '_strclass', 'defaultTestLoader', 'findTestCases', 'getTestCaseNames', 'mai

  8. n', 'makeSuite', 'os', 'sys', 'time', 'traceback', 'types']

可以看到其自身的成员也不是很多,大概包括有:
['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. #encoding: utf-8

  3. #该代码源自深入python

  4. import unittest

  5. import myclass

  6. import re

  7. import os

  8. import sys



  9. def testAllinCurrent():

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

  11. files = os.listdir(path)

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

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

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

  15. moduleNames = map(filenameToModuleName, files)

  16. modules = map(__import__, moduleNames)


  17. load = unittest.defaultTestLoader.loadTestsFromModule

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


  19. if __name__ == "__main__":

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

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

测试 单元 模块 实例 方法 套件 就是 对象 结果 函数 参数 文件 问题 代码 工作 事情 内容 字符 字符串 开头 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 南陵网络技术及信息安全工程师 不同服务器的人可以在一起玩吗 access表格数据库 分布式缓存放什么数据库 晨曦软件开发 查询语句插入其他数据库表 嘉讯软件开发 手机经常无法连接到服务器 租用的服务器能退钱吗 我的世界服务器如何用命令换皮肤 浅谈网络技术在铁道通信的应用 信息网络安全监察专业考公务员 steam加速用什么服务器 关于网络技术的工作领域 关系型数据库适用场景 六狐网络技术有限公司 智能家居软件开发oem 江苏特种网络技术分类服务标准 数据库怎么查询某架构下的表 学c软件开发 软件开发是干什么用的 注册一个手机服务器 石家庄软件开发公司有实力 浪潮5266m5服务器导轨 网络安全处罚法案例 服务器下载和客户端下载 逆水寒一个服务器上限多少人 明朝思维导图软件开发 fol服务器都有几部分组成 怎样在国泰安数据库剔除公司
0