WEBVTT 00:00:00.057 --> 00:00:01.092 過去幾節課裡 00:00:01.092 --> 00:00:03.032 我們花了些時間 00:00:03.032 --> 00:00:05.082 談論過不同的測試方法 00:00:05.082 --> 00:00:08.021 也談論過單元測試和整合測試的異同 00:00:08.021 --> 00:00:10.010 我們也講解過如何使用RSpec 00:00:10.010 --> 00:00:12.049 真正將你想測試的程式碼分開 00:00:12.049 --> 00:00:14.090 也因為作業三和其他部份的關係 00:00:14.090 --> 00:00:18.017 我們也研究過BDD 00:00:18.017 --> 00:00:20.062 當中,我們基本上就是使用Cucumber把使用者的流程 00:00:20.062 --> 00:00:22.095 轉變成整合測試和合格測試 (acceptance test) 00:00:22.095 --> 00:00:25.061 你已經看到不同層次的測試 00:00:25.061 --> 00:00:27.063 所以,這節課的目標基本上只是簡單的總結一下而已 00:00:27.063 --> 00:00:29.092 就是說,我們站遠點綜觀看看 00:00:29.092 --> 00:00:33.001 並將這些事情一起來看 00:00:33.001 --> 00:00:34.095 基本上,這節課的內容將會涵蓋 00:00:34.095 --> 00:00:37.000 課本上三到四個章節 00:00:37.000 --> 00:00:39.061 我在這邊只是稍微提到而已 00:00:39.061 --> 00:00:41.046 好了,有一個問題是常常出現的 00:00:41.046 --> 00:00:43.025 我想你們也都會有這個問題 00:00:43.025 --> 00:00:44.052 因為你們也有做作業 00:00:44.052 --> 00:00:45.069 問題就是:「多少測試才夠呢?」 00:00:45.069 --> 00:00:48.049 難過的是 00:00:48.049 --> 00:00:51.009 如果你們在業界問這個問題 00:00:51.009 --> 00:00:52.017 答案是非常簡單的 00:00:52.017 --> 00:00:53.017 「關於這個問題,我們有產品的結案日期, 00:00:53.017 --> 00:00:54.099 所以在結案日期前能做的測試 00:00:54.099 --> 00:00:56.066 即足以。」 00:00:56.066 --> 00:00:58.015 也就是有多少時間就做多少 00:00:58.015 --> 00:01:00.002 這其實有點顛倒了 00:01:00.002 --> 00:01:01.011 顯然不是很好 00:01:01.011 --> 00:01:02.054 其實你們可以做的更好,對吧? 00:01:02.054 --> 00:01:03.070 這邊有些靜態的測量 00:01:03.070 --> 00:01:06.003 像是程式裡有多少程式碼 00:01:06.003 --> 00:01:08.021 多少行測試用的程式碼等 00:01:08.021 --> 00:01:10.029 另外,在業界並不罕見的是 00:01:10.029 --> 00:01:12.068 針對測試完整的程式而言 00:01:12.068 --> 00:01:14.057 測試用的程式碼的行數 00:01:14.057 --> 00:01:17.073 往往是遠遠超過本來程式碼的行數的 00:01:17.073 --> 00:01:19.075 甚至,倍增的量也是常見的 00:01:19.075 --> 00:01:21.084 我想,即使甚至是 00:01:21.084 --> 00:01:23.022 研究程式碼,甚至是習作等 00:01:23.022 --> 00:01:26.085 1.5倍也非不合理 00:01:26.085 --> 00:01:30.005 也就是說,測試用的程式碼 00:01:30.005 --> 00:01:32.024 有應用程式碼的1.5倍 00:01:32.024 --> 00:01:34.022 在很多實作的系統裡 00:01:34.022 --> 00:01:35.027 就是說是真正需要測試的 00:01:35.027 --> 00:01:36.091 測試程式碼對應用程式碼的比率,甚至比這個更高 00:01:36.091 --> 00:01:38.015 所以也許可以用另一個較好的方式來問這個問題 00:01:38.015 --> 00:01:39.047 就是,與其問「需要多少測試呢?」 00:01:39.047 --> 00:01:42.049 不如問「我現在做的測試有多完整?」 00:01:42.049 --> 00:01:44.035 「有多徹底?」 00:01:44.035 --> 00:01:45.056 這個學期的後半部 00:01:45.056 --> 00:01:46.056 Sen教授將會 00:01:46.056 --> 00:01:48.018 對正規方法 (formal methods) 作一個簡略的介紹 00:01:48.018 --> 00:01:50.085 並談論一下測試和除錯方法的最新進展 00:01:50.085 --> 00:01:52.068 但是,對於這點,現在我們還是可以略提一二的 00:01:52.068 --> 00:01:54.007 就是說,基於你們已經知道的,我們還是可以略提 00:01:54.007 --> 00:01:57.074 一些有關測試涵蓋率 (test coverage) 的基本概念 00:01:57.074 --> 00:01:59.054 我也許會說 00:01:59.054 --> 00:02:01.001 事實上我們也一直說 00:02:01.001 --> 00:02:03.003 正規方法在大的系統上基本上根本是沒用的 00:02:03.003 --> 00:02:05.033 不過,我個人的觀點是 00:02:05.033 --> 00:02:07.001 這個說法以前的確很對,但現在已經不太對了 00:02:07.001 --> 00:02:09.019 我想,有許多特殊的場合裡 00:02:09.019 --> 00:02:10.052 特別在測試和除錯方面 00:02:10.052 --> 00:02:12.084 正規測試已經獲得了很大的進展 00:02:12.084 --> 00:02:15.075 在這方面 Koushik Sen 是個領導先驅 00:02:15.075 --> 00:02:17.094 所以,之後你們都有機會可以了解更多 00:02:17.094 --> 00:02:21.043 不過現在我講的,是一些可以說是很實際的東西 00:02:21.043 --> 00:02:22.073 就是測試涵蓋率的測量 (coverage measurement) 00:02:22.073 --> 00:02:24.047 因為這就是實際情況 00:02:24.047 --> 00:02:26.020 換句話說,假如有人要評估你 00:02:26.020 --> 00:02:28.063 就是說在真正的工作時有人要評估你,這就是實際情況 00:02:28.063 --> 00:02:29.052 那麼,有什麼基礎的東西呢? 00:02:29.052 --> 00:02:30.078 讓我給你一個很簡單的類別 00:02:30.078 --> 00:02:32.090 來講解有什麼不同的方法來量測 00:02:32.090 --> 00:02:34.080 我們的測試可涵蓋多少程式範圍 00:02:34.080 --> 00:02:36.063 這邊有些不同的程度差異 00:02:36.063 --> 00:02:37.085 以不同的字彙來說的話 00:02:37.085 --> 00:02:40.073 這不像是所有的程式部門都通用 00:02:40.073 --> 00:02:42.064 但是有一套較通常使用的字彙 00:02:42.064 --> 00:02:43.064 是我們的課本裡面用的 00:02:43.064 --> 00:02:44.068 就是,我們談到 S0 00:02:44.068 --> 00:02:47.045 意思是你呼叫每個方法一次 00:02:47.045 --> 00:02:50.045 就是說,你呼叫 foo,然後呼叫 bar,就完成了 00:02:50.045 --> 00:02:52.015 這就是 S0 coverage,不是怎麼的全盤 00:02:52.015 --> 00:02:54.068 比較嚴謹的 S1 00:02:54.068 --> 00:02:56.013 基本上就是,我們呼叫了每一個方法 00:02:56.013 --> 00:02:57.028 而且是只要可以呼叫某個方法的地方都去呼叫那個方法 00:02:57.028 --> 00:02:58.082 這什麼意思? 00:02:58.082 --> 00:03:00.007 舉例來說 00:03:00.007 --> 00:03:01.012 只呼叫 bar 不夠 00:03:01.012 --> 00:03:02.095 你要先確定你一定會 00:03:02.095 --> 00:03:05.057 在這裏呼叫 bar 至少一次 00:03:05.057 --> 00:03:07.016 除此以外,還要確定 00:03:07.016 --> 00:03:10.037 任何可以呼叫 bar 的外部函數都要呼叫 bar 一次 00:03:10.037 --> 00:03:12.081 至於 SimpleCov 所測量的 C0 00:03:12.081 --> 00:03:15.099 (你們當中已經設定好 SimpleCov 且實際做過的人啊) 00:03:15.099 --> 00:03:18.052 基本上就是表示你執行所有的程式碼 00:03:18.052 --> 00:03:20.004 在你的程式碼全部都做過一次 00:03:20.004 --> 00:03:22.048 但這邊要小心一下 00:03:22.048 --> 00:03:25.058 條件運算只被算一次而已 00:03:25.058 --> 00:03:28.091 所以假如發生條件判斷例如執行了 "if" 00:03:28.091 --> 00:03:31.074 只要程式碼分支有執行到 00:03:31.074 --> 00:03:33.035 你已經執行了 "if" 陳述句 00:03:33.035 --> 00:03:35.066 所以 C0 仍然只是涵蓋比較表層的範圍 00:03:35.066 --> 00:03:37.026 但是我們將會看到 00:03:37.026 --> 00:03:39.023 對 C0 涵蓋率的正確理解,其實是這樣的: 00:03:39.023 --> 00:03:41.079 假如 C0 程度的涵蓋率你也測出了不好的涵蓋率 00:03:41.079 --> 00:03:44.007 你的測試涵蓋率就真的是非常非常的差了 00:03:44.007 --> 00:03:46.008 因為 00:03:46.008 --> 00:03:47.037 你如果連這種簡單的表層測試也達不到 00:03:47.037 --> 00:03:50.002 你的測試大概很有問題了 00:03:50.002 --> 00:03:51.091 C1 則是更進一步 00:03:51.091 --> 00:03:53.071 可以這麼說 00:03:53.071 --> 00:03:55.019 必須把所有分支雙方向測試 00:03:55.019 --> 00:03:56.061 所以當我們在執行 "if" 陳述句 00:03:56.061 --> 00:03:58.066 就必須確保 00:03:58.066 --> 00:03:59.092 "if x" 這個部分執行到 00:03:59.092 --> 00:04:05.013 "if not x"這個部分也至少執行一次,才符合 C1 00:04:05.013 --> 00:04:08.036 如果要再進一步,可以再加入 decision coverage 00:04:08.036 --> 00:04:09.063 意思是:我們如果想要... 00:04:09.063 --> 00:04:12.036 假如我們發現 "if" 陳述句 00:04:12.036 --> 00:04:13.088 裡面包含不只一種陳述句 00:04:13.088 --> 00:04:15.071 我們必須確保每個陳述句 00:04:15.071 --> 00:04:17.097 都可以雙向評估 00:04:17.097 --> 00:04:19.067 換句話說 00:04:19.067 --> 00:04:22.041 如果 "if" 不執行 00:04:22.041 --> 00:04:24.034 就要確保 fail 至少一次 00:04:24.034 --> 00:04:26.044 因為 y 至少一次是 false , 又因為 z 是 false 00:04:26.044 --> 00:04:28.088 任何陳述句 00:04:28.088 --> 00:04:31.021 都是獨立的依條件改變結果 00:04:31.021 --> 00:04:34.048 都必須能夠雙向測試 00:04:34.048 --> 00:04:36.003 然後 00:04:36.003 --> 00:04:38.052 有一件事很多人都希望做到 00:04:38.052 --> 00:04:41.026 但沒有共識說這麼做到底有沒有意義 00:04:41.026 --> 00:04:42.083 就是每個路徑都走過 00:04:42.083 --> 00:04:45.053 顯然,這是有困難度的 00:04:45.053 --> 00:04:48.033 因為所有條件都考慮會造成量呈指數倍數的增加 00:04:48.033 --> 00:04:53.008 況且,通常都很難去評估 00:04:53.008 --> 00:04:55.031 究竟是不是每個路徑都已經測試 00:04:55.031 --> 00:04:57.001 針對這些困難的正規方法,是有的 00:04:57.001 --> 00:04:58.083 它們可以讓你們知道洞在哪 00:04:58.083 --> 00:05:01.031 但是最根本的是 00:05:01.031 --> 00:05:03.004 在大部分的商業軟體公司裡 00:05:03.004 --> 00:05:04.089 對於 C2 有多少價值的觀念 00:05:04.089 --> 00:05:06.070 還不太一致 00:05:06.070 --> 00:05:08.068 就是說,C2 比起 C0 或 C1 究竟有多少價值,還是沒有一個共識 00:05:08.068 --> 00:05:10.013 所以,我認為,這個課程的用意是 00:05:10.013 --> 00:05:11.067 讓你們了解 00:05:11.067 --> 00:05:13.020 怎樣使用測試涵蓋率的資訊 00:05:13.020 --> 00:05:16.040 SimpleCov 利用 Ruby 中的一些功能 00:05:16.040 --> 00:05:18.009 讓你們可以做 C0 測試 00:05:18.009 --> 00:05:19.062 也有很好的報表 00:05:19.062 --> 00:05:21.025 給我們的資訊 00:05:21.025 --> 00:05:22.096 大抵上而言是逐檔案,逐程式行的資訊 00:05:22.096 --> 00:05:24.091 你可以看看你的涵蓋範圍 00:05:24.091 --> 00:05:27.015 我覺得 00:05:27.015 --> 00:05:31.018 這是個很好的開始 00:05:31.018 --> 00:05:33.076 我們已經看了不同種類的測試後 00:05:33.076 --> 00:05:37.020 往回退一步宏觀的看 00:05:37.020 --> 00:05:38.098 我們實際看過的不同的測試 00:05:38.098 --> 00:05:40.078 究竟有那幾種? 00:05:40.078 --> 00:05:42.032 如果使用不同的測試 00:05:42.032 --> 00:05:43.089 各自的缺點又是什麼? 00:05:43.089 --> 00:05:47.016 我們已經看過單一類別和方法的程度 00:05:47.016 --> 00:05:50.009 我們用 RSpec 大量使用了 mocking 和 stubbing 測試 00:05:50.009 --> 00:05:53.004 比如,當我們模型中測試方法 00:05:53.004 --> 00:05:55.057 這是單元測試例子 00:05:55.057 --> 00:05:59.025 我們也完成其他非常像功能或模組測試 00:06:00.097 --> 00:06:02.071 裡面有多個模組 00:06:02.071 --> 00:06:04.065 所以如果我們有了 controller 得規格 00:06:04.065 --> 00:06:07.085 我們看到就模擬 POST 的行為 00:06:07.085 --> 00:06:09.029 但要記住 00:06:09.029 --> 00:06:10.086 送出的 POST 要通過 routing subsystem 才到 controller 00:06:12.042 --> 00:06:14.048 controller 完成後會產出一個 view 00:06:14.048 --> 00:06:16.007 事實上還有其他部分 00:06:16.007 --> 00:06:17.067 會和 controller 一起運作 00:06:17.067 --> 00:06:19.099 使得 controller 規格能通過 00:06:19.099 --> 00:06:21.051 這是裡面的某個部分 00:06:21.051 --> 00:06:23.035 我們在這邊有多個方法用到不只一個類別 00:06:25.000 --> 00:06:27.000 但我們仍要注意 00:06:27.000 --> 00:06:28.088 這只在系統中的一小部分 00:06:28.088 --> 00:06:31.044 我們仍廣泛的用 mocking 以及 stubbing 00:06:31.044 --> 00:06:35.030 把我們想要測試的行為獨立出來 00:06:35.030 --> 00:06:36.091 在 Cucumber 層級的整合或系統測試 00:06:38.047 --> 00:06:41.069 他們測試了程式的全部路徑 00:06:41.069 --> 00:06:43.044 可能也觸及了相當多不同的模組 00:06:43.044 --> 00:06:46.003 最小化使用 mocks 和 stubs 00:06:46.003 --> 00:06:48.032 因為整合測試其中一個目標 00:06:48.032 --> 00:06:50.099 是能確切的測試個區塊之間的相互影響 00:06:50.099 --> 00:06:53.021 所以如果你不想用 stub 或控制這些相互影響 00:06:53.021 --> 00:06:54.080 你想要讓系統執行它就會執行 00:06:56.030 --> 00:06:58.025 如果這是在開發時 00:06:58.025 --> 00:07:00.069 那麼要如何會比較這些不同的測試? 00:07:00.069 --> 00:07:02.038 我們看看這邊有幾個不同的軸 00:07:02.038 --> 00:07:05.007 其中之一是他們需要多長時間運行 00:07:05.007 --> 00:07:06.090 RSpec 和 Cucumber 看似有較高的啟動時間 00:07:09.013 --> 00:07:10.008 但如您所見 00:07:10.008 --> 00:07:11.090 如果加上更多的 RSpec 測試 00:07:11.090 --> 00:07:14.038 並在後臺執行自動測試 00:07:14.038 --> 00:07:17.088 一旦 RSpec 開始 00:07:17.088 --> 00:07:19.092 會執行 specs 相當快 00:07:19.092 --> 00:07:21.095 而 Cucumber 需要很長時間 00:07:21.095 --> 00:07:24.059 因為 Cucumber 觸發了整個應用程式 00:07:24.059 --> 00:07:26.010 這學期末 00:07:26.010 --> 00:07:28.086 我們將會看到讓 Cucumber 更慢 00:07:28.086 --> 00:07:30.070 因為整個瀏覽器內部都要觸發 00:07:30.070 --> 00:07:33.045 就像是傀儡操控 Firefox 00:07:33.045 --> 00:07:35.083 所以可以測試 Javascript 程式 00:07:35.083 --> 00:07:37.000 實際上我們做的 00:07:37.000 --> 00:07:40.032 我們能和朋友們在 SourceLabs 就在雲端裡操作 00:07:40.032 --> 00:07:42.080 真令人興奮 00:07:42.080 --> 00:07:45.083 所以執行的快與慢 00:07:46.068 --> 00:07:48.025 假如單元測試中發生了錯誤 00:07:48.025 --> 00:07:49.075 通常很容易發生 00:07:49.075 --> 00:07:52.029 要找出和追蹤該錯誤的來源 00:07:52.029 --> 00:07:53.071 正是因為獨立測試 00:07:53.071 --> 00:07:56.025 你已經 stub 所以無所謂 00:07:56.025 --> 00:07:58.025 你只專注在感興趣的行為 00:07:58.025 --> 00:07:59.076 如果已經做得很好但是測試時 有些錯誤的地方又發生錯誤 00:08:04.088 --> 00:08:07.041 相反地 如果您用 Cucumber 差不多10個步驟 00:08:08.089 --> 00:08:10.031 每一步都會觸擊到應用程式的一部分 00:08:11.061 --> 00:08:12.091 這就會花很多時間才能找到那個 bug 00:08:14.076 --> 00:08:16.014 所以需要去衡量 能夠涵蓋的錯誤範圍 00:08:20.065 --> 00:08:23.002 如果你寫一個好的套件用來作單元測試和功能測試 00:08:24.072 --> 00:08:26.020 您可以有很高的覆蓋範圍 00:08:26.020 --> 00:08:27.085 您可以產生 SimpleCov 報告 00:08:27.085 --> 00:08:30.080 也可以在檔案中的任何一行沒有側試過的程式碼 00:08:32.036 --> 00:08:34.016 做會涵蓋到這行的測試 00:08:34.016 --> 00:08:36.014 要找出如何改善您的覆蓋範圍 00:08:36.014 --> 00:08:37.057 例如在 C0 能更輕鬆地完成與單元測試 00:08:40.021 --> 00:08:42.018 而 Cucumber 測試會觸擊大量的程式碼 00:08:45.076 --> 00:08:47.080 但你的方法就顯得很少 00:08:47.080 --> 00:08:49.038 所以如果目標是提昇涵蓋範圍 00:08:49.038 --> 00:08:51.031 就用工具來協助單元的層級 00:08:51.031 --> 00:08:53.007 這樣可以更專心去了解程式那邊是不是還沒側過 00:08:54.074 --> 00:08:56.055 然後可以寫相當針對性的測試針對這些部分 00:08:58.086 --> 00:09:01.043 就像把這些部分放在一起做單元測試 00:09:03.039 --> 00:09:05.059 因為這些分離出來測試適合用 mocks 來隔開你不在意的部分 00:09:09.012 --> 00:09:11.020 定義上這意味著不是在測試介面 00:09:12.070 --> 00:09:14.099 而像是在軟體裡有智慧一樣 00:09:14.099 --> 00:09:16.069 很多有趣的錯誤 00:09:16.069 --> 00:09:18.076 發生在各部分間的介面 00:09:18.076 --> 00:09:20.078 (以下尚未處理) 並在類中或在方法內不進行排序的 00:09:20.078 --> 00:09:22.040 那些是有點簡單的 bug,追查 00:09:22.040 --> 00:09:24.026 與在另一個極端 00:09:24.026 --> 00:09:26.081 你越集成測試走向極端 00:09:26.081 --> 00:09:29.072 你應該少依賴類比考試 00:09:29.072 --> 00:09:30.090 這一確切原因 00:09:30.090 --> 00:09:32.066 現在我們看到的如果你在測試類似 00:09:32.066 --> 00:09:34.015 也就是說,在面向服務的體系結構 00:09:34.015 --> 00:09:35.089 你要在其上與遠端網站進行交互 00:09:35.089 --> 00:09:37.028 你最終仍 00:09:37.028 --> 00:09:38.094 不必做了相當大的嘲弄、 鉗 00:09:38.094 --> 00:09:40.028 這樣,你不要依賴互聯網 00:09:40.028 --> 00:09:41.067 為了使您的測試通過 00:09:41.067 --> 00:09:43.006 但是,總體上說 00:09:43.006 --> 00:09:47.014 你想盡可能多的類比考試,您可以刪除 00:09:47.014 --> 00:09:48.095 而讓系統運行的方式,它將運行在現實生活中 00:09:48.095 --> 00:09:52.070 所以,好消息是你 * 是 * 測試介面 00:09:52.070 --> 00:09:54.074 * 但 * 當事情出錯在一個介面 00:09:54.074 --> 00:09:57.053 因為您的解析度不是那麼好 00:09:57.053 --> 00:10:00.031 可能需要很長時間弄清楚它是什麼 00:10:00.031 --> 00:10:05.019 那麼,什麼是某種程度的高階位從折 00:10:05.019 --> 00:10:07.024 是你真的不想依賴 00:10:07.024 --> 00:10:08.076 太重上任何一種測試 00:10:08.076 --> 00:10:10.078 他們為不同的目的和具體取決於服務上 00:10:10.078 --> 00:10:13.043 你想行使您更多的介面 00:10:13.043 --> 00:10:15.089 或你想提高你的細細微性覆蓋率 00:10:15.089 --> 00:10:18.003 這會影響你如何發展你的測試套件 00:10:18.003 --> 00:10:20.065 和你就會把它演進隨您的軟體 00:10:20.065 --> 00:10:24.014 因此,我們使用一組特定的測試中的術語 00:10:24.014 --> 00:10:26.028 它是術語到,通過和大 00:10:26.028 --> 00:10:29.001 最常用的 Rails 社區 00:10:29.001 --> 00:10:30.060 但有一些變化 00:10:30.060 --> 00:10:33.069 [和] 你可能會聽到的一些其他術語 00:10:33.069 --> 00:10:35.018 如果你去找一份工作的某個地方 00:10:35.018 --> 00:10:36.093 你聽到有關變異測試 00:10:36.093 --> 00:10:38.072 我們還沒有用過 00:10:38.072 --> 00:10:40.024 這是一個有趣的想法,我認為,發明的 00:10:40.024 --> 00:10:43.037 維與駕駛艙,有,排序的 00:10:43.037 --> 00:10:44.093 軟體測試的通用書 00:10:44.093 --> 00:10:46.048 這個想法是: 00:10:46.048 --> 00:10:48.000 假設我向我的代碼提交蓄意的 bug 00:10:48.000 --> 00:10:49.051 這不會迫使一些測試失敗嗎? 00:10:49.051 --> 00:10:53.003 因為,如果我改變,你知道,"如果 x"到"如果不 x" 00:10:53.003 --> 00:10:56.010 並沒有測試失敗,然後要麼我的思念一些報導 00:10:56.010 --> 00:10:59.019 或我的應用程式是非常奇怪和不知何故不確定性 00:10:59.019 --> 00:11:03.099 模糊測試,其中 Koushik 森可能更詳細地談 00:11:03.099 --> 00:11:07.085 基本上,這就是"10,000 猴子在打字機 00:11:07.085 --> 00:11:09.024 在您的代碼中扔隨機輸入" 00:11:09.024 --> 00:11:10.037 有趣的是, 00:11:10.037 --> 00:11:11.065 我們一直在做這些測試 00:11:11.065 --> 00:11:13.086 基本上是精心編制來測試應用程式 00:11:13.086 --> 00:11:15.058 它設計的方法 00:11:15.058 --> 00:11:16.088 和這些,你知道,模糊測試 00:11:16.088 --> 00:11:19.064 有關測試應用程式的方式是它 * 不是 *,可使用 00:11:19.064 --> 00:11:22.098 所以,如果會發生什麼你扔巨大表單提交 00:11:22.098 --> 00:11:25.036 如果你把控制字元放在您的表單中,將會發生什麼? 00:11:25.036 --> 00:11:27.062 如果您反復提交同樣的事情,會發生什麼? 00:11:27.062 --> 00:11:29.093 Koushik 有一個統計資料, 00:11:29.093 --> 00:11:32.033 微軟認定他們的 bug 的 20 % 00:11:32.033 --> 00:11:34.064 使用一些變異的模糊化測試 00:11:34.064 --> 00:11:36.029 和,約 25 % 00:11:36.029 --> 00:11:39.021 常見的 Unix 命令列程式的 00:11:39.021 --> 00:11:40.092 可以向崩潰 00:11:40.092 --> 00:11:44.018 [當] 把侵略性模糊測試通過 00:11:44.018 --> 00:11:46.089 定義使用覆蓋範圍是我們還沒有完成的事情 00:11:46.089 --> 00:11:48.089 但它是另一個有趣的概念 00:11:48.089 --> 00:11:50.089 我的程式在任何一點的設想是, 00:11:50.089 --> 00:11:52.062 有一個地方,我的定義 — — 00:11:52.062 --> 00:11:54.046 或賦值給一些變數 — — 00:11:54.046 --> 00:11:56.000 然後還有下游的地方 00:11:56.000 --> 00:11:57.075 大概我的去向消費的價值 — — 00:11:57.075 --> 00:11:59.058 有人要使用此值 00:11:59.058 --> 00:12:01.013 我已覆蓋每一對嗎? 00:12:01.013 --> 00:12:02.059 換句話說,做有測試在每一對 00:12:02.059 --> 00:12:04.054 定義一個變數和某個地方使用它 00:12:04.054 --> 00:12:07.014 在我的測試套件的某些部分執行 00:12:07.014 --> 00:12:10.071 它有時被稱為杜覆蓋範圍 00:12:10.071 --> 00:12:14.011 其他條件,我認為不廣泛地不再使用 00:12:14.011 --> 00:12:17.071 與白牌或與 glassbox 黑匣子黑匣子 00:12:17.071 --> 00:12:20.025 大致上黑匣子測試是一個從寫入 00:12:20.025 --> 00:12:22.041 事物的外部規範的角度來看 00:12:22.041 --> 00:12:24.022 [例如:]"這是一個雜湊表 00:12:24.022 --> 00:12:26.015 當我把放在一個鍵時應回到一個值 00:12:26.015 --> 00:12:28.011 如果刪除了關鍵值不存在" 00:12:28.011 --> 00:12:29.099 這是一個黑匣子測試,因為它並沒有說 00:12:29.099 --> 00:12:32.028 任何有關該雜湊表如何實施的 00:12:32.028 --> 00:12:34.072 和它不會嘗試狠抓落實 00:12:34.072 --> 00:12:36.056 相應的白牌測試可能是: 00:12:36.056 --> 00:12:38.008 "我知道些什麼雜湊函數 00:12:38.008 --> 00:12:39.098 和我要去刻意製造 00:12:39.098 --> 00:12:41.088 我的測試用例中的雜湊鍵 00:12:41.088 --> 00:12:43.078 這造成了大量的散列碰撞 00:12:43.078 --> 00:12:45.095 以確保我正在測試的功能,部分" 00:12:45.095 --> 00:12:49.007 現在,C0 測試覆蓋工具,像 SimpleCov 00:12:49.007 --> 00:12:52.001 將顯示,如果你有的只是黑匣子測試 00:12:52.001 --> 00:12:53.028 您可能會發現, 00:12:53.028 --> 00:12:55.056 碰撞覆蓋代碼不是很多時候被撞傷 00:12:55.056 --> 00:12:56.075 ,可能會提示您,然後說: 00:12:56.075 --> 00:12:58.028 "好的如果我真的要加強,— — 00:12:58.028 --> 00:13:00.008 第一,如果我想要提高這些測試的覆蓋範圍 00:13:00.008 --> 00:13:02.006 現在要寫白牌或 glassbox 測試 00:13:02.006 --> 00:13:04.057 我要向內看看,請參閱執行什麼呢 00:13:04.057 --> 00:13:05.061 並找到具體的方法 00:13:05.061 --> 00:13:10.060 試圖打破邪惡的方式實施" 00:13:10.060 --> 00:13:13.075 所以,我認為,測試是一種生活方式,正確嗎? 00:13:13.075 --> 00:13:16.069 我們已經遠離的階段 00:13:16.069 --> 00:13:18.033 "我們將建立整個事情,然後,我們將考驗" 00:13:18.033 --> 00:13:19.092 和我們已經進入的階段 00:13:19.092 --> 00:13:20.077 "我們測試我們看一下" 00:13:20.077 --> 00:13:22.048 測試是真的更像是一種發展工具 00:13:22.048 --> 00:13:24.022 像這麼多的開發工具 00:13:24.022 --> 00:13:25.062 它的效力取決於 00:13:25.062 --> 00:13:27.013 不管你雅致的方式使用上 00:13:27.013 --> 00:13:31.002 所以,你會說:"好吧,讓我們看看 — — 我踢了輪胎 00:13:31.002 --> 00:13:33.048 你知道,我解雇了流覽器,我試過幾件事情 00:13:33.048 --> 00:13:35.097 (鮮花手)它工作起來 !部署它 !" 00:13:35.097 --> 00:13:38.045 這顯然不是你想要的多一點騎士 00:13:38.045 --> 00:13:41.024 通過的路上,我們發現的事情之一 00:13:41.024 --> 00:13:43.077 與剛剛起步的此線上課程 00:13:43.077 --> 00:13:45.090 當 60000 人參加課程 00:13:45.090 --> 00:13:48.099 和那些人的 0.1%有問題 00:13:48.099 --> 00:13:50.083 你就可以得到 60 電子郵件 00:13:50.083 --> 00:13:53.078 必然結果是: 當您的網站使用的很多人 00:13:53.078 --> 00:13:55.089 你沒有找到一些愚蠢的 bug 00:13:55.089 --> 00:13:57.018 但是,可以通過測試來找 00:13:57.018 --> 00:13:59.080 可以非常迅速生成 * 多 * 的痛 00:13:59.080 --> 00:14:02.023 另一方面,你不想被教條和說 00:14:02.023 --> 00:14:04.056 "呃,直到我們有 100%的覆蓋率和每個測試是綠色 00:14:04.056 --> 00:14:06.005 我們絕對會不船舶" 00:14:06.005 --> 00:14:07.012 這也是不健康 00:14:07.012 --> 00:14:08.048 和測試品質 00:14:08.048 --> 00:14:10.057 不一定相符的發言 00:14:10.057 --> 00:14:11.064 除非你可以說 00:14:11.064 --> 00:14:12.068 關於你的測試品質 00:14:12.068 --> 00:14:14.029 只是因為你已經執行的每一條線 00:14:14.029 --> 00:14:17.010 並不意味著你測試過的有趣的案件 00:14:17.010 --> 00:14:18.068 所以,某處之間,你會說 00:14:18.068 --> 00:14:20.014 "嗯,我們可以使用覆蓋工具來標識 00:14:20.014 --> 00:14:23.004 undertested 或差測試代碼的部分 00:14:23.004 --> 00:14:24.073 我們將使用它們作為指引 00:14:24.073 --> 00:14:27.011 要排序的説明改善我們的總體信心水準" 00:14:27.011 --> 00:14:29.024 但請記住,敏捷開發是擁抱變化 00:14:29.024 --> 00:14:30.032 它的處理 00:14:30.032 --> 00:14:32.002 更改的部分是事情會改變,將導致 00:14:32.002 --> 00:14:33.038 你沒有預見到的 bug 00:14:33.038 --> 00:14:34.031 和正確的反應就是: 00:14:34.031 --> 00:14:36.026 能自在的測試工具 00:14:36.026 --> 00:14:37.064 [這樣] 您可以快速找到這些 bug 00:14:37.064 --> 00:14:39.025 寫一個轉載了這個 bug 的測試 00:14:39.025 --> 00:14:40.062 然後進行測試綠色 00:14:40.062 --> 00:14:41.061 然後你就會真的改變它 00:14:41.061 --> 00:14:43.004 這意味著,您真的修復 bug 的方式是 00:14:43.004 --> 00:14:45.049 如果您創建了一個正確的失敗的測試 00:14:45.049 --> 00:14:46.088 重現這個 bug 00:14:46.088 --> 00:14:48.055 然後回到了並修復該代碼 00:14:48.055 --> 00:14:49.057 使這些測試通過 00:14:49.057 --> 00:14:51.073 同樣的你不想說 00:14:51.073 --> 00:14:53.036 "嗯,單元測試給你更好的覆蓋範圍 00:14:53.036 --> 00:14:54.073 他們是更徹底和詳細 00:14:54.073 --> 00:14:56.044 所以讓我們專注,我們所有的能量" 00:14:56.044 --> 00:14:57.062 而不是 00:14:57.062 --> 00:14:58.093 "哦,重點集成測試 00:14:58.093 --> 00:15:00.006 因為他們更切合實際,對不對? 00:15:00.006 --> 00:15:01.056 它們反映了客戶說他們想要什麼 00:15:01.056 --> 00:15:03.034 因此,如果通過集成測試 00:15:03.034 --> 00:15:05.067 通過定義我們滿足客戶需求" 00:15:05.067 --> 00:15:07.034 同樣,這兩個極端都有點不健康 00:15:07.034 --> 00:15:09.079 因為其中的每一個可以找出問題 00:15:09.079 --> 00:15:11.031 這將由其他忽略了 00:15:11.031 --> 00:15:12.060 所以,有好的結合 00:15:12.060 --> 00:15:15.042 就是有點全部是所有關于 00:15:15.042 --> 00:15:18.072 我想要留給你們的最後一件事是,我認為 00:15:18.072 --> 00:15:20.036 方面的測試,是"與拓展署 00:15:20.036 --> 00:15:22.005 所謂傳統的調試 — — 00:15:22.005 --> 00:15:24.004 即,我們都有點做的方式 00:15:24.004 --> 00:15:25.051 儘管我們說我們不要" 00:15:25.051 --> 00:15:26.064 和我們都試圖右好轉嗎? 00:15:26.064 --> 00:15:27.085 我們所有的在裝訂線 00:15:27.085 --> 00:15:29.036 我們中的一些正仰望星空 00:15:29.036 --> 00:15:31.011 努力提高我們的實踐 00:15:31.011 --> 00:15:33.099 但現在住這 3 或 4 年我自己 00:15:33.099 --> 00:15:35.091 和 — — 要老實 — 3 年前我沒做拓展署 00:15:35.091 --> 00:15:37.079 我現在就做,因為我發現它是更好 00:15:37.079 --> 00:15:40.081 這裡是我蒸餾的所以,我覺得很管用 00:15:40.081 --> 00:15:43.032 很抱歉,顏色是有點怪異 00:15:43.032 --> 00:15:45.000 但在左邊的列的表的 00:15:45.000 --> 00:15:46.034 [它] 說"常規調試" 00:15:46.034 --> 00:15:47.044 右側說"拓展署" 00:15:47.044 --> 00:15:49.069 所以我用來編寫代碼的方法是什麼? 00:15:49.069 --> 00:15:51.056 也許你們中的一些仍然這樣做 00:15:51.056 --> 00:15:53.013 我寫了一大堆的行 00:15:53.013 --> 00:15:54.043 也許我們只剩下幾十行代碼 00:15:54.043 --> 00:15:55.059 我是 * 確保 * 他們正確 — — 00:15:55.059 --> 00:15:56.061 我的意思是,我 * am * 一個好的程式師,正確嗎? 00:15:56.061 --> 00:15:57.099 這並不難 00:15:57.099 --> 00:15:59.002 我運行它 — — 它不起作用 00:15:59.002 --> 00:16:01.098 好的調試器點燃 — — 將 printf 的開始 00:16:01.098 --> 00:16:04.088 如果就已經使用 TDD 將我做什麼而是? 00:16:04.088 --> 00:16:08.022 嗯,我會寫 * 幾 * 行代碼,第一次寫了一個測試 00:16:08.022 --> 00:16:10.071 所以儘快把測試從紅色變為綠色 00:16:10.071 --> 00:16:12.064 我知道我寫了代碼的工作 — — 00:16:12.064 --> 00:16:15.013 或者至少,我原本想的行為的部件 00:16:15.013 --> 00:16:16.096 行為的那些部分工作,因為我有一個測試 00:16:16.096 --> 00:16:19.056 好的回傳統的調試: 00:16:19.056 --> 00:16:21.073 我正在我的程式試圖找到的 bug 00:16:21.073 --> 00:16:23.028 我開始把 printf 的無處不在 00:16:23.028 --> 00:16:24.062 可以列印出來的東西值 00:16:24.062 --> 00:16:25.064 方式是很有趣 00:16:25.064 --> 00:16:26.073 當你想閱讀這些 00:16:26.073 --> 00:16:28.014 日誌輸出的 500 線出來的 00:16:28.014 --> 00:16:29.035 你會得到一個 Rails 應用程式中 00:16:29.035 --> 00:16:30.087 試圖找到 * 你 * printf 的 00:16:30.087 --> 00:16:32.035 你知道,"我知道我要做 — — 00:16:32.035 --> 00:16:34.008 我要把放在 75 星號之前和之後 00:16:34.008 --> 00:16:36.043 這將使可讀"(笑聲) 00:16:36.043 --> 00:16:38.071 誰不要 — — 好吧,提高你的手,如果你不這樣做 ! 00:16:38.071 --> 00:16:40.090 謝謝你的誠實。(笑聲)還行。 00:16:40.090 --> 00:16:43.014 或 — — 或者我可以做其他事情,我可以說: 00:16:43.014 --> 00:16:45.030 列印變數的值而不是 00:16:45.030 --> 00:16:47.039 為什麼不寫檢查它的測試 00:16:47.039 --> 00:16:48.079 在這樣的期望應該 00:16:48.079 --> 00:16:50.090 我立即知道在明亮的紅色字母 00:16:50.090 --> 00:16:53.033 如果不滿足這一期望 00:16:53.033 --> 00:16:56.005 好的我對常規調試側: 00:16:56.005 --> 00:16:58.090 我打破出殺手鐧: 我拉出 Ruby 調試器 00:16:58.092 --> 00:17:02.044 我設置調試中斷點,和我現在開始 * 調整 * 說 00:17:02.044 --> 00:17:04.085 "哦,讓我們看看,我要讓過去的 if 語句 00:17:04.085 --> 00:17:06.002 所以要設置的那個東西 00:17:06.002 --> 00:17:07.063 哦,我要調用該方法,所以我需要 to…" 00:17:07.063 --> 00:17:08.065 不 ! 00:17:08.065 --> 00:17:10.087 我 * 能 * 相反 — — 如果我要去做,不管怎麼說 — — 00:17:10.087 --> 00:17:13.000 讓我們在檔中設置一些類比考試和存根,只是做 00:17:13.000 --> 00:17:16.045 若要控制的代碼路徑,讓它就這樣的方式 00:17:16.045 --> 00:17:19.013 現在,"好吧,肯定我已經固定它 ! 00:17:19.013 --> 00:17:22.012 我給出的調試器,運行它所有再次 !" 00:17:22.012 --> 00:17:24.022 並且,當然,9 次滿分,你並沒有解決它 00:17:24.022 --> 00:17:26.072 或你的部分原因是固定的它,但你並沒有完全修復, 00:17:26.072 --> 00:17:30.040 現在我再做這些手動都有 00:17:30.040 --> 00:17:32.086 * 或 * 我已經有一堆的測試 00:17:32.086 --> 00:17:34.031 和我可以自動他們重新 00:17:34.031 --> 00:17:35.056 可以,如果有些人不和 00:17:35.056 --> 00:17:36.087 "哦,我未修復整件事 00:17:36.087 --> 00:17:38.040 沒問題,我只是去回來 !" 00:17:38.040 --> 00:17:39.096 所以,底線是, 00:17:39.096 --> 00:17:41.095 你知道,你 * 能 * 做它的左側 00:17:41.095 --> 00:17:45.004 但在這兩種情況中使用相同的技術 00:17:45.004 --> 00:17:48.062 唯一不同的是,在一個案例中你正在手動 00:17:48.062 --> 00:17:50.004 這是無聊且容易出錯 00:17:50.004 --> 00:17:51.078 在其他情況下你做一些更多的工作 00:17:51.078 --> 00:17:53.095 但您可以使它自動和可重複 00:17:53.095 --> 00:17:55.071 有,你知道,一些高信心 00:17:55.071 --> 00:17:57.003 當您更改您的代碼中的東西 00:17:57.003 --> 00:17:58.092 你不打破過去工作的東西 00:17:58.092 --> 00:18:00.091 基本上,這是提高工作效率 00:18:00.091 --> 00:18:02.047 所以你正在做的事情都一樣 00:18:02.047 --> 00:18:04.037 但有一種"三角"額外工作 00:18:04.037 --> 00:18:07.086 您正在使用你的努力在多高的杠杆 00:18:07.086 --> 00:18:10.036 這樣說是我認為的種 TDD 是一件好事 00:18:10.036 --> 00:18:11.088 這是真的,這不需要新的技能 00:18:11.088 --> 00:18:15.011 它僅僅需要 [你] 重構您現有的技能 00:18:15.011 --> 00:18:18.014 也嘗試過當我 — — 再次,誠實口供,正確嗎? — — 00:18:18.014 --> 00:18:19.034 當我開始做這就像 00:18:19.034 --> 00:18:21.049 "好吧,我會在滑軌上的課程教學 00:18:21.049 --> 00:18:22.065 我真的應該集中測試 00:18:22.065 --> 00:18:24.032 所以我回到我寫了一些代碼 00:18:24.032 --> 00:18:26.087 那是 * 工作 * — — 你知道,那是體面的代碼 — — 00:18:26.087 --> 00:18:29.006 然後我就開始努力為它編寫測試 00:18:29.006 --> 00:18:31.019 它是 * 那麼痛苦 * 00:18:31.019 --> 00:18:33.033 因為是可測試的方式並不編寫代碼 00:18:33.033 --> 00:18:34.097 有各種各樣的交互 00:18:34.097 --> 00:18:36.038 比如有嵌套的條件陳述式 00:18:36.038 --> 00:18:38.083 如果你想要找出特定語句 00:18:38.083 --> 00:18:41.070 並將它測試 — — 到觸發器測試 — — 只是該聲明 00:18:41.070 --> 00:18:44.000 你會在您測試設置的東西量 00:18:44.000 --> 00:18:45.009 發生 — — 00:18:45.009 --> 00:18:46.040 請記住,當談到類比火車殘骸 — — 00:18:46.040 --> 00:18:48.014 您必須設置所有此基礎結構 00:18:48.014 --> 00:18:49.063 只是為了得到 * 一個 * 代碼行 00:18:49.063 --> 00:18:51.015 和你這麼做了,你走 00:18:51.015 --> 00:18:52.074 "Gawd,測試是真的不值得 ! 00:18:52.074 --> 00:18:54.034 我寫了 20 條線的安裝 00:18:54.034 --> 00:18:56.059 這樣我可以測試兩行在函數中我 !" 00:18:56.059 --> 00:18:58.085 真正帶告訴你 — — 我現在意識到 — — 00:18:58.085 --> 00:19:00.042 是你的函數是 * 壞 * 00:19:00.042 --> 00:19:01.049 它是一個嚴重的書面的函數 00:19:01.049 --> 00:19:02.052 它不是一個可測試函數 00:19:02.052 --> 00:19:03.088 它有太多的移動部件 00:19:03.088 --> 00:19:06.026 相關性的 * 可 * 被打破 00:19:06.026 --> 00:19:07.070 我的功能中有無接縫 00:19:07.070 --> 00:19:11.008 這使我單獨測試不同的行為 00:19:11.008 --> 00:19:12.083 一旦你開始做測試第一次開發 00:19:12.083 --> 00:19:15.043 因為你要的小塊寫你的測試 00:19:15.043 --> 00:19:17.053 它使解決這個問題 00:19:17.053 --> 99:59:59.999 所以,這一直是我的頓悟