美文网首页
unittest测试框架

unittest测试框架

作者: 波妞和宗介 | 来源:发表于2022-03-20 11:33 被阅读0次

    一、使用规则

    import unitest //在python2.1 之后都是直接作为标准模块放在了开发包中
    创建一个测试类必须要继承unitest.TestCase的基类
    测试方法(即测试用例名称)必须要以test开头,否则该用例不会被unitest识别到
    

    二、重要概念

    Test Case:最小的测试单元,即测试方法。
    Test Suite:测试用例、测试套件或两者的集合,用于组装一组要运行的测试。使用TestSuite类来创建测试套件。
    Test Runner:Test Runner是一个组件,用于协调测试的执行并向用户提供结果。
    unittest提供了TextTestRunner类运行测试用例。
    

    三、用例执行

    1、执行顺序

    unittest默认按照ASCII码的顺序加载测试用例(包括测试目录和测试文件、测试类、测试方法),
    即它并不是按照测试用例的创建顺序从上到下执行的
    
    unittest.main()  //通过main()方法来执行测试用例;
    //按照测试类、方法的名称ASCII值大小的顺序执行用例
    

    2、如何控制用例的执行顺序

    方法一:通过testSuite类中的addTest()方法来加载用例

    这里就是按照添加的顺序来执行了,不会按照ASCII码的顺序来加载用例
    弊端:如果想要执行的用例非常将会添加很多,照成代码冗余

    suit = unittest.TestSuite()
    suit.addTest(cluster_op("test11_delete_cluster"))  
    # 把这个类中需要执行的测试用例加进去,有多条再加即可
    unittest.TextTestRunner().run(suit) #运行测试用例
    
    方法二:通过discover方法执行多个用例
    unitest.defaultTestLoader.discaover()方法可从文件中或者目录中查找多个符合规则的测试用例
    discover(start_dir, pattern='Test*.py', top_level_dir=None)
    ------------
      start_dir:待测试的模块名/测试用例目录;
      discover()方法会自动根据这个参数查找测试用例文件
      pattern:测试用例文件名的匹配原则
      top_level_dir:测试模块的顶级目录,如果没有顶级目录,默认为None
    ------------
    
    
    • 示例代码
    test_dir = 'D:\下载文件\qf-api-master\\test_suite'
    suits = unittest.defaultTestLoader.discover(test_dir, pattern='api001*.py')
    if __name__ == '__main__':
        runner = unittest.TextTestRunner()
        runner.run(suits)
    

    踩坑:如果想让discover()查找子目录下的测试文件,得将子目录标记为一个python模块(子目录下放__init__.py文件)
    备注:发现了可以批量加载用例的方法testLoader()具体怎么用自己还没有实际用过,后续会详细介绍。可参考官方文档:https://docs.python.org/3.9/library/unittest.html?highlight=defaulttestloader#unittest.defaultTestLoader

    四、执行结果

    “.” 表示测试用例执行通过
    “F”表示执行失败
    “E” 表示执行错误
    "s“表示运行跳过

    五、用例跳过

    • unitest用例跳过一般用skip(),下面是具体的介绍和使用
    • 示例代码
    import unittest
    
    
    class Testaaa(unittest.TestCase):
        @unittest.skip(reason="no reason")  # 无理由的强制跳转,reason为原因
        def test_001(self):
            print("这是第一个测试用例")
    
        @unittest.skipIf(6 > 1, reason="如果6大于1")  # condition为true 的时候进行跳转
        def test_002(self):
            print("这是第二个测试用例")
    
        @unittest.skipUnless(6 == 1, reason="如果6==1=false ,则跳过")  # condition为false 的时候进行跳过
        def test_003(self):
            print("这是第三个测试用例")
    
        @unittest.expectedFailure  # 如果该测试用例执行失败,不统计到失败用例的条目中
        def test_004(self):
            assert 1 == 1
            print("这是第四个测试用例")
            
    
    if __name__ == '__main__':
        unittest.main()
    
    
    • 运行结果
      运行结果.png
      关于expectedFailure的用法感觉一直很别扭,这里贴上一张官方的解释。不过,在实际的项目中几乎没有用到这个。
      expectedFailure用法官方解释.png

    六、setUp&tearDown

    • setUp:每条用例执行前先执行
    • tearDown:每条用例执行后会执行
    • setUpClass: 每个类执行用例前先执行(一般用来初始化一些数据数据,使用时要加装饰器@classmethod)
    • tearDownClass: 类中的所有用例执行完成后执行一次(一般用来销毁环境,使用时要加装饰器@classmethod)

    七、用例参数化

    • parametrize
      • 在项目中是将测试用例数据写在yaml中,然后通过parametrize来调用这些测试数据


        yaml文件部分示例.png
    • 代码示例:
    case_name = load_yaml().get("cluster_op")
    @parameterized.expand(case_name.get('test_01_create_cluster'))
    //注意:在引用时注意yaml 文件中的测试数据要和测试函数中的传参一一对应
    
    • ddt
      • 没有实际用过,用过了在来补充

    八、测试报告

    • BeautifulReport
    def all_case():
        discover = unittest.defaultTestLoader.discover(case_path, pattern="api00*.py", top_level_dir=None)
        print(discover)
        return discover
    if __name__ == "__main__":
        allc = all_case()
        desc = "xxxx自动化测试报告"
        result = BeautifulReport(allc)
        result.report(filename="xxxx自动化测试报告", description=desc, 
                      report_dir=os.path.join(os.getcwd(), "out"), log_path=os.path.join(os.getcwd(), "log"))
    

    相关文章

      网友评论

          本文标题:unittest测试框架

          本文链接:https://www.haomeiwen.com/subject/mvvodrtx.html