Return to Video

5.8 - 5.11 - Coverage, Unit vs. Integration Tests, Other Testing Concepts, and Perspectives

  • 0:00 - 0:01
    過去幾節課裡
  • 0:01 - 0:03
    我們花了些時間
  • 0:03 - 0:05
    談論過不同的測試方法
  • 0:05 - 0:08
    也談論過單元測試和整合測試的異同
  • 0:08 - 0:10
    我們也講解過如何使用RSpec
  • 0:10 - 0:12
    真正將你想測試的程式碼分開
  • 0:12 - 0:14
    也因為作業三和其他部份的關係
  • 0:14 - 0:18
    我們也研究過BDD
  • 0:18 - 0:20
    當中,我們基本上就是使用Cucumber把使用者的流程
  • 0:20 - 0:22
    轉變成整合測試和合格測試 (acceptance test)
  • 0:22 - 0:25
    你已經看到不同層次的測試
  • 0:25 - 0:27
    所以,這節課的目標基本上只是簡單的總結一下而已
  • 0:27 - 0:29
    就是說,我們站遠點綜觀看看
  • 0:29 - 0:33
    並將這些事情一起來看
  • 0:33 - 0:34
    基本上,這節課的內容將會涵蓋
  • 0:34 - 0:37
    課本上三到四個章節
  • 0:37 - 0:39
    我在這邊只是稍微提到而已
  • 0:39 - 0:41
    好了,有一個問題是常常出現的
  • 0:41 - 0:43
    我想你們也都會有這個問題
  • 0:43 - 0:44
    因為你們也有做作業
  • 0:44 - 0:45
    問題就是:「多少測試才夠呢?」
  • 0:45 - 0:48
    難過的是
  • 0:48 - 0:51
    如果你們在業界問這個問題
  • 0:51 - 0:52
    答案是非常簡單的
  • 0:52 - 0:53
    「關於這個問題,我們有產品的結案日期,
  • 0:53 - 0:54
    所以在結案日期前能做的測試
  • 0:54 - 0:56
    即足以。」
  • 0:56 - 0:58
    也就是有多少時間就做多少
  • 0:58 - 1:00
    這其實有點顛倒了
  • 1:00 - 1:01
    顯然不是很好
  • 1:01 - 1:02
    其實你們可以做的更好,對吧?
  • 1:02 - 1:03
    這邊有些靜態的測量
  • 1:03 - 1:06
    像是程式裡有多少程式碼
  • 1:06 - 1:08
    多少行測試用的程式碼等
  • 1:08 - 1:10
    另外,在業界並不罕見的是
  • 1:10 - 1:12
    針對測試完整的程式而言
  • 1:12 - 1:14
    測試用的程式碼的行數
  • 1:14 - 1:17
    往往是遠遠超過本來程式碼的行數的
  • 1:17 - 1:19
    甚至,倍增的量也是常見的
  • 1:19 - 1:21
    我想,即使甚至是
  • 1:21 - 1:23
    研究程式碼,甚至是習作等
  • 1:23 - 1:26
    1.5倍也非不合理
  • 1:26 - 1:30
    也就是說,測試用的程式碼
  • 1:30 - 1:32
    有應用程式碼的1.5倍
  • 1:32 - 1:34
    在很多實作的系統裡
  • 1:34 - 1:35
    就是說是真正需要測試的
  • 1:35 - 1:36
    測試程式碼對應用程式碼的比率,甚至比這個更高
  • 1:36 - 1:38
    所以也許可以用另一個較好的方式來問這個問題
  • 1:38 - 1:39
    就是,與其問「需要多少測試呢?」
  • 1:39 - 1:42
    不如問「我現在做的測試有多完整?」
  • 1:42 - 1:44
    「有多徹底?」
  • 1:44 - 1:45
    這個學期的後半部
  • 1:45 - 1:46
    Sen教授將會
  • 1:46 - 1:48
    對正規方法 (formal methods) 作一個簡略的介紹
  • 1:48 - 1:50
    並談論一下測試和除錯方法的最新進展
  • 1:50 - 1:52
    但是,對於這點,現在我們還是可以略提一二的
  • 1:52 - 1:54
    就是說,基於你們已經知道的,我們還是可以略提
  • 1:54 - 1:57
    一些有關測試涵蓋率 (test coverage) 的基本概念
  • 1:57 - 1:59
    我也許會說
  • 1:59 - 2:01
    事實上我們也一直說
  • 2:01 - 2:03
    正規方法在大的系統上基本上根本是沒用的
  • 2:03 - 2:05
    不過,我個人的觀點是
  • 2:05 - 2:07
    這個說法以前的確很對,但現在已經不太對了
  • 2:07 - 2:09
    我想,有許多特殊的場合裡
  • 2:09 - 2:10
    特別在測試和除錯方面
  • 2:10 - 2:12
    正規測試已經獲得了很大的進展
  • 2:12 - 2:15
    在這方面 Koushik Sen 是個領導先驅
  • 2:15 - 2:17
    所以,之後你們都有機會可以了解更多
  • 2:17 - 2:21
    不過現在我講的,是一些可以說是很實際的東西
  • 2:21 - 2:22
    就是測試涵蓋率的測量 (coverage measurement)
  • 2:22 - 2:24
    因為這就是實際情況
  • 2:24 - 2:26
    換句話說,假如有人要評估你
  • 2:26 - 2:28
    就是說在真正的工作時有人要評估你,這就是實際情況
  • 2:28 - 2:29
    那麼,有什麼基礎的東西呢?
  • 2:29 - 2:30
    讓我給你一個很簡單的類別
  • 2:30 - 2:32
    來講解有什麼不同的方法來量測
  • 2:32 - 2:34
    我們的測試可涵蓋多少程式範圍
  • 2:34 - 2:36
    這邊有些不同的程度差異
  • 2:36 - 2:37
    以不同的字彙來說的話
  • 2:37 - 2:40
    這不像是所有的程式部門都通用
  • 2:40 - 2:42
    但是有一套較通常使用的字彙
  • 2:42 - 2:43
    是我們的課本裡面用的
  • 2:43 - 2:44
    就是,我們談到 S0
  • 2:44 - 2:47
    意思是你呼叫每個方法一次
  • 2:47 - 2:50
    就是說,你呼叫 foo,然後呼叫 bar,就完成了
  • 2:50 - 2:52
    這就是 S0 coverage,不是怎麼的全盤
  • 2:52 - 2:54
    比較嚴謹的 S1
  • 2:54 - 2:56
    基本上就是,我們呼叫了每一個方法
  • 2:56 - 2:57
    而且是只要可以呼叫某個方法的地方都去呼叫那個方法
  • 2:57 - 2:58
    這什麼意思?
  • 2:58 - 3:00
    舉例來說
  • 3:00 - 3:01
    只呼叫 bar 不夠
  • 3:01 - 3:02
    你要先確定你一定會
  • 3:02 - 3:05
    在這裏呼叫 bar 至少一次
  • 3:05 - 3:07
    除此以外,還要確定
  • 3:07 - 3:10
    任何可以呼叫 bar 的外部函數都要呼叫 bar 一次
  • 3:10 - 3:12
    至於 SimpleCov 所測量的 C0
  • 3:12 - 3:15
    (你們當中已經設定好 SimpleCov 且實際做過的人啊)
  • 3:15 - 3:18
    基本上就是表示你執行所有的程式碼
  • 3:18 - 3:20
    在你的程式碼全部都做過一次
  • 3:20 - 3:22
    但這邊要小心一下
  • 3:22 - 3:25
    條件運算只被算一次而已
  • 3:25 - 3:28
    所以假如發生條件判斷例如執行了 "if"
  • 3:28 - 3:31
    只要程式碼分支有執行到
  • 3:31 - 3:33
    你已經執行了 "if" 陳述句
  • 3:33 - 3:35
    所以 C0 仍然只是涵蓋比較表層的範圍
  • 3:35 - 3:37
    但是我們將會看到
  • 3:37 - 3:39
    對 C0 涵蓋率的正確理解,其實是這樣的:
  • 3:39 - 3:41
    假如 C0 程度的涵蓋率你也測出了不好的涵蓋率
  • 3:41 - 3:44
    你的測試涵蓋率就真的是非常非常的差了
  • 3:44 - 3:46
    因為
  • 3:46 - 3:47
    你如果連這種簡單的表層測試也達不到
  • 3:47 - 3:50
    你的測試大概很有問題了
  • 3:50 - 3:51
    C1 則是更進一步
  • 3:51 - 3:53
    可以這麼說
  • 3:53 - 3:55
    必須把所有分支雙方向測試
  • 3:55 - 3:56
    所以當我們在執行 "if" 陳述句
  • 3:56 - 3:58
    就必須確保
  • 3:58 - 3:59
    "if x" 這個部分執行到
  • 3:59 - 4:05
    "if not x"這個部分也至少執行一次,才符合 C1
  • 4:05 - 4:08
    如果要再進一步,可以再加入 decision coverage
  • 4:08 - 4:09
    意思是:我們如果想要...
  • 4:09 - 4:12
    假如我們發現 "if" 陳述句
  • 4:12 - 4:13
    裡面包含不只一種陳述句
  • 4:13 - 4:15
    我們必須確保每個陳述句
  • 4:15 - 4:17
    都可以雙向評估
  • 4:17 - 4:19
    換句話說
  • 4:19 - 4:22
    如果 "if" 不執行
  • 4:22 - 4:24
    就要確保 fail 至少一次
  • 4:24 - 4:26
    因為 y 至少一次是 false , 又因為 z 是 false
  • 4:26 - 4:28
    任何陳述句
  • 4:28 - 4:31
    都是獨立的依條件改變結果
  • 4:31 - 4:34
    都必須能夠雙向測試
  • 4:34 - 4:36
    然後
  • 4:36 - 4:38
    有一件事很多人都希望做到
  • 4:38 - 4:41
    但沒有共識說這麼做到底有沒有意義
  • 4:41 - 4:42
    就是每個路徑都走過
  • 4:42 - 4:45
    顯然,這是有困難度的
  • 4:45 - 4:48
    因為所有條件都考慮會造成量呈指數倍數的增加
  • 4:48 - 4:53
    況且,通常都很難去評估
  • 4:53 - 4:55
    究竟是不是每個路徑都已經測試
  • 4:55 - 4:57
    針對這些困難的正規方法,是有的
  • 4:57 - 4:58
    它們可以讓你們知道洞在哪
  • 4:58 - 5:01
    但是最根本的是
  • 5:01 - 5:03
    在大部分的商業軟體公司裡
  • 5:03 - 5:04
    對於 C2 有多少價值的觀念
  • 5:04 - 5:06
    還不太一致
  • 5:06 - 5:08
    就是說,C2 比起 C0 或 C1 究竟有多少價值,還是沒有一個共識
  • 5:08 - 5:10
    所以,我認為,這個課程的用意是
  • 5:10 - 5:11
    讓你們了解
  • 5:11 - 5:13
    怎樣使用測試涵蓋率的資訊
  • 5:13 - 5:16
    SimpleCov 利用 Ruby 中的一些功能
  • 5:16 - 5:18
    讓你們可以做 C0 測試
  • 5:18 - 5:19
    也有很好的報表
  • 5:19 - 5:21
    給我們的資訊
  • 5:21 - 5:22
    大抵上而言是逐檔案,逐程式行的資訊
  • 5:22 - 5:24
    你可以看看你的涵蓋範圍
  • 5:24 - 5:27
    我覺得
  • 5:27 - 5:31
    這是個很好的開始
  • 5:31 - 5:33
    我們已經看了不同種類的測試後
  • 5:33 - 5:37
    往回退一步宏觀的看
  • 5:37 - 5:38
    我們實際看過的不同的測試
  • 5:38 - 5:40
    究竟有那幾種?
  • 5:40 - 5:42
    如果使用不同的測試
  • 5:42 - 5:43
    各自的缺點又是什麼?
  • 5:43 - 5:47
    我們已經看過單一類別和方法的程度
  • 5:47 - 5:50
    我們用 RSpec 大量使用了 mocking 和 stubbing 測試
  • 5:50 - 5:53
    比如,當我們模型中測試方法
  • 5:53 - 5:55
    這是單元測試例子
  • 5:55 - 5:59
    我們也完成其他非常像功能或模組測試
  • 6:00 - 6:02
    裡面有多個模組
  • 6:02 - 6:04
    所以如果我們有了 controller 得規格
  • 6:04 - 6:07
    我們看到就模擬 POST 的行為
  • 6:07 - 6:09
    但要記住
  • 6:09 - 6:10
    送出的 POST 要通過 routing subsystem 才到 controller
  • 6:12 - 6:14
    controller 完成後會產出一個 view
  • 6:14 - 6:16
    事實上還有其他部分
  • 6:16 - 6:17
    會和 controller 一起運作
  • 6:17 - 6:19
    使得 controller 規格能通過
  • 6:19 - 6:21
    這是裡面的某個部分
  • 6:21 - 6:23
    我們在這邊有多個方法用到不只一個類別
  • 6:25 - 6:27
    但我們仍要注意
  • 6:27 - 6:28
    這只在系統中的一小部分
  • 6:28 - 6:31
    我們仍廣泛的用 mocking 以及 stubbing
  • 6:31 - 6:35
    把我們想要測試的行為獨立出來
  • 6:35 - 6:36
    在 Cucumber 層級的整合或系統測試
  • 6:38 - 6:41
    他們測試了程式的全部路徑
  • 6:41 - 6:43
    可能也觸及了相當多不同的模組
  • 6:43 - 6:46
    最小化使用 mocks 和 stubs
  • 6:46 - 6:48
    因為整合測試其中一個目標
  • 6:48 - 6:50
    是能確切的測試個區塊之間的相互影響
  • 6:50 - 6:53
    所以如果你不想用 stub 或控制這些相互影響
  • 6:53 - 6:54
    你想要讓系統執行它就會執行
  • 6:56 - 6:58
    如果這是在開發時
  • 6:58 - 7:00
    那麼要如何會比較這些不同的測試?
  • 7:00 - 7:02
    我們看看這邊有幾個不同的軸
  • 7:02 - 7:05
    其中之一是他們需要多長時間運行
  • 7:05 - 7:06
    RSpec 和 Cucumber 看似有較高的啟動時間
  • 7:09 - 7:10
    但如您所見
  • 7:10 - 7:11
    如果加上更多的 RSpec 測試
  • 7:11 - 7:14
    並在後臺執行自動測試
  • 7:14 - 7:17
    一旦 RSpec 開始
  • 7:17 - 7:19
    會執行 specs 相當快
  • 7:19 - 7:21
    而 Cucumber 需要很長時間
  • 7:21 - 7:24
    因為 Cucumber 觸發了整個應用程式
  • 7:24 - 7:26
    這學期末
  • 7:26 - 7:28
    我們將會看到讓 Cucumber 更慢
  • 7:28 - 7:30
    因為整個瀏覽器內部都要觸發
  • 7:30 - 7:33
    就像是傀儡操控 Firefox
  • 7:33 - 7:35
    所以可以測試 Javascript 程式
  • 7:35 - 7:37
    實際上我們做的
  • 7:37 - 7:40
    我們能和朋友們在 SourceLabs 就在雲端裡操作
  • 7:40 - 7:42
    真令人興奮
  • 7:42 - 7:45
    所以執行的快與慢
  • 7:46 - 7:48
    假如單元測試中發生了錯誤
  • 7:48 - 7:49
    通常很容易發生
  • 7:49 - 7:52
    要找出和追蹤該錯誤的來源
  • 7:52 - 7:53
    正是因為獨立測試
  • 7:53 - 7:56
    你已經 stub 所以無所謂
  • 7:56 - 7:58
    你只專注在感興趣的行為
  • 7:58 - 7:59
    如果已經做得很好但是測試時
    有些錯誤的地方又發生錯誤
  • 8:04 - 8:07
    相反地
    如果您用 Cucumber 差不多10個步驟
  • 8:08 - 8:10
    每一步都會觸擊到應用程式的一部分
  • 8:11 - 8:12
    這就會花很多時間才能找到那個 bug
  • 8:14 - 8:16
    所以需要去衡量
    能夠涵蓋的錯誤範圍
  • 8:20 - 8:23
    如果你寫一個好的套件用來作單元測試和功能測試
  • 8:24 - 8:26
    您可以有很高的覆蓋範圍
  • 8:26 - 8:27
    您可以產生 SimpleCov 報告
  • 8:27 - 8:30
    也可以在檔案中的任何一行沒有側試過的程式碼
  • 8:32 - 8:34
    做會涵蓋到這行的測試
  • 8:34 - 8:36
    要找出如何改善您的覆蓋範圍
  • 8:36 - 8:37
    例如在 C0 能更輕鬆地完成與單元測試
  • 8:40 - 8:42
    而 Cucumber 測試會觸擊大量的程式碼
  • 8:45 - 8:47
    但你的方法就顯得很少
  • 8:47 - 8:49
    所以如果目標是提昇涵蓋範圍
  • 8:49 - 8:51
    就用工具來協助單元的層級
  • 8:51 - 8:53
    這樣可以更專心去了解程式那邊是不是還沒側過
  • 8:54 - 8:56
    然後可以寫相當針對性的測試針對這些部分
  • 8:58 - 9:01
    就像把這些部分放在一起做單元測試
  • 9:03 - 9:05
    因為這些分離出來測試適合用 mocks 來隔開你不在意的部分
  • 9:09 - 9:11
    定義上這意味著不是在測試介面
  • 9:12 - 9:14
    而像是在軟體裡有智慧一樣
  • 9:14 - 9:16
    很多有趣的錯誤
  • 9:16 - 9:18
    發生在各部分間的介面
  • 9:18 - 9:20
    (以下尚未處理) 並在類中或在方法內不進行排序的
  • 9:20 - 9:22
    那些是有點簡單的 bug,追查
  • 9:22 - 9:24
    與在另一個極端
  • 9:24 - 9:26
    你越集成測試走向極端
  • 9:26 - 9:29
    你應該少依賴類比考試
  • 9:29 - 9:30
    這一確切原因
  • 9:30 - 9:32
    現在我們看到的如果你在測試類似
  • 9:32 - 9:34
    也就是說,在面向服務的體系結構
  • 9:34 - 9:35
    你要在其上與遠端網站進行交互
  • 9:35 - 9:37
    你最終仍
  • 9:37 - 9:38
    不必做了相當大的嘲弄、 鉗
  • 9:38 - 9:40
    這樣,你不要依賴互聯網
  • 9:40 - 9:41
    為了使您的測試通過
  • 9:41 - 9:43
    但是,總體上說
  • 9:43 - 9:47
    你想盡可能多的類比考試,您可以刪除
  • 9:47 - 9:48
    而讓系統運行的方式,它將運行在現實生活中
  • 9:48 - 9:52
    所以,好消息是你 * 是 * 測試介面
  • 9:52 - 9:54
    * 但 * 當事情出錯在一個介面
  • 9:54 - 9:57
    因為您的解析度不是那麼好
  • 9:57 - 10:00
    可能需要很長時間弄清楚它是什麼
  • 10:00 - 10:05
    那麼,什麼是某種程度的高階位從折
  • 10:05 - 10:07
    是你真的不想依賴
  • 10:07 - 10:08
    太重上任何一種測試
  • 10:08 - 10:10
    他們為不同的目的和具體取決於服務上
  • 10:10 - 10:13
    你想行使您更多的介面
  • 10:13 - 10:15
    或你想提高你的細細微性覆蓋率
  • 10:15 - 10:18
    這會影響你如何發展你的測試套件
  • 10:18 - 10:20
    和你就會把它演進隨您的軟體
  • 10:20 - 10:24
    因此,我們使用一組特定的測試中的術語
  • 10:24 - 10:26
    它是術語到,通過和大
  • 10:26 - 10:29
    最常用的 Rails 社區
  • 10:29 - 10:30
    但有一些變化
  • 10:30 - 10:33
    [和] 你可能會聽到的一些其他術語
  • 10:33 - 10:35
    如果你去找一份工作的某個地方
  • 10:35 - 10:36
    你聽到有關變異測試
  • 10:36 - 10:38
    我們還沒有用過
  • 10:38 - 10:40
    這是一個有趣的想法,我認為,發明的
  • 10:40 - 10:43
    維與駕駛艙,有,排序的
  • 10:43 - 10:44
    軟體測試的通用書
  • 10:44 - 10:46
    這個想法是:
  • 10:46 - 10:48
    假設我向我的代碼提交蓄意的 bug
  • 10:48 - 10:49
    這不會迫使一些測試失敗嗎?
  • 10:49 - 10:53
    因為,如果我改變,你知道,"如果 x"到"如果不 x"
  • 10:53 - 10:56
    並沒有測試失敗,然後要麼我的思念一些報導
  • 10:56 - 10:59
    或我的應用程式是非常奇怪和不知何故不確定性
  • 10:59 - 11:03
    模糊測試,其中 Koushik 森可能更詳細地談
  • 11:03 - 11:07
    基本上,這就是"10,000 猴子在打字機
  • 11:07 - 11:09
    在您的代碼中扔隨機輸入"
  • 11:09 - 11:10
    有趣的是,
  • 11:10 - 11:11
    我們一直在做這些測試
  • 11:11 - 11:13
    基本上是精心編制來測試應用程式
  • 11:13 - 11:15
    它設計的方法
  • 11:15 - 11:16
    和這些,你知道,模糊測試
  • 11:16 - 11:19
    有關測試應用程式的方式是它 * 不是 *,可使用
  • 11:19 - 11:22
    所以,如果會發生什麼你扔巨大表單提交
  • 11:22 - 11:25
    如果你把控制字元放在您的表單中,將會發生什麼?
  • 11:25 - 11:27
    如果您反復提交同樣的事情,會發生什麼?
  • 11:27 - 11:29
    Koushik 有一個統計資料,
  • 11:29 - 11:32
    微軟認定他們的 bug 的 20 %
  • 11:32 - 11:34
    使用一些變異的模糊化測試
  • 11:34 - 11:36
    和,約 25 %
  • 11:36 - 11:39
    常見的 Unix 命令列程式的
  • 11:39 - 11:40
    可以向崩潰
  • 11:40 - 11:44
    [當] 把侵略性模糊測試通過
  • 11:44 - 11:46
    定義使用覆蓋範圍是我們還沒有完成的事情
  • 11:46 - 11:48
    但它是另一個有趣的概念
  • 11:48 - 11:50
    我的程式在任何一點的設想是,
  • 11:50 - 11:52
    有一個地方,我的定義 — —
  • 11:52 - 11:54
    或賦值給一些變數 — —
  • 11:54 - 11:56
    然後還有下游的地方
  • 11:56 - 11:57
    大概我的去向消費的價值 — —
  • 11:57 - 11:59
    有人要使用此值
  • 11:59 - 12:01
    我已覆蓋每一對嗎?
  • 12:01 - 12:02
    換句話說,做有測試在每一對
  • 12:02 - 12:04
    定義一個變數和某個地方使用它
  • 12:04 - 12:07
    在我的測試套件的某些部分執行
  • 12:07 - 12:10
    它有時被稱為杜覆蓋範圍
  • 12:10 - 12:14
    其他條件,我認為不廣泛地不再使用
  • 12:14 - 12:17
    與白牌或與 glassbox 黑匣子黑匣子
  • 12:17 - 12:20
    大致上黑匣子測試是一個從寫入
  • 12:20 - 12:22
    事物的外部規範的角度來看
  • 12:22 - 12:24
    [例如:]"這是一個雜湊表
  • 12:24 - 12:26
    當我把放在一個鍵時應回到一個值
  • 12:26 - 12:28
    如果刪除了關鍵值不存在"
  • 12:28 - 12:29
    這是一個黑匣子測試,因為它並沒有說
  • 12:29 - 12:32
    任何有關該雜湊表如何實施的
  • 12:32 - 12:34
    和它不會嘗試狠抓落實
  • 12:34 - 12:36
    相應的白牌測試可能是:
  • 12:36 - 12:38
    "我知道些什麼雜湊函數
  • 12:38 - 12:39
    和我要去刻意製造
  • 12:39 - 12:41
    我的測試用例中的雜湊鍵
  • 12:41 - 12:43
    這造成了大量的散列碰撞
  • 12:43 - 12:45
    以確保我正在測試的功能,部分"
  • 12:45 - 12:49
    現在,C0 測試覆蓋工具,像 SimpleCov
  • 12:49 - 12:52
    將顯示,如果你有的只是黑匣子測試
  • 12:52 - 12:53
    您可能會發現,
  • 12:53 - 12:55
    碰撞覆蓋代碼不是很多時候被撞傷
  • 12:55 - 12:56
    ,可能會提示您,然後說:
  • 12:56 - 12:58
    "好的如果我真的要加強,— —
  • 12:58 - 13:00
    第一,如果我想要提高這些測試的覆蓋範圍
  • 13:00 - 13:02
    現在要寫白牌或 glassbox 測試
  • 13:02 - 13:04
    我要向內看看,請參閱執行什麼呢
  • 13:04 - 13:05
    並找到具體的方法
  • 13:05 - 13:10
    試圖打破邪惡的方式實施"
  • 13:10 - 13:13
    所以,我認為,測試是一種生活方式,正確嗎?
  • 13:13 - 13:16
    我們已經遠離的階段
  • 13:16 - 13:18
    "我們將建立整個事情,然後,我們將考驗"
  • 13:18 - 13:19
    和我們已經進入的階段
  • 13:19 - 13:20
    "我們測試我們看一下"
  • 13:20 - 13:22
    測試是真的更像是一種發展工具
  • 13:22 - 13:24
    像這麼多的開發工具
  • 13:24 - 13:25
    它的效力取決於
  • 13:25 - 13:27
    不管你雅致的方式使用上
  • 13:27 - 13:31
    所以,你會說:"好吧,讓我們看看 — — 我踢了輪胎
  • 13:31 - 13:33
    你知道,我解雇了流覽器,我試過幾件事情
  • 13:33 - 13:35
    (鮮花手)它工作起來 !部署它 !"
  • 13:35 - 13:38
    這顯然不是你想要的多一點騎士
  • 13:38 - 13:41
    通過的路上,我們發現的事情之一
  • 13:41 - 13:43
    與剛剛起步的此線上課程
  • 13:43 - 13:45
    當 60000 人參加課程
  • 13:45 - 13:48
    和那些人的 0.1%有問題
  • 13:48 - 13:50
    你就可以得到 60 電子郵件
  • 13:50 - 13:53
    必然結果是: 當您的網站使用的很多人
  • 13:53 - 13:55
    你沒有找到一些愚蠢的 bug
  • 13:55 - 13:57
    但是,可以通過測試來找
  • 13:57 - 13:59
    可以非常迅速生成 * 多 * 的痛
  • 13:59 - 14:02
    另一方面,你不想被教條和說
  • 14:02 - 14:04
    "呃,直到我們有 100%的覆蓋率和每個測試是綠色
  • 14:04 - 14:06
    我們絕對會不船舶"
  • 14:06 - 14:07
    這也是不健康
  • 14:07 - 14:08
    和測試品質
  • 14:08 - 14:10
    不一定相符的發言
  • 14:10 - 14:11
    除非你可以說
  • 14:11 - 14:12
    關於你的測試品質
  • 14:12 - 14:14
    只是因為你已經執行的每一條線
  • 14:14 - 14:17
    並不意味著你測試過的有趣的案件
  • 14:17 - 14:18
    所以,某處之間,你會說
  • 14:18 - 14:20
    "嗯,我們可以使用覆蓋工具來標識
  • 14:20 - 14:23
    undertested 或差測試代碼的部分
  • 14:23 - 14:24
    我們將使用它們作為指引
  • 14:24 - 14:27
    要排序的説明改善我們的總體信心水準"
  • 14:27 - 14:29
    但請記住,敏捷開發是擁抱變化
  • 14:29 - 14:30
    它的處理
  • 14:30 - 14:32
    更改的部分是事情會改變,將導致
  • 14:32 - 14:33
    你沒有預見到的 bug
  • 14:33 - 14:34
    和正確的反應就是:
  • 14:34 - 14:36
    能自在的測試工具
  • 14:36 - 14:37
    [這樣] 您可以快速找到這些 bug
  • 14:37 - 14:39
    寫一個轉載了這個 bug 的測試
  • 14:39 - 14:40
    然後進行測試綠色
  • 14:40 - 14:41
    然後你就會真的改變它
  • 14:41 - 14:43
    這意味著,您真的修復 bug 的方式是
  • 14:43 - 14:45
    如果您創建了一個正確的失敗的測試
  • 14:45 - 14:46
    重現這個 bug
  • 14:46 - 14:48
    然後回到了並修復該代碼
  • 14:48 - 14:49
    使這些測試通過
  • 14:49 - 14:51
    同樣的你不想說
  • 14:51 - 14:53
    "嗯,單元測試給你更好的覆蓋範圍
  • 14:53 - 14:54
    他們是更徹底和詳細
  • 14:54 - 14:56
    所以讓我們專注,我們所有的能量"
  • 14:56 - 14:57
    而不是
  • 14:57 - 14:58
    "哦,重點集成測試
  • 14:58 - 15:00
    因為他們更切合實際,對不對?
  • 15:00 - 15:01
    它們反映了客戶說他們想要什麼
  • 15:01 - 15:03
    因此,如果通過集成測試
  • 15:03 - 15:05
    通過定義我們滿足客戶需求"
  • 15:05 - 15:07
    同樣,這兩個極端都有點不健康
  • 15:07 - 15:09
    因為其中的每一個可以找出問題
  • 15:09 - 15:11
    這將由其他忽略了
  • 15:11 - 15:12
    所以,有好的結合
  • 15:12 - 15:15
    就是有點全部是所有關于
  • 15:15 - 15:18
    我想要留給你們的最後一件事是,我認為
  • 15:18 - 15:20
    方面的測試,是"與拓展署
  • 15:20 - 15:22
    所謂傳統的調試 — —
  • 15:22 - 15:24
    即,我們都有點做的方式
  • 15:24 - 15:25
    儘管我們說我們不要"
  • 15:25 - 15:26
    和我們都試圖右好轉嗎?
  • 15:26 - 15:27
    我們所有的在裝訂線
  • 15:27 - 15:29
    我們中的一些正仰望星空
  • 15:29 - 15:31
    努力提高我們的實踐
  • 15:31 - 15:33
    但現在住這 3 或 4 年我自己
  • 15:33 - 15:35
    和 — — 要老實 — 3 年前我沒做拓展署
  • 15:35 - 15:37
    我現在就做,因為我發現它是更好
  • 15:37 - 15:40
    這裡是我蒸餾的所以,我覺得很管用
  • 15:40 - 15:43
    很抱歉,顏色是有點怪異
  • 15:43 - 15:45
    但在左邊的列的表的
  • 15:45 - 15:46
    [它] 說"常規調試"
  • 15:46 - 15:47
    右側說"拓展署"
  • 15:47 - 15:49
    所以我用來編寫代碼的方法是什麼?
  • 15:49 - 15:51
    也許你們中的一些仍然這樣做
  • 15:51 - 15:53
    我寫了一大堆的行
  • 15:53 - 15:54
    也許我們只剩下幾十行代碼
  • 15:54 - 15:55
    我是 * 確保 * 他們正確 — —
  • 15:55 - 15:56
    我的意思是,我 * am * 一個好的程式師,正確嗎?
  • 15:56 - 15:57
    這並不難
  • 15:57 - 15:59
    我運行它 — — 它不起作用
  • 15:59 - 16:01
    好的調試器點燃 — — 將 printf 的開始
  • 16:01 - 16:04
    如果就已經使用 TDD 將我做什麼而是?
  • 16:04 - 16:08
    嗯,我會寫 * 幾 * 行代碼,第一次寫了一個測試
  • 16:08 - 16:10
    所以儘快把測試從紅色變為綠色
  • 16:10 - 16:12
    我知道我寫了代碼的工作 — —
  • 16:12 - 16:15
    或者至少,我原本想的行為的部件
  • 16:15 - 16:16
    行為的那些部分工作,因為我有一個測試
  • 16:16 - 16:19
    好的回傳統的調試:
  • 16:19 - 16:21
    我正在我的程式試圖找到的 bug
  • 16:21 - 16:23
    我開始把 printf 的無處不在
  • 16:23 - 16:24
    可以列印出來的東西值
  • 16:24 - 16:25
    方式是很有趣
  • 16:25 - 16:26
    當你想閱讀這些
  • 16:26 - 16:28
    日誌輸出的 500 線出來的
  • 16:28 - 16:29
    你會得到一個 Rails 應用程式中
  • 16:29 - 16:30
    試圖找到 * 你 * printf 的
  • 16:30 - 16:32
    你知道,"我知道我要做 — —
  • 16:32 - 16:34
    我要把放在 75 星號之前和之後
  • 16:34 - 16:36
    這將使可讀"(笑聲)
  • 16:36 - 16:38
    誰不要 — — 好吧,提高你的手,如果你不這樣做 !
  • 16:38 - 16:40
    謝謝你的誠實。(笑聲)還行。
  • 16:40 - 16:43
    或 — — 或者我可以做其他事情,我可以說:
  • 16:43 - 16:45
    列印變數的值而不是
  • 16:45 - 16:47
    為什麼不寫檢查它的測試
  • 16:47 - 16:48
    在這樣的期望應該
  • 16:48 - 16:50
    我立即知道在明亮的紅色字母
  • 16:50 - 16:53
    如果不滿足這一期望
  • 16:53 - 16:56
    好的我對常規調試側:
  • 16:56 - 16:58
    我打破出殺手鐧: 我拉出 Ruby 調試器
  • 16:58 - 17:02
    我設置調試中斷點,和我現在開始 * 調整 * 說
  • 17:02 - 17:04
    "哦,讓我們看看,我要讓過去的 if 語句
  • 17:04 - 17:06
    所以要設置的那個東西
  • 17:06 - 17:07
    哦,我要調用該方法,所以我需要 to…"
  • 17:07 - 17:08
    不 !
  • 17:08 - 17:10
    我 * 能 * 相反 — — 如果我要去做,不管怎麼說 — —
  • 17:10 - 17:13
    讓我們在檔中設置一些類比考試和存根,只是做
  • 17:13 - 17:16
    若要控制的代碼路徑,讓它就這樣的方式
  • 17:16 - 17:19
    現在,"好吧,肯定我已經固定它 !
  • 17:19 - 17:22
    我給出的調試器,運行它所有再次 !"
  • 17:22 - 17:24
    並且,當然,9 次滿分,你並沒有解決它
  • 17:24 - 17:26
    或你的部分原因是固定的它,但你並沒有完全修復,
  • 17:26 - 17:30
    現在我再做這些手動都有
  • 17:30 - 17:32
    * 或 * 我已經有一堆的測試
  • 17:32 - 17:34
    和我可以自動他們重新
  • 17:34 - 17:35
    可以,如果有些人不和
  • 17:35 - 17:36
    "哦,我未修復整件事
  • 17:36 - 17:38
    沒問題,我只是去回來 !"
  • 17:38 - 17:39
    所以,底線是,
  • 17:39 - 17:41
    你知道,你 * 能 * 做它的左側
  • 17:41 - 17:45
    但在這兩種情況中使用相同的技術
  • 17:45 - 17:48
    唯一不同的是,在一個案例中你正在手動
  • 17:48 - 17:50
    這是無聊且容易出錯
  • 17:50 - 17:51
    在其他情況下你做一些更多的工作
  • 17:51 - 17:53
    但您可以使它自動和可重複
  • 17:53 - 17:55
    有,你知道,一些高信心
  • 17:55 - 17:57
    當您更改您的代碼中的東西
  • 17:57 - 17:58
    你不打破過去工作的東西
  • 17:58 - 18:00
    基本上,這是提高工作效率
  • 18:00 - 18:02
    所以你正在做的事情都一樣
  • 18:02 - 18:04
    但有一種"三角"額外工作
  • 18:04 - 18:07
    您正在使用你的努力在多高的杠杆
  • 18:07 - 18:10
    這樣說是我認為的種 TDD 是一件好事
  • 18:10 - 18:11
    這是真的,這不需要新的技能
  • 18:11 - 18:15
    它僅僅需要 [你] 重構您現有的技能
  • 18:15 - 18:18
    也嘗試過當我 — — 再次,誠實口供,正確嗎? — —
  • 18:18 - 18:19
    當我開始做這就像
  • 18:19 - 18:21
    "好吧,我會在滑軌上的課程教學
  • 18:21 - 18:22
    我真的應該集中測試
  • 18:22 - 18:24
    所以我回到我寫了一些代碼
  • 18:24 - 18:26
    那是 * 工作 * — — 你知道,那是體面的代碼 — —
  • 18:26 - 18:29
    然後我就開始努力為它編寫測試
  • 18:29 - 18:31
    它是 * 那麼痛苦 *
  • 18:31 - 18:33
    因為是可測試的方式並不編寫代碼
  • 18:33 - 18:34
    有各種各樣的交互
  • 18:34 - 18:36
    比如有嵌套的條件陳述式
  • 18:36 - 18:38
    如果你想要找出特定語句
  • 18:38 - 18:41
    並將它測試 — — 到觸發器測試 — — 只是該聲明
  • 18:41 - 18:44
    你會在您測試設置的東西量
  • 18:44 - 18:45
    發生 — —
  • 18:45 - 18:46
    請記住,當談到類比火車殘骸 — —
  • 18:46 - 18:48
    您必須設置所有此基礎結構
  • 18:48 - 18:49
    只是為了得到 * 一個 * 代碼行
  • 18:49 - 18:51
    和你這麼做了,你走
  • 18:51 - 18:52
    "Gawd,測試是真的不值得 !
  • 18:52 - 18:54
    我寫了 20 條線的安裝
  • 18:54 - 18:56
    這樣我可以測試兩行在函數中我 !"
  • 18:56 - 18:58
    真正帶告訴你 — — 我現在意識到 — —
  • 18:58 - 19:00
    是你的函數是 * 壞 *
  • 19:00 - 19:01
    它是一個嚴重的書面的函數
  • 19:01 - 19:02
    它不是一個可測試函數
  • 19:02 - 19:03
    它有太多的移動部件
  • 19:03 - 19:06
    相關性的 * 可 * 被打破
  • 19:06 - 19:07
    我的功能中有無接縫
  • 19:07 - 19:11
    這使我單獨測試不同的行為
  • 19:11 - 19:12
    一旦你開始做測試第一次開發
  • 19:12 - 19:15
    因為你要的小塊寫你的測試
  • 19:15 - 19:17
    它使解決這個問題
  • 19:17 -
    所以,這一直是我的頓悟
Title:
5.8 - 5.11 - Coverage, Unit vs. Integration Tests, Other Testing Concepts, and Perspectives
Video Language:
English

Chinese, Traditional subtitles

Incomplete

Revisions