Flask Web Development —— 大型應用程序結構(下)

四、啓動腳本

頂層目錄中的manage.py文件用於啓動應用。這個腳本會在示例7-8中展現。html

示例7-8. manage.py:啓動腳本python

#!/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以及自定義上下文會被初始化。git

爲了方便,會增長一行執行環境,這樣在基於Unix的操做系統上能夠經過./manage.py來執行腳原本替代冗長的python manage.pysql

五、需求文件

應用程序必須包含requirements.txt文件來記錄全部依賴包,包括精確的版本號。這很重要,由於能夠在不一樣的機器上從新生成虛擬環境,例如在生產環境的機器上部署應用程序。這個文件能夠經過下面的pip命令自動生成:shell

(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

當你須要完美複製一個虛擬環境的時候,你能夠運行如下命令建立一個新的虛擬環境:flask

(venv) $ pip install -r requirements.txt

當你讀到這時,示例requirements.txt文件中的版本號可能已通過時了。若是喜歡你能夠嘗試用最近發佈的包。若是遇到任何問題,你能夠隨時回退到需求文件中與應用兼容的指定版本。session

六、單元測試

這個應用很是小以致於不須要太多的測試,可是做爲示例會在示例7-9中展現兩個簡單的測試定義。app

示例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

七、數據庫啓動

與單腳本的應用相比,重構後的應用使用不一樣數據庫。

從環境變量中獲取的數據庫URL做爲首選,默認SQLite數據庫做爲可選。三個配置中的環境變量和SQLite數據庫文件名是不同的。例如,開發配置的URL是從DEV_DATABASE_URL環境變量中獲取,若是沒有定義則會使用名爲data-dev.sqlite的SQLite數據庫。

不管數據庫URL源的是哪個,都必須爲新的數據庫建立數據庫表。若是使用了Flask-Migrate來保持遷移跟蹤,數據庫表能夠被建立或更新到最近的版本經過下面的命令:

(venv) $ python manage.py db upgrade

相信與否,已經到了第一部分結束的地方。你如今已經學到了Flask必要的基本要素,可是你不肯定如何將這些零散的知識組合在一塊兒造成一個真正的應用程序。第二部分的目的是經過開發一個完整的應用程序來帶領你繼續前行。

注:前段時間才知道這本書已經由圖靈社區出版翻譯,已經開始預售了,並於12月19日到貨。喜歡的朋友也能夠[點我]購買一本。後面的章節就再也不繼續更新了,本身確定也會去支持這本書的。

相關文章
相關標籤/搜索