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