我們繼續上期的話題,單純讀取數據文件來做自動化是有諸多問題的。那么我們借助單元測試框架來做自動化就爽多了,因為它解決了測試中的幾問題。
-
如何定義一條測試用例,我們知道編程的世界里並沒“用例”的概念。它只有目錄、文件、類、方法、函數...,而單元測試框架告訴我們如何定義一條用例。
-
如何寫斷言,是的!當你做了一堆操作之后,如何判斷這一系列操作是符合預期的,那么一定要拿實際結果與預期結果進行比較,而單元測試框架告訴我們如何寫斷言。
-
測試結果統計,當執行了一系列的用例之后,總共運行了多少條用例,成功了多少條,失敗了多少條,失敗的用例錯誤在哪里?單元測試框架會幫我們統計和展示。
被測功能還是上一篇的功能。
這里以unittest 單元測試框架為例。
import unittest
from selenium import webdriver
from time import sleep
class LoginTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.url = "http://127.0.0.1:8000/"
cls.driver.implicitly_wait(10)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
def user_login(self, username, password):
driver = self.driver
driver.get(self.url)
driver.find_element_by_id("inputUsername").send_keys(username)
driver.find_element_by_id("inputPassword").send_keys(password)
driver.find_element_by_id("Login").click()
def atest_login_01(self):
self.user_login("", '123')
tips = self.driver.find_element_by_id("tips").text
self.assertEqual(tips, '請輸入帳號')
def atest_login_02(self):
self.user_login("user", "")
tips = self.driver.find_element_by_id("tips").text
self.assertEqual(tips, '請輸入密碼')
def atest_login_03(self):
self.user_login("error", "error")
tips = self.driver.find_element_by_id("tips").text
self.assertEqual(tips, '帳號或密碼錯誤')
def atest_login_04(self):
self.user_login("admin", "admin123456")
sleep(2)
tips = self.driver.find_element_by_id("user").text
self.assertEqual(tips, 'admin你好')
if __name__ == '__main__':
unittest.main()
看!測試代碼是不是非常清晰。運行結果如下。
...F
======================================================================
FAIL: test_login_04 (__main__.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_login.py", line 43, in test_login_04
self.assertEqual(tips, 'admin你好')
AssertionError: 'admin' != 'admin你好'
- admin
+ admin你好
? ++
----------------------------------------------------------------------
Ran 4 tests in 12.977s
FAILED (failures=1)
結果告訴我們運行了4條測試,1條失敗了,失敗的原因是test_login_04用例斷言預期結果為“admin你好”,實際結果為“admin”。
可是,這沒有用到讀取數據文件啊?不是,數據驅動啊? 我以為這么規范的編寫測試用例,要啥自行車。
其實,我已經盡量的把登錄操作做了封裝,每條用例里面只關心登錄的數據和結果的斷言。誰告訴你“數據驅動”就必須要“讀取數據文件”的?
我們繼續引入unitest的參數化。
import unittest
from selenium import webdriver
from time import sleep
from parameterized import parameterized
class LoginTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.url = "http://127.0.0.1:8000/"
cls.driver.implicitly_wait(10)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
def user_login(self, username, password):
driver = self.driver
driver.get(self.url)
driver.find_element_by_id("inputUsername").send_keys(username)
driver.find_element_by_id("inputPassword").send_keys(password)
driver.find_element_by_id("Login").click()
@parameterized.expand([
("user_null", '', "123", "請輸入帳號"),
("pawd_null", "user", '', "請輸入密碼"),
("login_error", "error", "error", "帳號或密碼錯誤"),
("login_success", "admin", "admin123456", "admin你好"),
])
def test_login(self, name, username, password, assert_text):
self.user_login(username, password)
if name == "login_success":
sleep(2)
tips = self.driver.find_element_by_id("user").text
self.assertEqual(tips, assert_text)
else:
tips = self.driver.find_element_by_id("tips").text
self.assertEqual(tips, assert_text)
if __name__ == '__main__':
unittest.main(verbosity=2)
反正都是定義測試數據,這里提供了規范的元組給你用來定義數據,而且測試數據與測試方法上下呼應,維護起來也比讀取文件方便多了,這次還要啥自行車?
測試結果:
test_login_0_user_null (__main__.LoginTest) ... ok
test_login_1_pawd_null (__main__.LoginTest) ... ok
test_login_2_login_error (__main__.LoginTest) ... ok
test_login_3_login_success (__main__.LoginTest) ... FAIL
======================================================================
FAIL: test_login_3_login_success (__main__.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python36\lib\site-packages\parameterized-0.6.1-py3.6.egg\parameterized\parameterized.py", line 392, in standalone_func
return func(*(a + p.args), **p.kwargs)
File "test_login.py", line 37, in test_login
self.assertEqual(tips, assert_text)
AssertionError: 'admin' != '請輸入密碼'
- admin
+ 請輸入密碼
----------------------------------------------------------------------
Ran 4 tests in 12.363s
FAILED (failures=1)
測試結果依然清晰明白。
這個話題,本來到此就結束了,我其實是很鄙視讀取數據文件的操作的,因為真get不到它的“方便”之處,做自動化測試寫代碼就老老實實的寫代碼,就你測試用的這點數據,真沒必要讀取文件,數據庫就更談不上了。但是,那么多人都在分享讀取數據文件的demo(實際規模化之后就不得而知了),我也看了不少資料,找到一些勉強能接受的方法。
當然,這又是另一篇文章了。