前言 xv
準備工作和應具備的知識 xxi
配套視頻 xxviii
緻謝 xxix
第一部分 TDD和Django基礎
第1章 使用功能測試協助安裝Django 2
1.1 遵從測試山羊的教誨,沒有測試什麼也彆做 2
1.2 讓Django運行起來 4
1.3 創建Git倉庫 6
第2章 使用unittest模塊擴展功能測試 10
2.1 使用功能測試驅動開發一個最簡可用的應用 10
2.2 Python標準庫中的unittest模塊 12
2.3 提交 14
第3章 使用單元測試測試簡單的首頁 16
3.1 第一個Django應用,第一個單元測試 16
3.2 單元測試及其與功能測試的區彆 17
3.3 Django中的單元測試 18
3.4 Django中的MVC、URL和視圖函數 19
3.5 終於可以編寫一些應用代碼瞭 20
3.6 urls.py 22
3.7 為視圖編寫單元測試 23
第4章 測試(及重構)的目的 28
4.1 編程就像從井裏打水 28
4.2 使用Selenium測試用戶交互 30
4.3 遵守“不測試常量”規則,使用模闆解決這個問題 32
4.3.1 使用模闆重構 33
4.3.2 Django測試客戶端 35
4.4 關於重構 37
4.5 接著修改首頁 38
4.6 總結:TDD流程 39
第5章 保存用戶輸入:測試數據庫 42
5.1 編寫錶單,發送POST請求 42
5.2 在服務器中處理POST請求 45
5.3 把Python變量傳入模闆中渲染 46
5.4 事不過三,三則重構 50
5.5 Django ORM和第一個模型 51
5.5.1 第一個數據庫遷移 53
5.5.2 測試嚮前走得挺遠 53
5.5.3 添加新字段就要創建新遷移 54
5.6 把POST請求中的數據存入數據庫 55
5.7 處理完POST請求後重定嚮 57
5.8 在模闆中渲染待辦事項 59
5.9 使用遷移創建生産數據庫 61
5.10 迴顧 64
第6章 改進功能測試:確保隔離,去掉含糊的休眠 66
6.1 確保功能測試之間相互隔離 66
6.2 升級Selenium和Geckodriver 70
6.3 隱式等待、顯式等待和含糊的time.sleep 70
第7章 步步為營 75
7.1 必要時做少量的設計 75
7.1.1 不要預先做大量設計 75
7.1.2 YAGNI 76
7.1.3 REST(式) 76
7.2 使用TDD實現新設計 77
7.3 確保齣現迴歸測試 78
7.4 逐步迭代,實現新設計 80
7.5 自成一體的第一步:新的URL 81
7.5.1 一個新URL 82
7.5.2 一個新視圖函數 82
7.6 變綠瞭嗎?該重構瞭 84
7.7 再邁一小步:一個新模闆,用於查看清單 84
7.8 第三小步:用於添加待辦事項的URL 86
7.8.1 用來測試新建清單的測試類 87
7.8.2 用於新建清單的URL和視圖 88
7.8.3 刪除當前多餘的代碼和測試 89
7.8.4 齣現迴歸!讓錶單指嚮剛添加的新URL 89
7.9 下定決心,調整模型 90
7.9.1 外鍵關係 92
7.9.2 根據新模型定義調整其他代碼 93
7.10 每個列錶都應該有自己的URL 95
7.10.1 捕獲URL中的參數 96
7.10.2 按照新設計調整new_list視圖 97
7.11 功能測試又檢測到迴歸 98
7.12 還需要一個視圖,把待辦事項加入現有清單 99
7.12.1 小心霸道的正則錶達式 99
7.12.2 最後一個新URL 100
7.12.3 最後一個新視圖 101
7.12.4 直接測試響應上下文對象 102
7.13 使用URL引入做最後一次重構 103
第二部分 Web 開發要素
第8章 美化網站:布局、樣式及其測試方法 108
8.1 如何在功能測試中測試布局和樣式 108
8.2 使用CSS框架美化網站 111
8.3 Django模闆繼承 112
8.4 集成Bootstrap 114
8.5 Django中的靜態文件 115
8.6 使用Bootstrap中的組件改進網站外觀 117
8.6.1 超大文本塊 118
8.6.2 大型輸入框 118
8.6.3 樣式化錶格 118
8.7 使用自己編寫的CSS 118
8.8 補遺:collectstatic命令和其他靜態目錄 120
8.9 沒談到的話題 122
第9章 使用過渡網站測試部署 123
9.1 TDD以及部署的危險區域 124
9.2 一如既往,先寫測試 125
9.3 注冊域名 127
9.4 手動配置托管網站的服務器 127
9.4.1 選擇在哪裏托管網站 127
9.4.2 搭建服務器 128
9.4.3 用戶賬戶、SSH和權限 128
9.4.4 安裝Nginx 128
9.4.5 安裝Python 3.6 129
9.4.6 解析過渡環境和綫上環境所用的域名 130
9.4.7 使用功能測試確認域名可用而且Nginx正在運行 130
9.5 手動部署代碼 130
9.5.1 調整數據庫的位置 131
9.5.2 手動創建虛擬環境,使用requirements.txt 133
9.5.3 簡單配置Nginx 134
9.5.4 使用遷移創建數據庫 136
9.6 手動部署大功告成 137
第10章 為部署到生産環境做好準備 139
10.1 換用Gunicorn 139
10.2 讓Nginx伺服靜態文件 140
10.3 換用Unix套接字 141
10.4 把DEBUG設為False,設置ALLOWED_HOSTS 142
10.5 使用Systemd確保引導時啓動Gunicorn 143
10.6 考慮自動化 144
10.7 保存進度 147
第11章 使用Fabric自動部署 148
11.1 分析一個Fabric部署腳本 149
11.1.1 分析一個Fabric部署腳本 149
11.1.2 使用Git拉取源碼 150
11.1.3 更新settings.py 151
11.1.4 更新虛擬環境 151
11.1.5 需要時遷移數據庫 152
11.2 試用部署腳本 152
11.2.1 部署到綫上服務器 154
11.2.2 使用sed配置Nginx和Gunicorn 155
11.3 使用Git標簽標注發布狀態 157
11.4 延伸閱讀 157
第12章 輸入驗證和測試的組織方式 159
12.1 針對驗證的功能測試:避免提交空待辦事項 159
12.1.1 跳過測試 160
12.1.2 把功能測試分拆到多個文件中 161
12.1.3 運行單個測試文件 163
12.2 功能測試新工具:通用顯式等待輔助方法 164
12.3 補完功能測試 167
12.4 重構單元測試,分拆成多個文件 168
第13章 數據庫層驗證 171
13.1 模型層驗證 172
13.1.1 self.assertRaises上下文管理器 172
13.1.2 Django怪異的錶現:保存時不驗證數據 173
13.2 在視圖中顯示模型驗證錯誤 173
13.3 Django模式:在渲染錶單的視圖中處理POST請求 177
13.3.1 重構:把new_item實現的功能移到view_list中 178
13.3.2 在view_list視圖中執行模型驗證 180
13.4 重構:去除硬編碼的URL 182
13.4.1 模闆標簽{% url %} 182
13.4.2 重定嚮時使用get_absolute_url 183
第14章 簡單的錶單 186
14.1 把驗證邏輯移到錶單中 186
14.1.1 使用單元測試探索錶單API 187
14.1.2 換用Django中的ModelForm類 188
14.1.3 測試和定製錶單驗證 189
14.2 在視圖中使用這個錶單 191
14.2.1 在處理GET請求的視圖中使用這個錶單 191
14.2.2 大量查找和替換 192
14.3 在處理POST請求的視圖中使用這個錶單 194
14.3.1 修改new_list視圖的單元測試 195
14.3.2 在視圖中使用這個錶單 196
14.3.3 使用這個錶單在模闆中顯示錯誤消息 196
14.4 在其他視圖中使用這個錶單 197
14.4.1 定義輔助方法,簡化測試 197
14.4.2 意想不到的好處:HTML5自帶的客戶端驗證 199
14.5 值得鼓勵 201
14.6 這難道不是浪費時間嗎 201
14.7 使用錶單自帶的save方法 202
第15章 高級錶單 205
15.1 針對重復待辦事項的功能測試 205
15.1.1 在模型層禁止重復 206
15.1.2 題外話:查詢集閤排序和字符串錶示形式 208
15.1.3 重寫舊模型測試 210
15.1.4 保存時確實會顯示完整性錯誤 211
15.2 在視圖層試驗待辦事項重復驗證 212
15.3 處理唯一性驗證的復雜錶單 213
15.4 在清單視圖中使用ExistingListItemForm 215
15.5 小結:目前所學的Django測試知識 217
第16章 試探JavaScript 219
16.1 從功能測試開始 219
16.2 安裝一個基本的JavaScript測試運行程序 221
16.3 使用jQuery和固件元素 223
16.4 為想要實現的功能編寫JavaScript單元測試 225
16.5 固件、執行順序和全局狀態:JavaScript測試的重大挑戰 227
16.5.1 使用console.log打印調試信息 227
16.5.2 使用初始化函數精確控製執行時 229
16.6 經驗做法:onload樣闆代碼和命名空間 230
16.7 JavaScript測試在TDD循環中的位置 232
16.8 一些缺憾 232
第17章 部署新代碼 234
17.1 部署到過渡服務器 234
17.2 部署到綫上服務器 235
17.3 如果看到數據庫錯誤該怎麼辦 235
17.4 總結:為這次新發布打上Git標簽 235
第三部分 高級話題
第18章 用戶身份驗證、探究及去掉探究代碼 238
18.1 無密碼驗證 238
18.2 探索性編程(又名“探究”) 239
18.2.1 為此次探究新建一個分支 239
18.2.2 前端登錄UI 240
18.2.3 從Django中發齣郵件 240
18.2.4 使用環境變量,避免源碼中齣現機密信息 242
18.2.5 在數據庫中存儲令牌 243
18.2.6 自定義身份驗證模型 243
18.2.7 結束自定義Django身份驗證功能 224
18.3 去掉探究代碼 248
18.4 一個極簡的自定義用戶模型 251
18.5 令牌模型:把電子郵件地址與唯一的ID關聯起來 254
第19章 使用馭件測試外部依賴或減少重復 257
19.1 開始之前布好基本管道 257
19.2 自己動手模擬(打猴子補丁) 258
19.3 Python的模擬庫 261
19.3.1 使用unittest.patch 261
19.3.2 讓測試嚮前邁一小步 263
19.3.3 測試Django消息框架 263
19.3.4 在HTML中添加消息 265
19.3.5 構建登錄URL 266
19.3.6 確認給用戶發送瞭帶有令牌的鏈接 267
19.4 去除自定義的身份驗證後端中的探究代碼 269
19.4.1 一個if語句需要一個測試 269
19.4.2 get_user方法 272
19.4.3 在登錄視圖中使用自定義的驗證後端 273
19.5 使用馭件的另一個原因:減少重復 274
19.5.1 使用馭件的返迴值 277
19.5.2 在類一級上打補丁 278
19.6 關鍵時刻:功能測試能通過嗎 279
19.7 理論上正常,那麼實際呢 281
19.8 完善功能測試,測試退齣功能 283
第20章 測試固件和一個顯式等待裝飾器 285
20.1 事先創建好會話,跳過登錄過程 285
20.2 顯式等待輔助方法最終版:wait裝飾器 290
第21章 服務器端調試技術 293
21.1 實踐是檢驗真理的唯一標準:在過渡服務器中捕獲最後的問題 293
21.2 在服務器上通過環境變量設定機密信息 295
21.3 調整功能測試,以便通過POP3測試真實的電子郵件 296
21.4 在過渡服務器中管理測試數據庫 299
21.4.1 創建會話的Django管理命令 300
21.4.2 讓功能測試在服務器上運行管理命令 301
21.4.3 直接在Python代碼中使用Fabric 302
21.4.4 迴顧:在本地服務器和過渡服務器中創建會話的方式 303
21.5 集成日誌相關的代碼 304
21.6 小結 305
第22章 完成“My Lists”頁麵:由外而內的TDD 306
22.1 對立技術:“由內而外” 306
22.2 為什麼選擇使用“由外而內” 307
22.3 “My Lists”頁麵的功能測試 307
22.4 外層:錶現層和模闆 309
22.5 下移一層到視圖函數(控製器) 309
22.6 使用由外而內技術,再讓一個測試通過 310
22.6.1 快速重組模闆的繼承層級 311
22.6.2 使用模闆設計API 311
22.6.3 移到下一層:視圖嚮模闆中傳入什麼 313
22.7 視圖層的下一個需求:新建清單時應該記錄屬主 313
22.8 下移到模型層 315
第23章 測試隔離和“傾聽測試的心聲” 319
23.1 重溫抉擇時刻:視圖層依賴於尚未編寫的模型代碼 319
23.2 首先嘗試使用馭件實現隔離 320
23.3 傾聽測試的心聲:醜陋的測試錶明需要重構 323
23.4 以完全隔離的方式重寫視圖測試 323
23.4.1 為瞭新測試的健全性,保留之前的整閤測試組件 324
23.4.2 完全隔離的新測試組件 324
23.4.3 站在協作者的角度思考問題 324
23.5 下移到錶單層 329
23.6 下移到模型層 332
23.7 關鍵時刻,以及使用模擬技術的風險 335
23.8 把層與層之間的交互當作“閤約” 336
23.8.1 找齣隱形閤約 337
23.8.2 修正由於疏忽導緻的問題 338
23.9 還缺一個測試 339
23.10 清理:保留哪些整閤測試 340
23.10.1 刪除錶單層多餘的代碼 340
23.10.2 刪除以前實現的視圖 341
23.10.3 刪除視圖層多餘的代碼 342
23.11 總結:什麼時候編寫隔離測試,什麼時候編寫整閤測試 343
23.11.1 以復雜度為準則 344
23.11.2 兩種測試都要寫嗎 344
23.11.3 繼續前行 344
第24章 持續集成 346
24.1 安裝Jenkins 346
24.2 配置Jenkins 347
24.2.1 首次解鎖 348
24.2.2 現在建議安裝的插件 348
24.2.3 配置管理員用戶 348
24.2.4 添加插件 350
24.2.5 告訴Jenkins到哪裏尋找Python 3和Xvfb 350
24.2.6 設置HTTPS 351
24.3 設置項目 351
24.4 第一次構建 352
24.5 設置虛擬顯示器,讓功能測試能在無界麵的環境中運行 354
24.6 截圖 356
24.7 如有疑問,增加超時試試 359
24.8 使用PhantomJS運行QUnit JavaScript測試 359
24.8.1 安裝node 359
24.8.2 在Jenkins中添加構建步驟 361
24.9 CI服務器能完成的其他操作 362
第25章 簡單的社會化功能、頁麵模式以及練習 363
25.1 有多個用戶以及使用addCleanup的功能測試 363
25.2 頁麵模式 365
25.3 擴展功能測試測試第二個用戶和“My Lists”頁麵 367
25.4 留給讀者的練習 368
第26章 測試運行速度的快慢和熾熱的岩漿 371
26.1 正題:單元測試除瞭運行速度超快之外還有其他優勢 372
26.1.1 測試運行得越快,開發速度越快 372
26.1.2 神賜的心流狀態 372
26.1.3 經常不想運行速度慢的測試,導緻代碼變壞 373
26.1.4 現在還行,不過隨著時間推移,整閤測試會變得越來越慢 373
26.1.5 彆隻聽我一個人說 373
26.1.6 單元測試能驅使我們實現好的設計 373
26.2 純粹的單元測試有什麼問題 373
26.2.1 隔離的測試難讀也難寫 373
26.2.2 隔離測試不會自動測試集成情況 374
26.2.3 單元測試幾乎不能捕獲意料之外的問題 374
26.2.4 使用馭件的測試可能和實現方式聯係緊密 374
26.2.5 這些問題都可以解決 374
26.3 閤題:我們到底想從測試中得到什麼 374
26.3.1 正確性 374
26.3.2 簡潔可維護的代碼 375
26.3.3 高效的工作流程 375
26.3.4 根據所需的優勢評估測試 375
26.4 架構方案 375
26.4.1 端口和適配器(或六邊形、簡潔)架構 376
26.4.2 函數式核心,命令式外殼 377
26.5 小結 377
遵從測試山羊的教誨 379
附錄A PythonAnywhere 381
附錄B 基於類的Django 視圖 385
附錄C 使用Ansible 配置服務器 394
附錄D 測試數據庫遷移 398
附錄E 行為驅動開發 403
附錄F 構建一個REST API:JSON、Ajax 和JavaScript 模擬技術 416
附錄G Django-Rest-Framework 433
附錄H 速查錶 443
附錄I 接下來做什麼 447
附錄J 示例源碼 451
參考書目 453
作者簡介 454
封麵介紹 454
· · · · · · (
收起)