版权声明:浅弋、璃鱼的原创 https://blog.csdn.net/qq_35709559/article/details/83314407
一、蓝图和单元测试:
1.蓝图:
随着flask程序越来越复杂,我们需要对程序进行模块化的处理,之前学习过python的模块化管理,于是针对一个简单的flask程序进行模块化处理
名词解释:
高内聚,低耦合:
所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。
对于低耦合,粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。
解耦合:
模块间有依赖关系必然存在耦合,理论上的绝对零耦合是做不到的,但可以通过一些现有的方法将耦合度降至最低。
2. 使用步骤:
- 创建蓝图对象
- 使用蓝图对象
- 注册蓝图对象
demo01_blueprint.py:
from flask import Flask
from temp_file import api
app = Flask(__name__)
# 注册蓝图到程序实例app上
app.register_blueprint(api)
@app.route("/")
def index():
return "hello world!"
if __name__ == '__main__':
print(app.url_map)
app.run(debug=True)
temp_file.py:
# 导入蓝图模块
from flask import Blueprint
# 创建蓝图对象,第一个参数表示蓝图的名称,第二个参数是文件名
api = Blueprint("api",__name__)
# 把temp_detail文件导入到创建蓝图对象的文件中
# 需要把导包语句写到创建蓝图对象的下面
from temp_detail import detail
# 使用蓝图创建视图函数
@api.route("/list")
def list():
return "list..."
temp_detail.py
# 导入temp_file文件中的蓝图对象
from temp_file import api
@api.route("/detail")
def detail():
return "detail..."
二、单元测试:
1.为什么要测试:
Web程序开发过程一般包括以下几个阶段:[需求分析,设计阶段,实现阶段,测试阶段]。其中测试阶段通过人工或自动来运行测试某个系统的功能。目的是检验其是否满足需求,并得出特定的结果,以达到弄清楚预期结果和实际结果之间的差别的最终目的。
2.测试分类:
测试从软件开发过程可以分为:
- 单元测试
-
- 对单独的代码块(例如函数)分别进行测试,以保证它们的正确性
- 集成测试
-
- 对大量的程序单元的协同工作情况做测试
- 系统测试
-
- 同时对整个系统的正确性进行检查,而不是针对独立的片段
3.断言:
3.1断言原理:
在Web开发过程中,单元测试实际上就是一些“断言”(assert)代码。
断言就是判断一个函数或对象的一个方法所产生的结果是否符合你期望的那个结果。 python中assert断言是声明布尔值为真的判定,如果表达式为假会发生异常。单元测试中,一般使用assert来断言结果。
类似于:
if not expression:
raise AssertionError
AssertionError
3.2 常用的断言方法:
方法 | 说明 |
---|---|
assertEqual | 如果两个值相等,则pass |
assertNotEqual | 如果两个值不相等,则pass |
assertTrue | 判断bool值为True,则pass |
assertFalse | 判断bool值为False,则pass |
assertIsNone | 不存在,则pass |
assertIsNotNone | 存在,则pass |
4.书写单元测试:
- 定义一个类,继承自unittest.TestCase
- 重写两个方法:setUp()和tearDown()
- 测试方法必须以test_开头
- 对数据库测试,最后必须先移除数据库回话对象 db.session.remove()
单元测试: 图书管理系统
# 导入python中的测试框架,测试模块
import unittest
# 导入被测试的文件
from demo2_author_book import *
# 自定义测试类
class TestDatabase(unittest.TestCase):
# 方法名固定的,类似于初始化函数,会被首先执行
def setUp(self):
self.app = app
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:passwd@localhost/test_python32'
db.create_all()
# 方法名固定的,类似于析构函数,会被最后执行
def tearDown(self):
# 移除数据库会话对象
db.session.remove()
db.drop_all() # 删除所有表
# 测试方法的定义,方法名必须以test开头
def test_add_author_book(self):
itcast = Author(name='itcast')
book = Book(info='python')
db.session.add_all([itcast,book])
db.session.commit()
# 查询数据,确认提交数据成功
auth = Author.query.filter(Author.name=='itcast').first()
bk = Book.query.filter_by(info='python').first()
# 断言数据存在
self.assertIsNotNone(auth)
self.assertIsNotNone(bk)