前言  xv
         準備工作和應具備的知識  xxi
         緻謝  xxvii
         第一部分 TDD 和Django 基礎
         第1章 使用功能測試協助安裝Django  3
         1.1 遵從測試山羊的教誨,沒有測試什麼也彆做  3
         1.2 讓Django運行起來  6
         1.3 創建Git倉庫  7
         第2章 使用unittest模塊擴展功能測試  11
         2.1 使用功能測試驅動開發一個最簡可用的應用  11
         2.2 Python標準庫中的unittest模塊  14
         2.3 隱式等待  16
         2.4 提交  16
         第3章 使用單元測試測試簡單的首頁  18
         3.1 第一個Django應用,第一個單元測試  19
         3.2 單元測試及其與功能測試的區彆  19
         3.3 Django中的單元測試  20
         3.4 Django中的MVC、URL 和視圖函數  21
         3.5 終於可以編寫一些應用代碼瞭  22
         3.6 urls.py  24
         3.7 為視圖編寫單元測試  27
         第4章 編寫這些測試有什麼用  31
         4.1 編程就像從井裏打水  31
         4.2 使用Selenium測試用戶交互  33
         4.3 遵守“不測試常量”規則,使用模闆解決這個問題  35
         4.4 關於重構  39
         4.5 接著修改首頁  40
         4.6 總結:TDD流程  42
         第5章 保存用戶輸入  45
         5.1 編寫錶單,發送POST請求  45
         5.2 在服務器中處理POST請求  48
         5.3 把Python變量傳入模闆中渲染  49
         5.4 事不過三,三則重構  53
         5.5 Django ORM和第一個模型  54
         5.5.1 第一個數據庫遷移  56
         5.5.2 測試嚮前走得挺遠  57
         5.5.3 添加新字段就要創建新遷移  57
         5.6 把POST請求中的數據存入數據庫  58
         5.7 處理完POST請求後重定嚮  61
         5.8 在模闆中渲染待辦事項  63
         5.9 使用遷移創建生産數據庫  65
         第6章 完成最簡可用的網站  70
         6.1 確保功能測試之間相互隔離  70
         6.2 必要時做少量的設計  74
         6.2.1 YAGNI  74
         6.2.2 REST  75
         6.3 使用TDD 實現新設計  76
         6.4 逐步迭代,實現新設計  78
         6.5 使用Django測試客戶端一起測試視圖、模闆和URL  80
         6.5.1 一個新測試類  80
         6.5.2 一個新URL  81
         6.5.3 一個新視圖函數  81
         6.5.4 一個新模闆,用於查看清單  82
         6.6 用於添加待辦事項的URL和視圖  85
         6.6.1 用來測試新建清單的測試類  85
         6.6.2 用於新建清單的URL和視圖  86
         6.6.3 刪除當前多餘的代碼和測試  88
         6.6.4 讓錶單指嚮剛添加的新URL  88
         6.7 調整模型  89
         6.7.1 通過外鍵實現的關聯  91
         6.7.2 根據新模型定義調整其他代碼  92
         6.8 每個列錶都應該有自己的URL  94
         6.8.1 捕獲URL中的參數  95
         6.8.2 按照新設計調整new_list視圖  96
         6.9 還需要一個視圖,把待辦事項加入現有清單  97
         6.9.1 小心霸道的正則錶達式  98
         6.9.2 最後一個新URL  98
         6.9.3 最後一個新視圖  99
         6.9.4 如何在錶單中使用那個URL  100
         6.10 使用URL 引入做最後一次重構  102
         第二部分 Web開發要素
         第7章 美化網站:布局、樣式及其測試方法  106
         7.1 如何在功能測試中測試布局和樣式  106
         7.2 使用CSS框架美化網站  109
         7.3 Django模闆繼承  111
         7.4 集成Bootstrap  112
         7.5 Django中的靜態文件  114
         7.6 使用Bootstrap中的組件改進網站外觀  116
         7.6.1 超大文本塊  116
         7.6.2 大型輸入框  116
         7.6.3 樣式化錶格  117
         7.7 使用自己編寫的CSS  117
         7.8 補遺:collectstatic命令和其他靜態目錄  118
         7.9 沒談到的話題  121
         第8章 使用過渡網站測試部署  122
         8.1 TDD以及部署的危險區域  123
         8.2 一如既往,先寫測試  124
         8.3 注冊域名  126
         8.4 手動配置托管網站的服務器  126
         8.4.1 選擇在哪裏托管網站  127
         8.4.2 搭建服務器  127
         8.4.3 用戶賬戶、SSH和權限  128
         8.4.4 安裝Nginx  128
         8.4.5 解析過渡環境和綫上環境所用的域名  129
         8.4.6 使用功能測試確認域名可用而且Nginx正在運行  130
         8.5 手動部署代碼  130
         8.5.1 調整數據庫的位置  131
         8.5.2 創建虛擬環境  133
         8.5.3 簡單配置Nginx  135
         8.5.4 使用遷移創建數據庫  137
         8.6 為部署到生産環境做好準備  138
         8.6.1 換用Gunicorn  138
         8.6.2 讓Nginx伺服靜態文件  139
         8.6.3 換用Unix套接字  140
         8.6.4 把DEBUG設為False,設置ALLOWED_HOSTS  141
         8.6.5 使用Upstart確保引導時啓動Gunicorn  141
         8.6.6 保存改動:把Gunicorn 添加到requirements.txt  142
         8.7 自動化  143
         第9章 使用Fabric自動部署  147
         9.1 分析一個Fabric部署腳本  148
         9.2 試用部署腳本  151
         9.2.1 部署到綫上服務器  153
         9.2.2 使用sed配置Nginx 和Gunicorn  155
         9.3 使用Git標簽標注發布狀態  155
         9.4 延伸閱讀  156
         第10章 輸入驗證和測試的組織方式  158
         10.1 針對驗證的功能測試:避免提交空待辦事項  158
         10.1.1 跳過測試  159
         10.1.2 把功能測試分拆到多個文件中  160
         10.1.3 運行單個測試文件  162
         10.1.4 填充功能測試  163
         10.2 使用模型層驗證  164
         10.2.1 重構單元測試,分拆成多個文件  164
         10.2.2 模型驗證的單元測試和self.assertRaises上下文管理器  165
         10.2.3 Django怪異的錶現:保存時不驗證數據  166
         10.3 在視圖中顯示模型驗證錯誤  167
         10.4 Django模式:在渲染錶單的視圖中處理POST 請求  171
         10.4.1 重構:把new_item實現的功能移到view_list 中  172
         10.4.2 在view_list 視圖中執行模型驗證  174
         10.5 重構:去除硬編碼的URL  176
         10.5.1 模闆標簽{% url %}  176
         10.5.2 重定嚮時使用get_absolute_url  177
         第11章 簡單的錶單  181
         11.1 把驗證邏輯移到錶單中  181
         11.1.1 使用單元測試探索錶單API  182
         11.1.2 換用Django中的ModelForm類  183
         11.1.3 測試和定製錶單驗證  184
         11.2 在視圖中使用這個錶單  186
         11.2.1 在處理GET請求的視圖中使用這個錶單  187
         11.2.2 大量查找和替換  189
         11.3 在處理POST請求的視圖中使用這個錶單  191
         11.3.1 修改new_list視圖的單元測試  191
         11.3.2 在視圖中使用這個錶單  192
         11.3.3 使用這個錶單在模闆中顯示錯誤消息  193
         11.4 在其他視圖中使用這個錶單  194
         11.5 使用錶單自帶的save方法  196
         第12章 高級錶單  199
         12.1 針對重復待辦事項的功能測試  199
         12.1.1 在模型層禁止重復  200
         12.1.2 題外話:查詢集閤排序和字符串錶示形式  202
         12.1.3 重寫舊模型測試  204
         12.1.4 保存時確實會顯示完整性錯誤  205
         12.2 在視圖層試驗待辦事項重復驗證  206
         12.3 處理唯一性驗證的復雜錶單  207
         12.4 在清單視圖中使用ExistingListItemForm  209
         第13章 試探JavaScript  213
         13.1 從功能測試開始  213
         13.2 安裝一個基本的JavaScript 測試運行程序  214
         13.3 使用jQuery 和<div>固件元素  217
         13.4 為想要實現的功能編寫JavaScript單元測試  219
         13.5 JavaScript測試在TDD循環中的位置  221
         13.6 經驗做法:onload樣闆代碼和命名空間  222
         13.7 一些缺憾  223
         第14章 部署新代碼  224
         14.1 部署到過渡服務器  224
         14.2 部署到綫上服務器  225
         14.3 如果看到數據庫錯誤該怎麼辦  225
         14.4 總結:為這次新發布打上Git 標簽  225
         第三部分 高級話題
         第15章 用戶認證、集成第三方插件以及JavaScript模擬技術的使用  228
         15.1 Mozilla Persona(BrowserID)  229
         15.2 探索性編程(又名“探究”)  229
         15.2.1 為此次探究新建一個分支  230
         15.2.2 前端和JavaScript代碼  230
         15.2.3 Browser-ID協議  231
         15.2.4 服務器端:自定義認證機製  232
         15.3 去掉探究代碼  237
         15.3.1 常用Selenium技術:顯式等待  240
         15.3.2 刪除探究代碼  241
         15.4 涉及外部組件的JavaScript單元測試:首次使用模擬技術  242
         15.4.1 整理:全站共用的靜態文件夾  242
         15.4.2 什麼是模擬技術,為什麼要模擬,模擬什麼  244
         15.4.3 命名空間  244
         15.4.4 在initialize函數的單元測試中使用一個簡單的馭件  245
         15.4.5 高級模擬技術  250
         15.4.6 檢查參數的調用  253
         15.4.7 QUnit 中的setup和teardown函數,以及Ajax請求測試  255
         15.4.8 深層嵌套迴調函數和測試異步代碼  259
         第16章 服務器端認證,在Python中使用模擬技術  262
         16.1 探究登錄視圖  262
         16.2 在Python代碼中使用模擬技術  263
         16.2.1 通過模擬authenticate函數測試視圖  263
         16.2.2 確認視圖確實登錄瞭用戶  266
         16.3 模擬網絡請求,去除自定義認證後颱中的探究代碼  270
         16.3.1 一個if 語句需要一個測試  270
         16.3.2 在類上使用patch修飾器  272
         16.3.3 進行布爾值比較時要留意馭件  275
         16.3.4 需要時創建用戶  276
         16.3.5 get_user方法  277
         16.4 一個最簡單的自定義用戶模型  279
         16.4.1 稍微有點兒失望  280
         16.4.2 把測試當作文檔  281
         16.4.3 用戶已經通過認證  282
         16.5 關鍵時刻:功能測試能通過嗎  283
         16.6 完善功能測試,測試退齣功能  284
         第17章 測試固件、日誌和服務器端調試  287
         17.1 事先創建好會話,跳過登錄過程  287
         17.2 實踐是檢驗真理的唯一標準:在過渡服務器中捕獲最後的問題  290
         17.2.1 設置日誌  291
         17.2.2 修正Persona引起的這個問題  293
         17.3 在過渡服務器中管理測試數據庫  295
         17.3.1 創建會話的Django管理命令  295
         17.3.2 讓功能測試在服務器上運行管理命令  296
         17.3.3 使用subprocess模塊完成額外的工作  298
         17.4 集成日誌相關的代碼  301
         17.5 小結  304
         第18章 完成“My Lists”頁麵:由外而內的TDD  305
         18.1 對立技術:“由內而外”  305
         18.2 為什麼選擇使用“由外而內”  306
         18.3 “My Lists”頁麵的功能測試  306
         18.4 外層:錶現層和模闆  307
         18.5 下移一層到視圖函數(控製器)  308
         18.6 使用由外而內技術,再讓一個測試通過  309
         18.6.1 快速重組模闆的繼承層級  309
         18.6.2 使用模闆設計API  310
         18.6.3 移到下一層:視圖嚮模闆中傳入什麼  311
         18.7 視圖層的下一個需求:新建清單時應該記錄屬主  312
         18.8 下移到模型層  313
         第19章 測試隔離和“傾聽測試的心聲”  318
         19.1 重溫抉擇時刻:視圖層依賴於尚未編寫的模型代碼  318
         19.2 首先嘗試使用馭件實現隔離  319
         19.3 傾聽測試的心聲:醜陋的測試錶明需要重構  322
         19.4 以完全隔離的方式重寫視圖測試  323
         19.4.1 為瞭新測試的健全性,保留之前的整閤測試組件  323
         19.4.2 完全隔離的新測試組件  324
         19.4.3 站在協作者的角度思考問題  324
         19.5 下移到錶單層  328
         19.6 下移到模型層  332
         19.7 關鍵時刻,以及使用模擬技術的風險  335
         19.8 把層與層之間的交互當作“閤約”  336
         19.8.1 找齣隱形閤約  337
         19.8.2 修正由於疏忽導緻的問題  338
         19.9 還缺一個測試  340
         19.10 清理:保留哪些整閤測試  340
         19.10.1 刪除錶單層多餘的代碼  340
         19.10.2 刪除以前實現的視圖  341
         19.10.3 刪除視圖層多餘的代碼  342
         19.11 總結:什麼時候編寫隔離測試,什麼時候編寫整閤測試  343
         19.11.1 以復雜度為準則  344
         19.11.2 兩種測試都要寫嗎  344
         19.11.3 繼續前行  345
         第20章 持續集成  346
         20.1 安裝Jenkins  346
         20.1.1 Jenkins的安全配置  348
         20.1.2 添加需要的插件  348
         20.2 設置項目  350
         20.3 第一次構建  351
         20.4 設置虛擬顯示器,讓功能測試能在無界麵的環境中運行  353
         20.5 截圖  355
         20.6 一個常見的Selenium問題:條件競爭  358
         20.7 使用PhantomJS運行QUnit JavaScript測試  361
         20.7.1 安裝node  361
         20.7.2 在Jenkins中添加構建步驟  362
         20.8 CI 服務器能完成的其他操作  364
         第21章 簡單的社會化功能、頁麵模式,以及練習  365
         21.1 有多個用戶以及使用addCleanup 的功能測試  365
         21.2 實現Selenium交互等待模式  367
         21.3 頁麵模式  368
         21.4 擴展功能測試測試第二個用戶和“My Lists”頁麵  371
         21.5 留給讀者的練習  373
         第22章 測試運行速度的快慢和熾熱的岩漿  375
         22.1 正題:單元測試除瞭運行速度超快之外還有其他優勢  376
         22.1.1 測試運行得越快,開發速度越快  376
         22.1.2 神賜的心流狀態  377
         22.1.3 速度慢的測試經常不想運行,導緻代碼變壞  377
         22.1.4 現在還行,不過隨著時間推移,整閤測試會變得越來越慢  377
         22.1.5 彆隻聽我一個人說  377
         22.1.6 單元測試能驅使我們實現好的設計  377
         22.2 純粹的單元測試有什麼問題  378
         22.2.1 隔離的測試難讀也難寫  378
         22.2.2 隔離測試不會自動測試集成情況  378
         22.2.3 單元測試幾乎不能捕獲意料之外的問題  378
         22.2.4 使用馭件的測試可能和實現方式聯係緊密  378
         22.2.5 這些問題都可以解決  379
         22.3 閤題:我們到底想從測試中得到什麼  379
         22.3.1 正確性  379
         22.3.2 簡潔可維護的代碼  379
         22.3.3 高效的工作流程  379
         22.3.4 根據所需的優勢評估測試  379
         22.4 架構方案  380
         22.4.1 端口和適配器(或六邊形、簡潔)架構  380
         22.4.2 函數式核心,命令式外殼  381
         22.5 小結  381
         遵從測試山羊的教誨  383
         附錄A PythonAnywhere  385
         附錄B 基於類的Django 視圖  388
         附錄C 使用Ansible配置服務器  398
         附錄D 測試數據庫遷移  402
         附錄E 接下來做什麼  407
         附錄F 速查錶  411
         附錄G 參考書目  415
         作者簡介  416
         封麵介紹  416
      · · · · · ·     (
收起)