zoukankan      html  css  js  c++  java
  • unittest中setUp与tearDown

    在unittest中用例执行的先后顺序是根据数字、字母的先后顺序来判定的,如果要按照预定的顺序执行方法如下:

    1.用字母、数字先后顺序排序(缺点:用例名称会不够美观、杂乱无章)

    2.用testsuite控制用例加载顺序(缺点:当case较多时,逐个添加非常麻烦)

    每次执行用例时,unittest.TestCase的类下每个test开头的方法(就是用例)时,都会执行setUp和tearDown

    如下:

    import unittest
     
    class TestSetupTeardown(unittest.TestCase):
        def setUp(self):
            print('连接数据库成功...')
        def tearDown(self):
            print('关闭数据库。')
        def test_a(self):
            print('test_a')
        def test_b(self):
            print('test_b')
     
    if __name__ == '__main__':
        unittest.main()

    执行效果如下:

    setUp连接数据库,tearDown关闭数据库,这样反复执行,无疑是会增加数据库服务器资源的损耗,且浪费时间

    而且下一个用例的执行需要依赖上一个用例的执行结果时,应该怎么办?

    1.在需要依赖的case中,将上一个case单独拎出来做一个公用的方法。然后在进入这个case时先调用该方法。例如caseB需要caseA返回的结果,那么我先将caseA封装成一个通用的方法,根据传入的参数不同返回不同的值。然后在caseB中获取返回的值,作为caseB开始前的另一种变相的 ‘setup’。代码如下:

    import unittest
    
    def set_A(a, b):
        a = a*2
        b = b*2
        return (a, b)
    
    class Test_setup_and_teardwon(unittest.TestCase):
    
        def setUp(self):
            self.a = 2 
            self.b = 3
            print('set up over :')
            print('a = %s, b = %s 
    '%(self.a, self.b))
    
        def tearDown(self):
            a = 0
            b = 0
            print('tear down over :')
            print('a = %s, b = %s'%(a, b))
            print('__________________________________________________________')
    
        def test_case_B(self):
            (a, b) = set_A(self.a, self.b)
            a = a*2
            b = b*2
            print('run B over :')
            print('a= %s, b = %s 
    '%(a, b))
    
        def test_case_A(self):
            a = self.a*2
            b = self.b*2
            print('run A over :')
            print('a = %s, a = %s 
    '%(a, b))
    
        def test_case_C(self):
            a = self.a*4
            b = self.b*4
            print('run C over :')
            print('a = %s, a = %s 
    '%(a, b))
    
    if __name__ == '__main__':
        suite = unittest.TestSuite()
        suite.addTest(Test_setup_and_teardwon("test_case_A"))
        suite.addTest(Test_setup_and_teardwon("test_case_B"))
        suite.addTest(Test_setup_and_teardwon("test_case_C"))
        runner = unittest.TextTestRunner()
        runner.run(suite)

    执行结果:

    set up over :
    .a = 2, b = 3 
    
    run A over :
    a = 4, a = 6 
    
    tear down over :
    a = 0, b = 0
    __________________________________________________________
    set up over :
    a = 2, b = 3 
    
    run B over :
    a= 8, b = 12 
    
    tear down over :
    .a = 0, b = 0
    __________________________________________________________
    set up over :
    a = 2, b = 3 
    
    run C over :
    .a = 8, a = 12 
    
    tear down over :
    a = 0, b = 0
    __________________________________________________________
    
    ----------------------------------------------------------------------
    Ran 3 tests in 0.000s
    
    OK
    [Finished in 0.1s]

    但是在测试用例难以解耦的情况下,每写下一个用例就要封装上一个用例的方法,这会导致代码长度翻倍增长。

    因此在此处对于用例之间依赖性较强的模块,控制setUp和tearDown方法只执行一次很有必要

    【解决方案】:

    将setup()  和teardown() 换成setUpClass()和tearDownClass()

    【注意事项】:

    setUpClass():必须使用@classmethod 装饰器,  所有case运行之前只运行一次
    tearDownClass():必须使用@classmethod装饰器, 所有case运行完之后只运行一次

    执行效果如下:

    import unittest
     
    class TestSetupTeardown(unittest.TestCase):
        @classmethod
        def setUpClass(cls):
            print('连接数据库成功...')
        @classmethod
        def tearDownClass(cls):
            print('关闭数据库。')
        def test_a(self):
            print('test_a')
        def test_b(self):
            print('test_b')
     
    if __name__ == '__main__':
        unittest.main()

    用例运行级别

    • 模块级(setup_module/teardown_module)开始于模块始末,全局的

    • 函数级(setup_function/teardown_function)只对函数用例生效(不在类中)

    • 类级(setup_class/teardown_class)只在类中前后运行一次(在类中)

    • 方法级(setup_method/teardown_method)开始于方法始末(在类中)

    • 类里面的(setup/teardown)运行在调用方法的前后

    # coding:utf-8
    import pytest
    # 类和方法
     
    def setup_module():
        print("setup_module:整个.py模块只执行一次")
        print("比如:所有用例开始前只打开一次浏览器")
     
    def teardown_module():
        print("teardown_module:整个.py模块只执行一次")
        print("比如:所有用例结束只最后关闭浏览器")
     
    def setup_function():
        print("setup_function:每个用例开始前都会执行")
     
    def teardown_function():
        print("teardown_function:每个用例结束前都会执行")
     
    def test_one():
        print("正在执行----test_one")
        x = "this"
        assert 'h' in x
     
    def test_two():
        print("正在执行----test_two")
        x = "hello"
        assert 'h' in x
     
    class TestCase():
     
        def setup_class(self):
            print("setup_class:类中所有用例执行之前")
     
        def teardown_class(self):
            print("teardown_class:类中所有用例执行之后")
     
        def setup(self):
            print("setup:类中每个用例执行之前")
        def teardown(self):
            print("teardown:类中每个用例执行之后")
        def setup_method(self):
            print("setup_method:类中每个用例执行之前")
        def teardown_method(self):
            print("teardown_method:类中每个用例执行之后")
     
        def test_three(self):
            print("正在执行----test_three")
            x = "this"
            assert 'h' in x
     
        def test_four(self):
            print("正在执行----test_four")
            x = "hello"
            assert  'h' in x
     
    if __name__ == "__main__":
      pytest.main(["-s", "Testcase2.py"])

    运行结果:

    Testcase2.py setup_module:整个.py模块只执行一次
    比如:所有用例开始前只打开一次浏览器
    setup_function:每个用例开始前都会执行
    .正在执行----test_one
    teardown_function:每个用例结束前都会执行
    setup_function:每个用例开始前都会执行
    .正在执行----test_two
    teardown_function:每个用例结束前都会执行
    setup_class:类中所有用例执行之前
    setup_method:类中每个用例执行之前
    setup:类中每个用例执行之前
    .正在执行----test_three
    teardown:类中每个用例执行之后
    teardown_method:类中每个用例执行之后
    setup_method:类中每个用例执行之前
    setup:类中每个用例执行之前
    .正在执行----test_four
    teardown:类中每个用例执行之后
    teardown_method:类中每个用例执行之后
    teardown_class:类中所有用例执行之后
    teardown_module:整个.py模块只执行一次
    比如:所有用例结束只最后关闭浏览器

    setup_module/teardown_module的优先级是最大的,然后函数里面用到的setup_function/teardown_function与类里面的setup_class/teardown_class互不干涉

    类里面的setup_method和teardown_method的功能和setup/teardown功能是一样的,一般二者用其中一个即可

     参考原文链接:

    https://www.cnblogs.com/UncleYong/p/7076872.html

    https://blog.csdn.net/qq_27261401/article/details/78312252

    https://blog.csdn.net/yaoliuwei1426/article/details/82146316

  • 相关阅读:
    我所理解的执行力
    iOS移动开发周报-第20期
    iOS移动开发周报-第19期
    iOS开发如何提高
    iOS移动开发周报-第18期
    iOS移动开发周报-第17期
    一起入门python3之元组和数列
    提权笔记本
    sqlmap笔记本
    SQL注入自学[第一学:一个简单的注入环境的编写]
  • 原文地址:https://www.cnblogs.com/87060524test/p/12248439.html
Copyright © 2011-2022 走看看