资讯专栏INFORMATION COLUMN

Flask Web Development —— 大型应用程序结构(下)

whidy / 2478人阅读

摘要:单元测试这个应用非常小以至于不需要太多的测试,但是作为示例会在示例中展示两个简单的测试定义。示例单元测试编写好的测试使用的是来自于标准库中标准的包。为了运行单元测试,可以在脚本中增加一个自定义的命令。

4、启动脚本

顶层目录中的manage.py文件用于启动应用。这个脚本会在示例7-8中展示。

示例7-8. manage.py:启动脚本

#!/usr/bin/env python
import os
from app import create_app, db
from app.models import User, Role
from flask.ext.script import Manager, Shell
from flask.ext.migrate import Migrate, MigrateCommand

app = create_app(os.getenv("FLASK_CONFIG") or "default") 
manager = Manager(app)
migrate = Migrate(app, db)

def make_shell_context():
    return dict(app=app, db=db, User=User, Role=Role)

manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command("db", MigrateCommand)

if __name__ == "__main__": 
    manager.run()

这个脚本开始于创建应用程序。使用环境变量FLASK_CONFIG,若它已经定义了则从中获取配置;如果没有,则是用默认配置。然后用于Python shell的Flask-Script、Flask-Migrate以及自定义上下文会被初始化。

为了方便,会增加一行执行环境,这样在基于Unix的操作系统上可以通过./manage.py来执行脚本来替代冗长的python manage.py

5、需求文件

应用程序必须包含requirements.txt文件来记录所有依赖包,包括精确的版本号。这很重要,因为可以在不同的机器上重新生成虚拟环境,例如在生产环境的机器上部署应用程序。这个文件可以通过下面的pip命令自动生成:

(venv) $ pip freeze >requirements.txt

当安装或更新一个包之后最好再更新一下这个文件。以下展示了一个需求文件示例:

Flask==0.10.1
Flask-Bootstrap==3.0.3.1
Flask-Mail==0.9.0
Flask-Migrate==1.1.0
Flask-Moment==0.2.0
Flask-SQLAlchemy==1.0
Flask-Script==0.6.6
Flask-WTF==0.9.4
Jinja2==2.7.1
Mako==0.9.1
MarkupSafe==0.18
SQLAlchemy==0.8.4
WTForms==1.0.5
Werkzeug==0.9.4
alembic==0.6.2
blinker==1.3
itsdangerous==0.23

当你需要完美复制一个虚拟环境的时候,你可以运行以下命令创建一个新的虚拟环境:

(venv) $ pip install -r requirements.txt

当你读到这时,示例requirements.txt文件中的版本号可能已经过时了。如果喜欢你可以尝试用最近发布的包。如果遇到任何问题,你可以随时回退到需求文件中与应用兼容的指定版本。

6、单元测试

这个应用非常小以至于不需要太多的测试,但是作为示例会在示例7-9中展示两个简单的测试定义。

示例7-9. tests/test_basics.py:单元测试

import unittest
from flask import current_app 
from app import create_app, db

class BasicsTestCase(unittest.TestCase): 
    def setUp(self):
        self.app = create_app("testing")
        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_app_exists(self): 
        self.assertFalse(current_app is None)

    def test_app_is_testing(self): 
        self.assertTrue(current_app.config["TESTING"])

编写好的测试使用的是来自于Python标准库中标准的unittest包。setUp()tearDown()方法在每个测试之前和之后运行,且任何一个方法必须以test_开头作为测试来执行。

建议:如果你想要学习更多使用Python的unittest包来写单元测试的内容,请参阅官方文档。

setUp()方法尝试创建一个测试环境,类似于运行应用程序。首先它创建应用程序配置用于测试并激活上下文。这一步确保测试可以和常规请求一样访问current_app。然后,当需要的时候,可以创建一个供测试使用的全新数据库。数据库和应用程序上下文会在tearDown()方法中被移除。

第一个测试确保应用程序实例存在。第二个测试确保应用程序在测试配置下运行。为了确保tests目录有效,需要在tests目录下增加__init__.py文件,不过该文件可以为空,这样unittest包可以扫描所有模块并定位测试。

建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 7a来切换到这个版本的应用程序。为了确保你已经安装了所有依赖集,需要运行pip install -r requirements.txt

为了运行单元测试,可以在manage.py脚本中增加一个自定义的命令。

示例7-10展示如何添加测试命令。

示例7-10. manage.pyt:单元测试启动脚本

@manager.command
def test():
    """Run the unit tests."""
    import unittest
    tests = unittest.TestLoader().discover("tests") 
    unittest.TextTestRunner(verbosity=2).run(tests)

