Python3 unittest单元测试

本文介绍了Python3中的unittest模块,用于进行单元测试。内容涵盖了unittest的基本方法,setUp和tearDown的使用,参数化测试,参数化文件的处理,关联接口的处理,以及批量读取python文件获取所有测试用例的方法,旨在帮助读者掌握unittest单元测试的实践技巧。
摘要由CSDN通过智能技术生成

单元测试老生常谈了,但是测试要会单元测试还是近几年在国内流行起来的,测试开发岗位那是必备技能了,所以这个单元测试还是要接触下,就算以后的岗位中用不上,但万一面试时问到单元测试,也不至于太狼狈,或者学到这个技能不是不可以往测试开发岗位发展下。我们看下python怎么实现单元测试。

  python的优点想必大家已经很了解了,现在想到要单元测试,那么肯定有牛人已经探好路子,并研发了这个模块,我们用就好了,没错,就是unittest模块:

  TestCase 测试用例,就是功能里那样一条条用例

  TestSuite 多个测试用例集合在一起,就是TestSuite,就是一个功能模块的所有用例放这里了

  TestLoader是用来加载TestCase到TestSuite中的,这个方法很好玩,可以将一个目录下的所有python文件里的测试用例抠出来

  TestRunner是来执行测试用例的,测试的结果会保存到TestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息

  1.unittest测试的基本方法

复制代码
复制代码
 1 import unittest #导入unittest模块
 2 import HTMLTestRunner,xmlrunner #导入生成报告的模块,html生成的是方便给自己看的,xml生成的报告是以后给jekens用的,能自动识别测试报告内容。
 3 class MyTest(unittest.TestCase):    #定义一个测试用例的类
 4     def testa(self):    #定义一个测试用例,注意,测试用例必须test开始,不然不会当做是测试用例
 5         '''a''' #描述,会同测试用例标题一并显示在测试报告里
 6         self.assertEqual(1,1)   #测试用例断言,比较预期结果与实际结果,这里1==1,显然结果是pass
 7     def testhaha(self):
 8         '''b'''
 9         self.assertEqual(2, 1)  #测试用例断言,比较预期结果与实际结果,这里2==1,显然结果是Fail
10     def testb(self):
11         '''c'''
12         self.assertEqual(3, 2)  #测试用例断言,比较预期结果与实际结果,这里3==1,显然结果是Fail
13 
14 class MyTest2(unittest.TestCase):
15     def testc(self):
16         '''d'''
17         self.assertEqual(1,1)
18     def testhaha(self):
19         '''e'''
20         self.assertEqual(2, 1)
21     def testd(self):
22         '''f'''
23         self.assertEqual(3, 2)
24 
25 if __name__=='__main__':
26     # unittest.main()   #运行所有的测试用例,运行下面的代码时这个要注释
27     suite=unittest.TestSuite()  #定义一个测试套件
28     # suite.addTest(MyTest('testa'))    #添加测试用例方法一:往测试套件里新增一条测试用例,测试用例只能用一种方法,同时两种会报错
29     # suite.addTest(MyTest('testb'))
30     suite.addTest(unittest.makeSuite(MyTest))   #添加测试用例方法二:往测试套件里新增这个类下的所有测试用例
31     suite.addTest(unittest.makeSuite(MyTest2))
32     # fw=open('test.html','wb') #定义一个文件对象,给后面的HTMLTestRunner生成测试报告用,注意打开方式必须是wb
33     # runner=HTMLTestRunner.HTMLTestRunner(stream=fw,title='Testing',description='miaoshu') #生成测试报告方法一:HTMLTestRunner,需要指定文件对象和标题
34     runner=xmlrunner.XMLTestRunner(output='.') #生成测试报告方法二:xmlrunner,这个方法只要指定测试报告目录就可以
35     runner.run(suite)   #运行,注意上述方法我写一起了,运行的话只能运行一种,另一个要注释
复制代码
复制代码

 

  2.unittest中的setUp和tearDown的应用

复制代码
复制代码
 1 #setUp和tearDown的运用
 2 import unittest
 3 class MyTest(unittest.TestCase):
 4     @classmethod
 5     def setUpClass(cls):  #类开始前运行,比如在执行这些用例之前需要备份数据库
 6         print('1')
 7 
 8     @classmethod
 9     def tearDownClass(cls):   #类结束后运行,比如在执行这些用例之后需要还原数据库
10         print('0')
11     def setUp(self):  #测试用例执行前运行
12         print('a')
13     def tearDown(self):   #测试用例执行后运行
14         print('z')
15     def testa(self):
16         print('测试用例1')
17         self.assertEqual(1,1)
18     def testb(self):
19         print('测试用例2')
20         self.assertEqual(1,1)
21 if __name__=='__main__':
22     unittest.main()
复制代码
复制代码

 

  3.unittest中的参数化

  参数化的概念不陌生了,一种是需要大量数据还有一种是有唯一性校验的情况都需要参数化,那么在unittest中怎么参数化呢?如下:

复制代码
复制代码
 1 import unittest,HTMLTestRunner
 2 from nose_parameterized import parameterized
 3 def login(username,passwd):
 4     if username=='xiaogang' and passwd=='123456':
 5         return True
 6     else:
 7         return False
 8 
 9 class Login(unittest.TestCase):
