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": "[email protected]",
        }
        self.register_data_bad_too_short_password = {
            "username": "user2",
            "password": "short",
            "repeat_password": "short",
            "email": "[email protected]",
        }

    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 当然不只有这两个路径,但我们就示范一些,不然太多也太重复了。


<<:  Day1-JavaScript(JS)与TypeScript(TS)的基本观念

>>:  IT 铁人赛 k8s 入门30天 -- day2 k8s 元件介绍

Day 18动画原理

前言 我们平常手机拍摄的视讯,看起来虽然是一个连续播放的视讯,但其实他是由一连串的图片组成的。动画的...

Day 6 轻松了解欧洲个资隐私保护

在完整完善的隐私保护设计之下,也需有个健全的隐私保护法规在背後做支撑,藉由完善法规制度的保护之下,视...

DAY3-排序(二)

Merge Sort 原理:利用将两有序数组合并只需要线性时间的特性将数组分割,合并 思考&...

15【雷坑】千万别肖想用 APCS 升大学

事实上一现在的情况来看,若是要用 APCS 成绩当作升大学的跳板是完全不建议的,理由如下: 高手独占...

Day25-好用的网页服务器-nginx(一)

前言 系列文也来到尾声了,终於要进入最後一个观念:Nginx 了,有了前面 K8s 的观念其实就可...