在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 \n'%(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 \n'%(a, b)) def test_case_A(self): a = self.a*2 b = self.b*2 print('run A over :') print('a = %s, a = %s \n'%(a, b)) def test_case_C(self): a = self.a*4 b = self.b*4 print('run C over :') print('a = %s, a = %s \n'%(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