我們在做接口測試的時候很可能設計出這樣與數據關聯的測試用例。比如
def test_create_user(self):
user = create_user(name="fred", age=29) # 調用創建用戶的接口
self.assertEqual(user['name'], 'fred')
def test_get_user(self):
user = get_last_created_user() #調用獲取最新注冊用戶的接口
self.assertEqual(user['name'], 'fred')
這樣的測試用例第一眼看上去是感受不出來問題的。
不過仔細想想,可能會存在下面的問題
test_create_user
用例必須在test_get_user
用例執行之前執行,否則test_get_user(self)
用戶是沒有數據的,*test_get_user
用例沒辦法單獨執行test_create_user
用例執行一次之后,name: fred, age: 29
就成了臟數據了,不刪除的話之后test_get_user
用例有很大概率每次都能執行成功
為了解決上面的問題,我們可以這樣做
def test_create_user(self):
user = create_user(name="fred", age=29) # 調用創建用戶的接口
delete_user(user['id']) # 調用刪除接口,將創建的用戶給刪除掉
self.assertEqual(user['name'], 'fred')
def test_get_user(self):
user = create_user(name="fred", age=29) # 調用創建用戶的接口
user = get_last_created_user() #調用獲取最新注冊用戶的接口
delete_user(user['id']) # 調用刪除接口,將創建的用戶給刪除掉
self.assertEqual(user['name'], 'fred')
這樣一來臟數據問題就解決了,不過用例里多了很多跟測試邏輯無關的代碼。
順便留一個問題給大家思考:為什么刪除數據的代碼要放在斷言之前執行?
為了將數據處理代碼跟測試邏輯分開來,下一步我們可以這樣做,以sqlite3為例
import sqlite3
def setUp(self):
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute("delete * from users")
c.execute("insert into users ......") # 插入一些存量數據,這樣測試翻頁之類的邏輯會容易點
conn.commit()
conn.close()
def test_create_user(self):
user = create_user(name="fred", age=29) # 調用創建用戶的接口
self.assertEqual(user['name'], 'fred')
def test_get_user(self):
user = create_user(name="fred", age=29) # 調用創建用戶的接口
user = get_last_created_user() #調用獲取最新注冊用戶的接口
self.assertEqual(user['name'], 'fred')
上面的例子里,setUp
方法會在每個用例執行之前執行,所以就不需要每條用例都去清理數據了。
總結
- 上面的例子都是以unittest庫為例,其他測試框架庫原理是相同的
- 上面的例子是偽代碼,不能直接執行
- 上面的例子里,每個用例執行之前都會插入一遍數據,如果數據量比較大,那么用例運行速度會變慢