1. 程式人生 > >使用“數據驅動測試”之前你應該知道的(二)

使用“數據驅動測試”之前你應該知道的(二)

clas back args ase 沒有 告訴 ... last 數據文件

我們繼續上期的話題,單純讀取數據文件來做自動化是有諸多問題的。那麽我們借助單元測試框架來做自動化就爽多了,因為它解決了測試中的幾問題。

  • 如何定義一條測試用例,我們知道編程的世界裏並沒“用例”的概念。它只有目錄、文件、類、方法、函數...,而單元測試框架告訴我們如何定義一條用例。

  • 如何寫斷言,是的!當你做了一堆操作之後,如何判斷這一系列操作是符合預期的,那麽一定要拿實際結果與預期結果進行比較,而單元測試框架告訴我們如何寫斷言。

  • 測試結果統計,當執行了一系列的用例之後,總共運行了多少條用例,成功了多少條,失敗了多少條,失敗的用例錯誤在哪裏?單元測試框架會幫我們統計和展示。

被測功能還是上一篇的功能。

技術分享圖片



這裏以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(實際規模化之後就不得而知了),我也看了不少資料,找到一些勉強能接受的方法。

當然,這又是另一篇文章了。

使用“數據驅動測試”之前你應該知道的(二)