• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >python > 在Python的Flask框架中实现单元测试的教程

在Python的Flask框架中实现单元测试的教程

作者:goldensun 字体:[增加 减小] 来源:互联网

goldensun 通过本文主要向大家介绍了python flask框架,python flask教程,python flask,python3 flask,python3 flask教程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

 概要

在前面的章节里我们专注于在我们的小应用程序上一步步的添加功能上。到现在为止我们有了一个带有数据库的应用程序,可以注册用户,记录用户登陆退出日志以及查看修改配置文件。

在本节中,我们不为应用程序添加任何新功能,相反,我们要寻找一种方法来增加我们已写代码的稳定性,我们还将创建一个测试框架来帮助我们防止将来程序中出现的失败和回滚。

让我们来找bug

在上一章的结尾谈到,我故意在应用程序中引入一个bug。接下来让我描述一下它是什么样的bug,然后看看当我们的程序不按照我们意愿执行的时候,它在其中又起了什么样的影响。

应用程序的问题在于,没有保证用户昵称的唯一性。用户昵称是由应用程序自动初始化的。我们首先会考虑使用OpenID provider给出的用户的昵称,然后再考虑使用Email信息中的用户名部分作为用户的昵称。但如果出现重复的昵称,则后面的用户将无法注册成功。更糟糕的是,在修改用户配置的表单中,我们允许用户任意更改他们的昵称,但我们仍然没有对昵称冲突进行检查。

当我们分析完错误产生时应用程序的行为之后,我们将会定位这些问题。

Flask 的调试功能

那么让我们看看当bug被触发时,会出现什么现象。

让我们从创建一个崭新的数据库,在linux下,执行:
 

rm app.db
./db_create.py
</div>

在Windows下,执行:
 

del app.db
flask/Scripts/python db_create.py

</div> 我们需要两个OpenID的账号来重现这个bug。当然这两个账号最理想的状态是来自来个不同的拥有者,那样可以避免他们的cookie把情况搞的更复杂。通过如下步骤创建冲突的昵称:</div>
  •     用第一个账号登陆
  •     进入用户信息属性编辑页面,将昵称改为“dup”
  •     登出系统
  •     用第二个账号登陆
  •     修改第二个账号的用户信息属性,将昵称改为“dup”


哎哟!sqlalchemy中抛出了一个异常,来看一下错误信息:

lalchemy.exc.IntegrityError
IntegrityError: (IntegrityError) column nickname is not unique u'UPDATE user SET nickname=?, about_me=? WHERE user.id = ?' (u'dup', u'', 2)

</div>

错误的后面是这个错误的堆栈信息,事实上,这是一个相当不错的错误提示,你可以转向任何框架检查代码或者在浏览器里执行正确的表达式。

这个错误信息相当明确,我们试图在数据插入一个重复的昵称,数据库的昵称字段是一个卫衣键,因此这样的操作是无效的。
 

除了实际的错误,在我们手头上还有一个次要的错误。如果一个用户不注意在我们应用程序里引起了一个错误(这一个错误或者任何其他原因引起的异常),应用程序将向他/她暴漏错误信息和堆栈信息,而不是暴露给我们。对于我们开发者来说这是个很好的特性,但是很多时候我们不想让用户看到这些信息。

这么长时间以来,我们一直在debug模式下运行我们的应用程序,我们通过设置debug=True的参数来启用应用程序的debug模式。这里我们在运行脚本run.py里配置。

当我们这样开发应用是方便的,但是我们需要在生产环境上关闭debug模式。 让我们创建另一个启动脚本文件设置关闭dubug模式(filerunp.py): 
 

#!flask/bin/python
from app import app
app.run(debug = False)
</div>

现在重新启动应用:

./runp.py
</div>

并且现在再尝试重命名第二个账号nickname成‘dup'

这次我们没有获取到一个错误信息,取而代之,我们得到了一个HTTP 500错误码,这是个内部服务器错误。虽然这不容易定位错误,但至少没有暴露我们应用程序的任何细节给陌生人。当调试关闭后出现一个异常时,Flask会产生一个500页面。

虽然这样好些了,但现在仍存在两个问题。首先美化问题:默认的500页面很丑陋。第二个问题更重要些,当用户操作失败时,我们无法获取到错误信息了,因为错误在后台默默的处理了。幸运的是有个简单方式来处理这两个问题。

定制HTTP错误处理程序

Flask为应用程序提供了一个机制来安装他们自己的错误页面,作为例子,让我们定义两个最常见的HTTP 404和500错误的自定义页面。定制其他错误页面也是同样的方式。

使用一个修饰来声明一个定制的错误处理程序 (fileapp/views.py):
 

@app.errorhandler(404)
def internal_error(error):
  return render_template('404.html'), 404
 
@app.errorhandler(500)
def internal_error(error):
  db.session.rollback()
  return render_template('500.html'), 500
</div>

