python接口自动化(二十二)--unittest执行顺序隐藏的坑(详解)
简介
大多数的初学者在使用 unittest 框架时候,不清楚用例的执行顺序到底是怎样的。对测试类里面的类和方法分不清楚,不知道什么时候执行,什么时候不执行。虽然或许通过代码实现了,也是稀里糊涂的一知半解,这样还好,好歹自己鼓
捣出了,但是时间和效率并不是很高,下次遇到还是老样子。那么本篇通过最简单案例来给给为小伙伴详细讲解、演示一下 unittest 执行顺序。
实例代码
参考代码
1 # coding=utf-8 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 #2.注释:包括记录创建时间,创建人,项目名称。 5 ''' 6 Created on 2019-4-23 7 @author: 北京-宏哥 8 Project:学习和使用unittest框架编写测试用例执行顺序 9 ''' 10 #3.导入unittest模块 11 import unittest 12 #4.执行顺序和运行测试 13 import unittest 14 15 class TestLogin(unittest.TestCase): 16 17 def test_login_blog(self): 18 """登录博客园 19 20 :return: 21 """ 22 23 def test_add_essay(self): 24 """ 添加随笔 25 26 :return: 27 """ 28 29 def test_release_essay(self): 30 """ 发布随笔 31 32 :return: 33 """ 34 35 def test_quit_blog(self): 36 """退出博客园 37 38 :return: 39 """ 40 if __name__ == "__main__()": 41 unittest.main()
这是一个标准的使用unittest进行测试的例子,写完后心里美滋滋,嗯,就按照一贯思路代码会按照这个顺序测就可以了。结果一运行。就傻眼了
这时候自己心里犯嘀咕,这是什么鬼,怎么回事呢。执行的顺序乱了。第一个执行的测试用例并不是登录博客园,而是添加随笔,此时用户还没登录博客园,进行添加随笔的话会直接报错,导致用例失败。
到这里有些小伙伴可能会说,为什么要让测试用例之间有所依赖呢?
的确,如果完全没依赖,测试用例的执行顺序是不需要关注的。但是这样对于用例的设计和实现,要求就高了许多。而对博客园来说,一个系统内的操作,是有很大的关联性的。以添加随笔为例,随笔内的每个操作都有一个前提,你需要
登录博客园才能添加随笔。所以要实现用例之间的完全解耦,需要每个用例开始之前,检测用户的登录状态。
如果可以控制测试用例的执行顺序,按照功能流程一遍走下来,节省的代码量是非常可观的,阅读测试用例也会清晰明了许多。
如何控制unittest用例执行的顺序呢?
1、带大家先看看源码,unittest是怎么样对用例进行排序的。在loader.py
的loadTestsFromTestCase
方法里边,调用了getTestCaseNames
方法来获取测试用例的名称
2、从源码可以清楚地看到,getTestCaseNames
方法对测试用例的名称进行了排序
3、一步一步跟进去,查看其排序方法
4、根据排序规则,unittest执行测试用例,默认是根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。
5、做个小demo,看看是不是我们所说的那种排序规则
6、从上边的运行结果,我们可以看出是:unittest执行测试用例,默认是根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。
7、基于unittest的机制,如何控制用例执行顺序呢?查了一些网上的资料,主要介绍了两种方式:
方式1,通过TestSuite类的addTest方法,按顺序加载测试用例
参考代码
1 # coding=utf-8 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 #2.注释:包括记录创建时间,创建人,项目名称。 5 ''' 6 Created on 2019-4-23 7 @author: 北京-宏哥 8 Project:学习和使用unittest框架编写测试用例执行顺序 9 ''' 10 #3.导入unittest模块 11 import unittest 12 #4.执行顺序和运行测试 13 import unittest 14 15 class TestLogin(unittest.TestCase): 16 17 def setUp(self): 18 pass 19 def test_login_blog(self): 20 """登录博客园 21 22 :return: 23 """ 24 print("登录博客园") 25 def test_add_essay(self): 26 """ 添加随笔 27 28 :return: 29 """ 30 print("添加随笔") 31 def test_release_essay(self): 32 """ 发布随笔 33 34 :return: 35 """ 36 print("发布随笔") 37 def test_quit_blog(self): 38 """退出博客园 39 40 :return: 41 """ 42 print("退出博客园") 43 44 def tearDown(self): 45 pass 46 if __name__ == '__main__': 47 # 启动单元测试 48 # unittest.main() 49 50 # 获取TestSuite的实例对象 51 suite = unittest.TestSuite() 52 53 # 将测试用例添加到测试容器中 54 suite.addTest(TestLogin('test_login_blog')) 55 suite.addTest(TestLogin('test_add_essay')) 56 suite.addTest(TestLogin('test_release_essay')) 57 suite.addTest(TestLogin('test_quit_blog')) 58 59 # 创建TextTestRunner类的实例对象 60 runner = unittest.TextTestRunner() 61 runner.run(suite) 62 #unittest.TextTestRunner(verbosity=3).run(suite)
方式2,通过修改函数名的方式
参考代码
1 # coding=utf-8 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 #2.注释:包括记录创建时间,创建人,项目名称。 5 ''' 6 Created on 2019-4-23 7 @author: 北京-宏哥 8 Project:学习和使用unittest框架编写测试用例执行顺序 9 ''' 10 #3.导入unittest模块 11 import unittest 12 #4.执行顺序和运行测试 13 import unittest 14 15 class TestLogin(unittest.TestCase): 16 17 def setUp(self): 18 pass 19 def test_1_login_blog(self): 20 """登录博客园 21 22 :return: 23 """ 24 print("登录博客园") 25 def test_2_add_essay(self): 26 """ 添加随笔 27 28 :return: 29 """ 30 print("添加随笔") 31 def test_3_release_essay(self): 32 """ 发布随笔 33 34 :return: 35 """ 36 print("发布随笔") 37 def test_4_quit_blog(self): 38 """退出博客园 39 40 :return: 41 """ 42 print("退出博客园") 43 44 def tearDown(self): 45 pass 46 if __name__ == '__main__': 47 # 启动单元测试 48 unittest.main()
拓展练习
1、实例
2、运行结果
3、运行结果分析
1、从运行结果可以看出执行顺序:
start!-执行测试用例 01-end!
start!-执行测试用例 02-end!
start!-执行测试用例 03-end!
2、从执行结果可以看出几点
--先执行的前置 setUp,然后执行的用例(test*),最后执行的后置 tearDown
--测试用例(test*)的执行顺序是根据 01-02-03 执行的,也就是说根据用例名称来顺序执行的
--addtest(self)这个方法没执行,说明只执行 test 开头的用例
参考代码
1 # coding=utf-8 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 #2.注释:包括记录创建时间,创建人,项目名称。 5 ''' 6 Created on 2019-4-23 7 @author: 北京-宏哥 8 Project:学习和使用unittest框架编写测试用例思路 9 ''' 10 #3.导入unittest模块 11 import unittest 12 13 #4.执行顺序和运行测试 14 import time 15 class Test(unittest.TestCase): 16 def setUp(self): 17 print ("start!") 18 def tearDown(self): 19 time.sleep(1) 20 print ("end!") 21 def test01(self): 22 print ("执行测试用例 01") 23 def test03(self): 24 print ("执行测试用例 03") 25 def test02(self): 26 print ("执行测试用例 02") 27 def addtest(self): 28 print ("add 方法") 29 if __name__ == "__main__": 30 unittest.main()
小结
1、这个执行顺序,看似简单,实则不简单,只有掌握最简单的才可以应付最复杂的。
2、setUp()
和tearDown()
方法有什么用呢?设想你的测试需要启动一个数据库,这时,就可以在setUp()
方法中连接数据库,在tearDown()
方法中关闭数据库,这样,不必在每个测试方法中重复相同的代码。
感谢您花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让博主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下左下角“推荐”按钮,您的
本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/du-hong 欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利!
公众号(关注宏哥)                                                                                 客服微信
![个人微信公众号](https://img2018.cnblogs.com/common/1741949/201911/1741949-20191119095948011-608816619.png)
![个人微信](https://img2018.cnblogs.com/common/1741949/201911/1741949-20191106101257091-849954564.png)