iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
Modern Web

Flask系列 第 16

Day 16 實作測試 (2)

前言

昨天我們寫好了測試的 model,今天就來用他實作吧。

test_main

我們先從最簡單的 main_bp 開始。

from flask import url_for
from tests.helper import TestModel


class IndexPageTest(TestModel):
    def setUp(self) -> None:
        super().setUp()
        self.route = url_for("main.index_page")

    def test_get_with_no_auth(self):
        res = self.get()
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Login", res.data)

    def test_get_with_auth(self):
        res = self.get(login="user")
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Dashboard", res.data)

他繼承了 TestModel,然後重寫了 setUp,用原先的 setUp 再加上一行指定 self.route,這樣昨天寫的 getpost 就都可以用了,而這個 self.route 是用 url_for 處理的。

後面我們用了兩個測試,一個是在沒登入的情況下抓這個頁面,另一個是在有登入的情況下。我們分別看他們有沒有回傳 200,然後後面我們再使用 assertIn 來確定 "Login""Dashboard" 有沒有在回傳的 HTML 裡面 (res.data),我們會拿這個來當作判斷依據是因為到時候網頁的 navbar 會根據有沒有登入來決定要用怎麼樣子的,如果沒有登入當然就是顯示 login、register 等等,有登入的話就是 dashboard、寫文章之類的按鈕,這邊要注意的是,res.data 是一個 bytes 型別,所以我們前面用的 assertIn 也要跟著他用 bytes 型別。

test_user

結束了 main_bp 的測試,我們來繼續看 user_bp 的。這裡就會有很多路徑,我們一個一個看,首先是登入頁面。

class LoginPageTest(TestModel):
    def setUp(self) -> None:
        super().setUp()
        self.route = url_for("user.login_page")
        self.user_data_bad_wrong_password = {"username": "user", "password": "bad"}

    def test_get_with_no_auth(self):
        res = self.get()
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Login", res.data)

    def test_get_with_auth(self):
        res = self.get(login="user")
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Dashboard", res.data)

    def test_post_ok(self):
        res = self.post(data=self.user_data)
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Dashboard", res.data)

    def test_post_bad_wrong_password(self):
        res = self.post(data=self.user_data_bad_wrong_password)
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Wrong username or password.", res.data)

setUp 裡面,我們一樣先寫好這裡的 self.route,然後額外放了一個錯的帳號密碼。這邊要記得,我們在 TestModelsetUp 就有先生出兩個測試帳號,所以他們用一般的登入是可以的。

我們一樣先分別用沒登入和有登入的狀況去抓這個頁面,這個部分跟剛剛一樣。接下來輪到 post,我們先做一次 OK 的測試,就是拿正確的登入資料塞給他,那他應該要讓我們過,這是我們的期望,後面的 assertIn 是因為我們用 follow_redirects,所以登入後理論上會被重新導向到 dashboard 之類的地方,也就是說一定會有 navbar,所以用這個來判斷。再來是用錯誤的資料塞給網頁,那他應該要出現打錯密碼的訊息,也就是後面 assertIn 的內容。

接下來我們來看看註冊頁面的測試。

class RegisterPageTest(TestModel):
    def setUp(self) -> None:
        super().setUp()
        self.route = url_for("user.register_page")
        self.register_data_ok = {
            "username": "user2",
            "password": "useruser",
            "repeat_password": "useruser",
            "email": "user@a.a",
        }
        self.register_data_bad_too_short_password = {
            "username": "user2",
            "password": "short",
            "repeat_password": "short",
            "email": "user@a.a",
        }

    def test_get_with_no_auth(self):
        res = self.get()
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Login", res.data)

    def test_get_with_auth(self):
        res = self.get(login="user")
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Dashboard", res.data)

    def test_post_ok(self):
        res = self.post(data=self.register_data_ok)
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"Login", res.data)

    def test_post_bad_too_short_password(self):
        res = self.post(data=self.register_data_bad_too_short_password)
        self.assertEqual(res.status_code, 200)
        self.assertIn(b"The password must contain at least 6 characters.", res.data)

setUp 我們做了差不多的事情,這次我們準備了一份可以註冊的使用者資料跟一份密碼過短的,這個密碼過短的部分是 Flask-WTF 的工作,他會幫我們驗證。

一開始我們一樣看一下正常去抓網頁會不會有正常反應,當然加入登入和未登入兩個狀態。接下來我們先丟正確的資料給他,所以正常來說應該是註冊成功了,他應該會把我們導向到登入頁面之類的,但是還沒有登入,所以 navbar 上面還是會有 Login。而第二個則是密碼過短,Flask-WTF 會幫我們驗證到然後丟出錯誤,所以我們會收到這個訊息,然後 flash 出去,所以用 assertIn 來確定有沒有這個錯誤訊息,這個錯誤訊息是可以自訂的,也可以在 Flask-WTF 自己修改。

user_bp 當然不只有這兩個路徑,但我們就示範一些,不然太多也太重複了。


上一篇
Day 15 實作測試 (1)
下一篇
Day 17 實作測試 (3)
系列文
Flask30

尚未有邦友留言

立即登入留言