• 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.pyloadTestsFromTestCase方法里边,调用了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()方法中关闭数据库,这样,不必在每个测试方法中重复相同的代码。

  • 相关阅读:
    ubuntu下无法在目录下创建文件夹,权限不足解决办法
    mongo中的模糊查询
    mysql中的模糊查询
    mysql安装与配置详情
    Django model中的class Meta详解
    kafka集群搭建
    myeclipse/eclipse添加Spket插件实现ExtJs4.2/ExtJs3智能提示
    博客园自定义标题、阅读目录、导航栏、活动的推荐&反对按钮
    IntelliJ IDEA 14 创建maven项目二
    EXT4.2--Ext Designer 使用
  • 原文地址:https://www.cnblogs.com/du-hong/p/10755530.html
Copyright © 2020-2023  润新知