manager.command装饰器使得它可以很容易的实现自定义命令。被装饰的函数名可以被当做命令名使用,且函数的文档字符串会显示帮助信息。test()函数的执行会调用unittest包中的测试运行器。

单元测试可以像下面这样执行:

(venv) $ python manage.py test
test_app_exists (test_basics.BasicsTestCase) ... ok
test_app_is_testing (test_basics.BasicsTestCase) ... ok

.----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK
7、数据库启动

与单脚本的应用相比,重构后的应用使用不同数据库。

从环境变量中获取的数据库URL作为首选,默认SQLite数据库作为可选。三个配置中的环境变量和SQLite数据库文件名是不一样的。例如,开发配置的URL是从DEV_DATABASE_URL环境变量中获取,如果没有定义则会使用名为data-dev.sqlite的SQLite数据库。

无论数据库URL源的是哪一个,都必须为新的数据库创建数据库表。如果使用了Flask-Migrate来保持迁移跟踪,数据库表可以被创建或更新到最近的版本通过下面的命令:

(venv) $ python manage.py db upgrade

相信与否,已经到了第一部分结束的地方。你现在已经学到了Flask必要的基本要素,但是你不确定如何将这些零散的知识组合在一起形成一个真正的应用程序。第二部分的目的是通过开发一个完整的应用程序来带领你继续前行。

注:前段时间才知道这本书已经由图灵社区出版翻译,已经开始预售了,并于12月19日到货。喜欢的朋友也可以[点我]购买一本。后面的章节就不再继续更新了,自己肯定也会去支持这本书的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/45321.html

相关文章

  • Flask Web Development —— 大型应用程序结构(上)

    摘要:被定义在包的构造函数中的应用程序工厂函数会在示例中展示。这个构造函数导入大部分当前需要使用的扩展,但因为没有应用程序实例初始化它们,它可以被创建但不初始化通过不传递参数给它们的构造函数。而应用程序范围内的错误处理则必须使用。 虽然小型web应用程序用单个脚本可以很方便,但这种方法却不能很好地扩展。随着应用变得复杂,在单个大的源文件中处理会变得问题重重。 与大多数其他web框架不同,Fl...

    chemzqm 评论0 收藏0
  • [分享] Flask 网络开发经典书籍: Flask Web Development

    摘要:他和妻子四个孩子两只狗和一只猫共同生活在俄勒冈州波特兰市。。还邀请他根据书的内容,制作了两个视频教程。 showImg(http://img4.douban.com/lpic/s27205547.jpg); 这本书算是学习Flask的权威材料了,网上很多人都是推荐从这本书开始学习。起初,作者在自己的博客发布了一个大型的Flask建站教程,在这个教程大受欢迎的基础上,才与OReilly公...

    HmyBmny 评论0 收藏0
  • Flask Web Development —— 基本应用程序结构(上)

    摘要:注对于开发者来说,传给应用程序构造函数的参数是比较容易弄混淆的。在应程序中定义路由的最便捷的方式是通过显示定义在应用程序实例之上的装饰器,注册被装饰的函数来作为一个路由。一个常见的模式是使用装饰器来注册函数作为一个事件处理程序。 在这一章,你将学习Flask应用程序不同部分。同时你将编写和运行你的第一个Flask web应用程序。 1、初始化 在这章,你将学到Flask应用程序的不...

    NusterCache 评论0 收藏0
  • Flask Web Development —— 基本应用程序结构

    摘要:有两类应用级和请求级。一个响应中非常重要的部分是状态码,默认设置来指示请求已经成功处理。重定向通常由响应状态码注明并且重定向的由头部的给出。因为这些变化,应用程序获得一组基本的命令行选项。运行显示可用信息在应用程序上下文的内部运行一个。 5、请求-响应循环 现在你已经玩过一个基本的Flask应用程序,你也许想要知道更多关于Flask如何施展魔力。下面章节描述了一些框架设计方面的特点。...

    caohaoyu 评论0 收藏0
  • Flask Web Development —— 模板(上)

    摘要:用真实的值替换变量并返回最终响应字符串,这个过程称为渲染。示例展示模板实现该响应。控制结构提供一些控制结构用于改变模板流。这个示例展示如何使用循环做到这些同样支持宏,这和代码中的函数很像。 写代码最关键的是要易于维护且结构清晰整洁。目前为止,你看到的例子都过于简单从而没有做这方面的要求。Flask视图函数希望将两个应该完全独立的任务一并处理,两个任务有两种代码,一并处理势必会引发问题。...

    fizz 评论0 收藏0

发表评论

0条评论

whidy

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<