flask.pocoo.org/docs/0.12/——testing-Flask-Application翻譯

logo-full.png

原文地址

Flask應(yīng)用測試

Something that is untested is broken.
上面這句話并不完全正確嘴办,但是距離事實也不遠(yuǎn)了膝迎,雖然不知道這句話從哪兒來的。
未經(jīng)測試的應(yīng)用瞄沙,很難去改善它的代碼,未經(jīng)測試的應(yīng)用程序的開發(fā)人員往往變得非常偏執(zhí)。
如果應(yīng)用程序具有自動測試功能品姓,您可以安全地進(jìn)行更改,并立即知道是否有任何故障箫措。

Flask提供了一種通過暴露Werkzeug測試客戶端腹备,并為您處理上下文本地來測試應(yīng)用程序的方法。
你可以使用它搭建自己喜歡的測試方案斤蔓。在這篇文檔里植酥,我們使用Python自帶的unittest包。

應(yīng)用程序

首先弦牡,我們需要有一個待測試的應(yīng)用程序友驮,我們使用在Tutorial
教程中編寫的程序。如果你還沒有這個程序驾锰,請從這里下載the examples

測試骨架

為了便于測試卸留,我們增加第二個模塊flaskr_tests.py,并且創(chuàng)建一個單元測試的骨架:

import os
import flaskr
import unittest
import tempfile

class FlaskrTestCase(unittest.TestCase):
    def setUp(self):
        self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
        flaskr.app.testing = True
        self.app = flaskr.app.test_client()
        with flaskr.app.app_context():
            flaskr.init_db()
            
    def tearDown(self):
        os.close(self.db_fd)
        os.unlink(flaskr.app.config['DATABASE'])
        
if __name__ == '__main__':
    unittest.main()

setUp()中的代碼創(chuàng)建了一新的測試客戶端椭豫,并且初始化了一個數(shù)據(jù)庫耻瑟。
在每個獨立的測試程序運行之前,這個函數(shù)就被執(zhí)行了赏酥。為了在測試之后刪除數(shù)據(jù)庫喳整,我們在tearDown()
方法中關(guān)閉文件,并且移除裸扶。此外框都,在建立的時候,TESTING配置旗桿也被激活了呵晨。它所做的就是阻止
請求處理時候的錯誤捕捉魏保,使你在執(zhí)行測試請求的時候可以得到更好的錯誤報告蔗蹋。

這個測試端口將會為我們提供一個簡單的程序接口。我們可以觸發(fā)對程序的請求囱淋,并且端口也會為我們跟蹤cookies猪杭。

因為SQLite3是基于文件系統(tǒng)的,我們可以輕易的使用tempfile模塊妥衣,去創(chuàng)建一個臨時的數(shù)據(jù)庫并進(jìn)行初始化皂吮。
mkstemp()函數(shù)為我們做了兩件事:它返回一個底層的文件句柄,和一個隨機(jī)的文件名税手,這個名字是我們將要用來創(chuàng)建數(shù)據(jù)庫的名字蜂筹。
我們必須始終保存 db_fd 以便于我們可以使用os.close()函數(shù)關(guān)閉文件。

如果現(xiàn)在我們運行測試的話芦倒,我們將會看到如下輸出:

python flaskr_tests.py
------------------------------------------------
Ran 0 tests in 0.000s

OK

即使這沒有做任何真正的測試艺挪,我們也已經(jīng)知道了這個flaskr應(yīng)用是語法上有效的,否則兵扬,這樣的引入會產(chǎn)生異常而終止麻裳。

第一個測試

現(xiàn)在是時候開始測試應(yīng)用程序的功能了.現(xiàn)在我們測試,如果我們進(jìn)入應(yīng)用程序的根目錄器钟,就會顯示“No entries here so far”
因此津坑,我們向類中增加一個方法,如下:

class FlaskrTestCase(unittest.TestCase):

    def setUp(self):
        self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
        flaskr.app.testing = True
        self.app = flaskr.app.test_client()
        with flaskr.app.app_context():
            flaskr.init_db()

    def tearDown(self):
        os.close(self.db_fd)
        os.unlink(flaskr.app.config['DATABASE'])

    def test_empty_db(self):
        rv = self.app.get('/')
        assert b'No entries here so far' in rv.data

請注意傲霸,我們的測試功能以測試文字開始;這允許unittest自動將方法識別為運行測試疆瑰。
通過使用self.app.get('/')我們可以用特定的路徑,向應(yīng)用程序發(fā)送一個HTTP請求昙啄。
返回值是一個response_class對象∧乱郏現(xiàn)在我們可以使用data屬性,檢驗從應(yīng)用程序的返回值(字符串)梳凛。
在這種情況下耿币,我們確保‘No entries here so far’是輸出的一部分伶跷。

再次運行它掰读,你將會看到顯示通過測試:

python flaskr_tests.py
------------------------------------
Ran 1 test in 0.034s