10     @parameterized.expand(
11         [
12             ['xiaogang','123456',True], #可以是list,也可以是元祖
13             ['','123456',True],
14             ['xiaogang','',False],
15             ['adgadg','123456',False]
16         ]
17     )
18     def test_login(self,username,passwd,exception): #这里的参数对应上述列表里的元素,运行的时候会遍历上述列表里的二维列表直到所有元素都调用运行完成
19         '''登录'''
20         res=login(username,passwd)
21         self.assertEqual(res,exception)
22 
23 if __name__=='_main__':
24     suite = unittest.TestSuite()
25     suite.addTest(unittest.makeSuite(Login))
26     fw = open('a.html', 'wb')
27     runner = HTMLTestRunner.HTMLTestRunner(
28         stream=fw, title='参数化测试数据', description='描述'
29     )
30     runner.run(suite)
复制代码
复制代码

  

  4.unittest参数化文件

  上面的参数化要自己手写一个二维数组,但是要做一个测试框架,显然不应该这样low,用框架的人直接维护问文档就好了啊,其实比较简单,代码如下:

复制代码
复制代码
 1 #用文件作为参数进行unittest单元测试
 2 import unittest,HTMLTestRunner
 3 from nose_parameterized import parameterized
 4 def redCvs(filename,sep=','):
 5     lis=[]
 6     with open(filename,'rb') as f:  #rb模式,在任何操作系统下打开都不会报错,考虑到系统兼容性
 7         for line in f:
 8             lis1=line.decode().strip().split(',')   #decode是因为上面用了rb模式打开,是bytes类型,需要解码
 9             lis.append(lis1)
10     return(lis)
11 
12 def login(username,passwd):
13     if username=='xiaogang' and passwd=='123456':
14         return True
15     return False
16 
17 class Login(unittest.TestCase):
18     @parameterized.expand(redCvs('a.txt'))
19     def testa(self,username,passwd,exception):
20         res=login(username,passwd)
21         self.assertEqual(bool(exception),res)
22 
23 if __name__=='__main__':
24     suite=unittest.TestSuite()
25     suite.addTest(unittest.makeSuite(Login))
26     fw=open('test.html','wb')
27     runner=HTMLTestRunner.HTMLTestRunner(
28         stream=fw,title='test测试',description='嘿嘿'
29     )
30     runner.run(suite)
复制代码
复制代码

 

  5.unittest处理关联接口

  基本不存在单独的接口,一般都是依赖接口,比如购买商品,依赖登录接口返回的token或者session,这些都是变化的,那怎么在unittest里实现呢?代码如下:

复制代码
复制代码
 1 #接口关联,只是一个思路,并没有结合实际的项目,有兴趣的同学可以尝试下
 2 import unittest,HTMLTestRunner
 3 def login(username,passwd):
 4     if username=='xiaogang' and passwd=='123456':
 5         return '138'
 6     else:
 7         return False
 8 
 9 def shopping(sign):
10     if sign=='138':
11         return True
12     else:
13         return False
14 
15 class My(unittest.TestCase):
16     def login(self):    #注意,这里不以test开头命名,就是一普通方法,在执行测试用例的时候并不会运行,调用的时候才会
17         res=login('xiaogang','123456')
18         self.assertEqual(res,'138')
19         return res
20 
21     def test_login_cj(self):
22         res=self.login()    #调用登录方法,获取sign
23         self.jp=shopping(res)
24         self.assertEqual(self.jp,True)
25         
26 suite=unittest.TestSuite()
27 suite.addTest(unittest.makeSuite(My))
28 fw=open('res.html','wb')
29 runner=HTMLTestRunner.HTMLTestRunner(
30     stream=fw,title='关联接口',description='描述'
31 )
32 # runner=xmlrunner.XMLTestRunner(output='.')
33 runner.run(suite)
复制代码
复制代码

 

 

  6.unittest批量读取python文件获取所有测试用例

  每个python文件里放不同的功能测试用例,方便维护,那么怎么把他们一次性运行完呢,这里就用到了unittest里的 defaultTestLoader.discover方法了,用法如下:

复制代码
复制代码
import unittest,HTMLTestRunner
suite = unittest.TestSuite()#定义测试集合
all_case = unittest.defaultTestLoader.discover(
    r'E:\szg\bestTest\day11\AUTO\case','test_*.py'
)#找到case目录下所以的.py文件

for case in all_case:
    #循环添加case到测试集合里面
    suite.addTests(case)

fw = open('report.html','wb')
runner = HTMLTestRunner.HTMLTestRunner(
    stream=fw,title='多个文件运行'
)
runner.run(suite)
复制代码
复制代码
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.将 HTMLTestRunner.py 放置在 C:\Python36\Lib 下 2.涉及到创建目录和时间,需要在脚本开头 import os import time 3.执行脚本中删除语句 unittest.main() ,一般在脚本最后,然后添加如下语句: #导入HTMLTestRunner库,这句也可以放在脚本开头 from HTMLTestRunner import HTMLTestRunner #定义脚本标题,加u为了防止中文乱码 report_title = u'登陆模块测试报告' #定义脚本内容,加u为了防止中文乱码 desc = u'手机JPG登陆模块测试报告详情:' #定义date为日期,time为时间 date=time.strftime("%Y%m%d") time=time.strftime("%Y%m%d%H%M%S") #定义path为文件路径,目录级别,可根据实际情况自定义修改 path= 'D:/Python_test/'+ date +"/login/"+time+"/" #定义报告文件路径和名字,路径为前面定义的path,名字为report(可自定义),格式为.html report_path = path+"report.html" #判断是否定义的路径目录存在,不能存在则创建 if not os.path.exists(path): os.makedirs(path) else: pass #定义一个测试容器 testsuite = unittest.TestSuite() #将测试用例添加到容器 testsuite.addTest(测试类名("测试方法名1")) testsuite.addTest(测试类名("测试方法名2")) #将运行结果保存到report,名字为定义的路径和文件名,运行脚本 with open(report_path, 'wb') as report: runner = HTMLTestRunner(stream=report, title=report_title, description=desc) runner.run(testsuite) #关闭report,脚本结束 report.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值