Flask Vue.js全栈开发|第8章:单元测试
Synopsis: 未经测试的小猫,肯定不是一只好猫。本文是填补之前没有进行任何单元测试的坑,使用 Python 自带的 unittest 包,当然你也可以使用 pytest 包。另外,Flask 内建了一个测试客户端 app.test_client(),它能复现程序运行在 Web 服务器中的环境,扮演成客户端从而发送请求。为了查看我们的测试代码覆盖率,需要安装 coverage 包,并创建一个 Flask CLI 命令 - flask test,以后修改业务逻辑了,请跑一遍测试用例
代码已上传到 https://github.com/wangy8961/flask-vuejs-madblog/tree/v0.8 ,欢迎star
1. 测试框架: unittest
1.1 第一个测试
使用 Python 自带的 unittest
包来测试我们的 Flask 应用程序,创建 back-end/tests
目录,并新建 back-end/tests/__init__.py
:
from config import Config class TestConfig(Config): TESTING = True SQLALCHEMY_DATABASE_URI = 'sqlite://'
然后创建我们第一个单元测试 back-end/tests/test_basic.py
,以 test
开头的文件可以被 unittest
找到:
import unittest from flask import current_app from app import create_app, db from tests import TestConfig class BasicsTestCase(unittest.TestCase): def setUp(self): '''每个测试之前执行''' self.app = create_app(TestConfig) # 创建Flask应用 self.app_context = self.app.app_context() # 激活(或推送)Flask应用上下文 self.app_context.push() db.create_all() # 通过SQLAlchemy来使用SQLite内存数据库,db.create_all()快速创建所有的数据库表 def tearDown(self): '''每个测试之后执行''' db.session.remove() db.drop_all() # 删除所有数据库表 self.app_context.pop() # 退出Flask应用上下文 def test_app_exists(self): self.assertFalse(current_app is None) def test_app_is_testing(self): self.assertTrue(current_app.config['TESTING'])
注意: 我们的调试函数都是以
test
开头,这样unittest
就会将这些函数自动识别为测试函数
,并运行它们
1.2 Flask CLI 命令
使用 flask --help
可以查看 flask
命令支持哪些子命令:
(venv) D:\python-code\flask-vuejs-madblog\back-end>flask --help Usage: flask [OPTIONS] COMMAND [ARGS]... A general utility script for Flask applications. Provides commands from Flask, extensions, and the application. Loads the application defined in the FLASK_APP environment variable, or from a wsgi.py file. Setting the FLASK_ENV environment variable to 'development' will enable debug mode. > set FLASK_APP=hello.py > set FLASK_ENV=development > flask run Options: --version Show the flask version --help Show this message and exit. Commands: db Perform database migrations. routes Show the routes for the app. run Runs a development server. shell Runs a shell in the app context.
修改 back-end/madblog.py
:
@app.cli.command() def test(): '''Run the unit tests.''' import unittest tests = unittest.TestLoader().discover('tests') # 找到 tests 目录 unittest.TextTestRunner(verbosity=2).run(tests)
此时,再次运行 flask --help
:
(venv) D:\python-code\flask-vuejs-madblog\back-end>flask --help Usage: flask [OPTIONS] COMMAND [ARGS]... A general utility script for Flask applications. Provides commands from Flask, extensions, and the application. Loads the application defined in the FLASK_APP environment variable, or from a wsgi.py file. Setting the FLASK_ENV environment variable to 'development' will enable debug mode. > set FLASK_APP=hello.py > set FLASK_ENV=development > flask run Options: --version Show the flask version --help Show this message and exit. Commands: db Perform database migrations. routes Show the routes for the app. run Runs a development server. shell Runs a shell in the app context. test Run the unit tests.
发现多了一个 flask test
命令,试一下看看:
(venv) D:\python-code\flask-vuejs-madblog\back-end>flask test test_app_exists (test_basic.BasicsTestCase) ... ok test_app_is_testing (test_basic.BasicsTestCase) ... ok ---------------------------------------------------------------------- Ran 4 tests in 0.242s OK
2个测试都通过了
1.3 测试用户数据模型
新增 back-end/tests/test_user_model.py
:
import unittest from app import create_app, db from app.models import User from tests import TestConfig class UserModelTestCase(unittest.TestCase): def setUp(self): self.app = create_app(TestConfig) self.app_context = self.app.app_context() self.app_context.push() db.create_all() def tearDown(self): db.session.remove() db.drop_all() self.app_context.pop() def test_password_hashing(self): u = User(username='john') u.set_password('pass1234') self.assertTrue(u.check_password('pass1234')) self.
3 条评论
评论者的用户名
评论时间capricorn_bu
2020-04-01T10:51:02Z我本地测试flask --help 没有test这块内容。
本地flask版本1.1.1,是缺少了什么模块么?
Madman capricorn_bu Author
2020-04-01T23:58:06Zflask 使用
click
来增加命令行子命令或选项参数,文章已经写的很清楚:shishijia
2020-04-13T05:31:04Z八八八八