簡介
大多數的初學者在使用 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()
方法中關閉資料庫,這樣,不必在每個測試方法中重複相同的代碼。