Django中的csrf_token和單元測試

1、前言#####

最近在學習django仇味,使用的書是《Python Web開發(fā) 測試驅動方法》硫惕,在第四章中遇到了一個問題使用render_to_string()函數(shù)。學習過程中使用的是py2敞斋,Django的版本是1.10.1截汪。

2、問題描述#####

第四章的單元測試部分代碼:

class HomePageTest(TestCase):
    [...]
    def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)
        expected_html = render_to_string('home.html')
        self.assertEqual(response.content.decode(), expected_html)
    [...]

在沒有在表單中加入CSRF令牌{% csrf_token %}時植捎,運行都是正常的衙解。

I:\Django_learn\superlists>python manage.py test
Creating test database for alias 'default'...
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK
Destroying test database for alias 'default'...

I:\Django_learn\superlists>

現(xiàn)在在home.html中加入CSRF令牌{% csrf_token %}后。

<html>
<head>
    <title>To-Do lists</title>
</head>
<body>
    <h1>Your To-Do lists</h1>
    <form method="POST">
        <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
        {% csrf_token %}
    </form>
    <table id="id_list_table">
        <tr><td>{{ new_item_text }}</td></tr>
        </table>
</body>
</html>

再次運行單元測試

I:\Django_learn\superlists>python manage.py test
Creating test database for alias 'default'...
.F.
======================================================================
FAIL: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "I:\Django_learn\superlists\lists\tests.py", line 28, in test_home_page_returns_correct_html
    self.assertEqual(response.content.decode(), expected_html)
AssertionError: u'<html>\n<head>\n    <title>To-Do lists</title>\n</head>\n<body>\n    <h1>Your To-Do lists</h1>\n    <form method="POST">\n        <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>\n        <input type=\'hidden\' name=\'csrfmiddlewaretoken\' value=\'WkE5AMVHQu5oVmJ6wFSU2KjMvXV6yGYwsB3IJ0Too0QM4xXKVPj6BJ24DBLP600v\' />\n    </form>\n    <table id="id_list_table">\n        <tr><td></td></tr>\n        </table>\n</body>\n</html>\n' != u'<html>\n<head>\n    <title>To-Do lists</title>\n</head>\n<body>\n    <h1>Your To-Do lists</h1>\n    <form method="POST">\n        <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>\n        \n    </form>\n    <table id="id_list_table">\n        <tr><td></td></tr>\n        </table>\n</body>\n</html>\n'

----------------------------------------------------------------------
Ran 3 tests in 0.047s

FAILED (failures=1)
Destroying test database for alias 'default'...

根據(jù)錯誤信息可以知道在最后的斷言self.assertEqual(response.content.decode(), expected_html)導致測試失敗焰枢。
我們添加兩行用于調試蚓峦,打印出response.content.decode()和expected_html.

   print 'response.content.decode()\n', response.content.decode()
   print 'expected_html\n', expected_html
I:\Django_learn\superlists>python manage.py test
Creating test database for alias 'default'...
.response.content.decode()
<html>
<head>
    <title>To-Do lists</title>
</head>
<body>
    <h1>Your To-Do lists</h1>
    <form method="POST">
        <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>
        <input type='hidden' name='csrfmiddlewaretoken' value='VUMXA6dNnUT8Y2rAY3nAcQyTMtJKGznXqts0HbPaDWN16b4uiMDkFMWp1EVbC3xu' />
    </form>
    <table id="id_list_table">
        <tr><td></td></tr>
        </table>
</body>
</html>

expected_html
<html>
<head>
    <title>To-Do lists</title>
</head>
<body>
    <h1>Your To-Do lists</h1>
    <form method="POST">
        <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/>

    </form>
    <table id="id_list_table">
        <tr><td></td></tr>
        </table>
</body>
</html>

..
----------------------------------------------------------------------
Ran 3 tests in 0.031s

OK
Destroying test database for alias 'default'...

I:\Django_learn\superlists>

在渲染模板時,Django 會把這個模板標簽替換成一個<input type="hidden">元素,其值是CSRF 令牌济锄。
從上面的html代碼可以看出暑椰,通過視圖函數(shù)home_page()渲染得到的響應包含csrf轉換的<input>元素,而render_to_string()則未生成該部分荐绝,所以導致測試失敗一汽。

3、如何解決#####

經過google低滩,在stackoverflow找到了解決辦法召夹。
按照stackoverflow上的解決辦法(當前djano==1.10.1)岩喷,我使用expected_html = render_to_string('home.html', request=request)和render_to_string('index.html', context_instance=RequestContext(request))仍然會報錯,于是將自己django版本降低到1.8后使用expected_html = render_to_string('home.html', request=request)监憎,測試通過纱意。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市枫虏,隨后出現(xiàn)的幾起案子妇穴,更是在濱河造成了極大的恐慌,老刑警劉巖隶债,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腾它,死亡現(xiàn)場離奇詭異,居然都是意外死亡死讹,警方通過查閱死者的電腦和手機瞒滴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赞警,“玉大人妓忍,你說我怎么就攤上這事±⒌” “怎么了世剖?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長笤虫。 經常有香客問我旁瘫,道長,這世上最難降的妖魔是什么琼蚯? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任酬凳,我火速辦了婚禮,結果婚禮上遭庶,老公的妹妹穿的比我還像新娘宁仔。我一直安慰自己,他們只是感情好峦睡,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布翎苫。 她就那樣靜靜地躺著,像睡著了一般赐俗。 火紅的嫁衣襯著肌膚如雪拉队。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天阻逮,我揣著相機與錄音粱快,去河邊找鬼。 笑死,一個胖子當著我的面吹牛事哭,可吹牛的內容都是我干的漫雷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鳍咱,長吁一口氣:“原來是場噩夢啊……” “哼降盹!你這毒婦竟也來了?” 一聲冷哼從身側響起谤辜,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤蓄坏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丑念,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涡戳,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年脯倚,在試婚紗的時候發(fā)現(xiàn)自己被綠了渔彰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡推正,死狀恐怖恍涂,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情植榕,我是刑警寧澤再沧,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站尊残,受9級特大地震影響产园,放射性物質發(fā)生泄漏。R本人自食惡果不足惜夜郁,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粘勒。 院中可真熱鬧竞端,春花似錦、人聲如沸庙睡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乘陪。三九已至统台,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啡邑,已是汗流浹背贱勃。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贵扰。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓仇穗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戚绕。 傳聞我的和親對象是個殘疾皇子纹坐,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容

  • 在《Python Web開發(fā):測試驅動方法》一書中作者使用的 Django 版本是 1.7,而我使用的是1.9.7...
    潘澤彥閱讀 870評論 -1 0
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理舞丛,服務發(fā)現(xiàn)耘子,斷路器,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 此段內容簡要來自自強學堂的教程詳情請查詢自強學堂 一球切、 后臺的運作流程 接收request請求 處理數(shù)據(jù) 獲取請求...
    coder_ben閱讀 5,246評論 6 56
  • 已經同步到gitbook谷誓,想閱讀的請轉到gitbook: Django 1.10 中文文檔 Writing you...
    leyu閱讀 534評論 0 0
  • (一)、啟動服務器 (二)欧聘、創(chuàng)建數(shù)據(jù)庫表 或 更改數(shù)據(jù)庫表或字段 Django 1.7.1及以上 用以下命令 1....
    夏天夏星閱讀 5,658評論 0 17