Flask中的藍圖與單元測試 簡介
因為Flask框架的整合度很低,隨著Flask專案檔案的增多,會導致不太好管理。但如果對一個專案進行模組化管理的,那樣子管理起來就會特別方便。而在Flask中剛好就提供了這麼一個特別好用的工具藍圖(Blueprint)。在進行團隊開發時,為了保證我們寫的程式碼更加穩定,一般需要進行單元測試。該如何進行單元測試呢?
一、Blueprint
1.什麼是藍圖
可以把藍圖當做一個儲存檢視的容器,被藍圖裝飾過的函式,會被儲存起來,然後把這個藍圖註冊到專案中的APP之後就被藍圖裝飾的函式可以使用了。
藍圖的作用就是把多個檔案中的檢視繫結到專案的app中,這樣就能處理請求了。說白了就是一種模組化管理。
2.藍圖的特點
(1). 一個應用中可以有多個藍圖
(2). 在初始化應用後,一般就需要把藍圖註冊到應用中。但是不能反過來。
(3). 可以將一個藍圖註冊到一個未使用的url下,這樣被這個藍圖裝飾的檢視預設就是在這個url下。
注意:一個藍圖不是一個完整的應用,不能獨立於應用執行,必須註冊到某個應用中。
3. 使用藍圖步驟:
(1). 建立一個藍圖物件
(2). 使用藍圖物件註冊路由等操作
(3). 在應用上註冊這個物件
4. 執行機制
(1). 藍圖儲存了一組可以在應用物件上執行的操作,如註冊路由
(2). 當在應用物件呼叫route裝飾器註冊路由時,這個操作將修改物件的url_map路由表
(3). 但是,藍圖沒有路由表,當在藍圖物件上呼叫route()裝飾器註冊路由時,只是在內部的一個延時操作記錄列表defered_funcitons中添加了一項。
(4). 當呼叫應用物件的register_blueprint()時,應用物件將從藍圖物件的defered_functions列表中取出每一項,實際上是呼叫應用物件那個的add_url_rule(),這真正的改變了應用物件的路由表(url_map)。
二、具體應用如下:
app.py
1 from flask import Flask, Blueprint 2 3 from blueprint import admin 4 5 app = Flask(__name__) 6 7 # 3.註冊藍圖物件 8 # url_prefix引數指明,由api裝飾的函式,其url必須有/admin 9 app.register_blueprint(admin, url_prefix='/admin') 10 11 12 @app.route('/') 13 def index(): 14 return 'index' 15 16 17 @app.route('/list') 18 def list(): 19 return 'list' 20 21 22 @app.route('/detail') 23 def detail(): 24 return 'detail' 25 26 27 if __name__ == '__main__': 28 print(app.url_map) 29 app.run(debug=True)
admin.py檔案:
1 from flask import Blueprint 2 3 4 # 1.建立一個藍圖物件 5 admin = Blueprint('admin', __name__) 6 7 8 # 2. 使用藍圖物件裝飾函式 9 @admin.route('/new') 10 def new(): 11 return 'new' 12 13 14 @admin.route('/edit') 15 def edit(): 16 return 'edit' 17 18 19 @admin.route('/publish') 20 def publish(): 21 return 'publish'
url_map如下:
三、單元測試
1.為什麼要單元測試
雖然測試有專門的測試人員,但是為了提高我們自身程式碼的穩定性,我們一般都要為自己寫的程式碼做單元測試,這樣開發的效率會大大提高。單元測試就是我們寫的一小段程式碼,來檢驗目的碼的功能是否符合預期。在Web開發中,單元測試很簡單,就是一個"斷言"(assert)程式碼
2. 斷言
在Python中,使用assert語句來判斷預期結果。
常用斷言:
(1). assertEqual:如果兩個值相等,則pass
(2). assertNotEqual:如果兩個值不相等,則pass
(3). assertTrue:判斷bool值為True,則pass
(4). assertFlase:判斷bool值為False, 則pass
(5). assertIsNone:不存在,則pass
(6). assertIsNotNone:存在,則pass
3. 單元測試的寫法
(1). 自定義一個類,繼承自unittest.TestCase
(2). 類中兩個固定方法setUp()和tearDown():做初始化和回收資源的任務
(3). 自定義以"test"開頭的方法,用來測試某些功能。
4.對資料庫進行測試:
1 import unittest 2 3 from author_book_models import app, db, Author, Book 4 5 6 class DatabaseTestCase(unittest.TestCase): 7 """資料庫單元測試""" 8 9 def setUp(self): 10 # 要進行測試的話,需要開啟這個配置資訊 11 app.config['TESTING'] = True 12 self.app = app 13 db.create_all() 14 15 def tearDown(self): 16 db.session.remove() 17 db.drop_all() 18 19 def test_append_data(self): 20 """新增資料""" 21 22 au = Author(name='laowang') 23 bk = Book(info='python') 24 25 db.session.add_all([au, bk]) 26 db.session.commit() 27 28 author = Author.query.filter_by(name='laowang').first() 29 book = Book.query.filter_by(info='python').first() 30 31 # 斷言資料存在 32 self.assertIsNotNone(author) 33 self.assertIsNotNone(book)