OK

登陸和退出

我們應(yīng)用的大部分只對于管理員才有用秘狞,所以我們需要一種方式叭莫,讓我們測試的客戶可以登錄、推出烁试。
為了這樣做雇初,我們使用所需的表單數(shù)據(jù)(用戶名和密碼)將一些請求發(fā)送到登錄和注銷頁面。
并且因為登錄和注銷頁面重定向减响,我們告訴客戶follow_redirects靖诗。

向FlaskrTestCase類增加如下兩個方法:

def login(self, username, password):
    return self.app.post('/login', data=dict(
        username = username,
        password = password
    ), follow_redirects=True)
    
def logout(self):
    return self.app.get('/logout', follow_redirects=True)
    

現(xiàn)在我們可以輕松地測試登陸和退出的功能郭怪,并且,對于無用的數(shù)據(jù)刊橘,會顯示失敗鄙才。
現(xiàn)在把新的測試添加到類中:

def test_login_logout(self):
    rv = self.login('admin', 'default')
    assert b'You were logged in' in rv.data
    rv = self.logout()
    assert b'You were logged out' in rv.data
    rv = self.login('adminx', 'default')
    assert b'Invalid username' in rv.data
    rv = self.login('admin', 'defaultx')
    assert b'Invalid passward' in rv.data

添加消息測試

我們還應(yīng)該測試添加消息是否有效。像下面這樣添加一個測試方法:

def test_message(self):
    self.login('admin', 'default')
    rv = self.app.post('/add', data=dict(
        title = '<Hello>',
        text = '<strong>HTML</strong> allowed here'
    ), follow_redirects=True)
    assert b'No entries here so far' not in rv.data
    assert b'< Hello>' in rv.data
    assert b'<strong>HTML</strong> allowed here' in rv.data

這里我們測試HTML可以存在于文本中促绵,但是不能在標(biāo)題中攒庵,這是intended behavior.
運行測試,我們得到3個測試成功的結(jié)果:

python flaskr_tests.py
...
---------------------------------
Ran 3 tests in 0.332s

OK

如果想測試更多關(guān)于返回頭败晴,和返回狀態(tài)浓冒,請查看MiniTwit Example
包含了許多測試套件。

其他一些測試技巧

除了上面介紹的用戶測試以外尖坤,還有另外一種測試方法稳懒,使用test_request_context()方法和with語句
一起進(jìn)行測試,以適當(dāng)?shù)姆椒せ钫埱舐丁_@種方法可以使你獲得request,g,session對象场梆,就像在試圖函數(shù)中
一樣。這是一個充分演示這種方法的例子:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纯路,一起剝皮案震驚了整個濱河市辙谜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌感昼,老刑警劉巖装哆,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異定嗓,居然都是意外死亡蜕琴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門宵溅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凌简,“玉大人,你說我怎么就攤上這事恃逻〕В” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵寇损,是天一觀的道長凸郑。 經(jīng)常有香客問我,道長矛市,這世上最難降的妖魔是什么芙沥? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上而昨,老公的妹妹穿的比我還像新娘救氯。我一直安慰自己,他們只是感情好歌憨,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布着憨。 她就那樣靜靜地躺著,像睡著了一般务嫡。 火紅的嫁衣襯著肌膚如雪享扔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天植袍,我揣著相機(jī)與錄音惧眠,去河邊找鬼。 笑死于个,一個胖子當(dāng)著我的面吹牛氛魁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厅篓,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼秀存,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羽氮?” 一聲冷哼從身側(cè)響起或链,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎档押,沒想到半個月后澳盐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡令宿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年叼耙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粒没。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡筛婉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出癞松,到底是詐尸還是另有隱情爽撒,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布响蓉,位于F島的核電站硕勿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏厕妖。R本人自食惡果不足惜首尼,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望言秸。 院中可真熱鬧软能,春花似錦、人聲如沸举畸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抄沮。三九已至跋核,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間叛买,已是汗流浹背砂代。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留率挣,地道東北人刻伊。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像椒功,于是被迫代替她去往敵國和親捶箱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理动漾,服務(wù)發(fā)現(xiàn)丁屎,斷路器,智...
    卡卡羅2017閱讀 134,600評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,519評論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法旱眯,類相關(guān)的語法晨川,內(nèi)部類的語法,繼承相關(guān)的語法删豺,異常的語法础爬,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • 一紙書來只為墻赔桌,讓他三尺又何妨供炎。長城萬里今猶在,不見當(dāng)年秦始皇疾党!想清代康熙年間的張英是用何等胸懷包容他們老家的鄰居...
    紅袖添香0615閱讀 821評論 1 2
  • 不知道你是不是也有這樣的感受: 那些我們曾以為會一直走下去的朋友,突然在某天、某個十字路香罐,你向左我向右卧波,越走越遠(yuǎn)!...
    小淘米_TTMIX閱讀 185評論 0 0