这地方无需多言,因为他们都是不言而喻的。唯一有趣的地方时错误500处理中的rollack语句,这个地方是不可缺少的因为这个方法会被当做一个异常调用。如果因为数据库错误导致一个异常,那么数据库的会话将变成一个无效状态,因此我们需要回滚它,以防止一个会话转向一个500错误的模板。

这是一个404错误在模版
 

<!-- extend base layout -->
{% extends "base.html" %}
 
{% block content %}
<h1>File Not Found</h1>
<p><a href="{{url_for('index')}}">Back</a></p>
{% endblock %}
</div>

这是一个500错误的模版
 

<!-- extend base layout -->
{% extends "base.html" %}
 
{% block content %}
<h1>An unexpected error has occurred</h1>
<p>The administrator has been notified. Sorry for the inconvenience!</p>
<p><a href="{{url_for('index')}}">Back</a></p>
{% endblock %}
</div>

注意,我们会继续使用我们base.html 布局, 这样我们的错误页看起来比较舒服

通过email发送错误日志

为了处理第二个问题我们需要配置应用的错误报告机制。

第一个是每当有错误发生时把错误日志通过邮件发送给我们。

首先,我们需要在我们的应用配置邮件服务器和管理员列表 (fileconfig.py):
 

# mail server settings
MAIL_SERVER = 'localhost'
MAIL_PORT = 25
MAIL_USERNAME = None
MAIL_PASSWORD = None
 
# administrator list
ADMINS = ['you@example.com']
</div>

当然,你要把上面的配置改成你自己的才有意义
 

Flask 使用通用的Python logging模块, 所以设置发送错误日志邮件非常简单. (fileapp/__init__.py):
 

from config import basedir, ADMINS, MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD
 
if not app.debug:
  import logging
  from logging.handlers import SMTPHandler
  credentials = None
  if MAIL_USERNAME or MAIL_PASSWORD:
    credentials = (MAIL_USERNAME, MAIL_PASSWORD)
  mail_handler = SMTPHandler((MAIL_SERVER, MAIL_PORT), 'no-reply@' + MAIL_SERVER, ADMINS, 'microblog failure', credentials)
  mail_handler.setLevel(logging.ERROR)
  app.logger.addHandler(mail_handler)
</div>

Note that we are only enabling the emails when we run without debugging.
注意,我们要的非dubug模式下开启邮件功能.
 

在没有邮件服务器的pc上测试邮件功能也很容易,幸好Python有SMTP的测试排错的服务器(SMTP debugging server)。打开一个控制台窗口,并且运行下面的命令:
 

python -m smtpd -n -c DebuggingServer localhost:25
</div>

当程序运行的时候,应用接收和发送邮件会在控制台窗口中显示出来。

打印日志到文件

通过邮件接收错误日志非常不错,但是,这是不够的。有些导致失败的条件不会触发异常并且不是主要的问题,所以我们需要将日志保存到log文件中,在某些情况下,需要日志来进行排错。

出于这个原因,我们的应用需要一个日志文件。

开启文件日志和邮件日志很相似(fileapp/__init__.py):
 

if not app.debug:
  import logging
  from logging.handlers import RotatingFileHandler
  file_handler = RotatingFileHandler('tmp/microblog.log', 'a', 1 * 1024 * 1024, 10)
  file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [
  


 

您可能想查找下面的文章:

  • 使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
  • Python的Flask框架标配模板引擎Jinja2的使用教程
  • Python的Flask框架及Nginx实现静态文件访问限制功能
  • Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
  • 详解Python的Flask框架中的signals信号机制
  • Flask的图形化管理界面搭建框架Flask-Admin的使用教程
  • Python的Flask框架中集成CKeditor富文本编辑器的教程
  • Flask框架中密码的加盐哈希加密和验证功能的用法详解
  • Python的Flask框架应用程序实现使用QQ账号登录的方法
  • Python的Flask框架中使用Flask-Migrate扩展迁移数据库的教程

相关文章

  • Python中利用原始套接字进行网络编程的示例
  • python根据距离和时长计算配速示例
  • python使用win32com在百度空间插入html元素示例
  • 简介Python设计模式中的代理模式与模板方法模式编程
  • 在Django的通用视图中处理Context的方法
  • 在Lighttpd服务器中运行Django应用的方法
  • python基础教程之字典操作详解
  • 用python解析xml的几种方法
  • python进程类subprocess的一些操作方法例子
  • 深入解析Python中的变量和赋值运算符

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • pytyon 带有重复的全排列
    • python中map、any、all函数用法分析
    • 跟老齐学Python之关于类的初步认识
    • python实现从一组颜色中找出与给定颜色最接近颜色的方法
    • python打开网页和暂停实例
    • python实现html转ubb代码(html2ubb)
    • 记录Django开发心得
    • 简单谈谈Python中的几种常见的数据类型
    • python解析xml文件实例分享
    • python基于windows平台锁定键盘输入的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有