Slide 1

Slide 1 text

Unit Test 簡介 Elvis Lin 2017-07-06 @KKday

Slide 2

Slide 2 text

關於測試 • 測試個概念念與定義 • 測試的分類 • End-to-End Test • Integration Test • Unit Test • 測試循環:使⽤用 BDD 結合 TDD • 單元測試的實作 • 驗收測試的實作

Slide 3

Slide 3 text

這次分享的重點 • 測試個概念念與定義 • 測試的分類 • 測試循環:使⽤用 BDD 結合 TDD •單元測試的實作 • 驗收測試的實作

Slide 4

Slide 4 text

傳統的測試流程 • ⼈人⼯工測試 • 屬於整合測試或 End-to-End 測試 • 集中在軟體開發完成之後 • ……

Slide 5

Slide 5 text

⼈人⼯工測試

Slide 6

Slide 6 text

傳統測試流程的問題 • 環境準備的時間比較長 • 執⾏行行測試的時間比較長 • 難以保證每次測試的操作都相同 • 發現錯誤後,除錯的時間比較長

Slide 7

Slide 7 text

漫長的等待

Slide 8

Slide 8 text

如何減少等待的時間 • 撰寫腳本讓⼈人⼯工操作變成⾃自動化的操作 • 撰寫⼤大量量的單元測試,讓問題在開發初期就可 以被發現

Slide 9

Slide 9 text

Unit Test

Slide 10

Slide 10 text

什什麼是單元測試 • 情侶間的單元測試: • 傳 Line 訊息,測 input 跟 output • 情侶間的整合測試 • ⼀一起出去玩 — 來來源

Slide 11

Slide 11 text

什什麼是單元測試 • 測試軟體系統的最⼩小單元 • Method 或 Function • Class 或 Object • 某組⾏行行為

Slide 12

Slide 12 text

測試的流程 • (準備相關的資料與執⾏行行環境) • 執⾏行行要被測試的程式碼 • 檢查程式執⾏行行的結果是否符合預期

Slide 13

Slide 13 text

單元測試範例例1 • Production Code
 
 
 • Test Code
 
 
 
 


Slide 14

Slide 14 text

單元測試範例例2

Slide 15

Slide 15 text

3A • Arrange — 準備需要的資料 • Action — 執⾏行行被測試的程式 • Assert — 驗證執⾏行行的結果

Slide 16

Slide 16 text

3A — 範例例說明 @Test
 public void testPop() {
 // Arrange
 // 準備⼀一個 Stack,在裡⾯面放入幾筆資料
 Stack stack = new Stack<>();
 stack.push("teddy");
 stack.push("kay");
 stack.push("eiffel"); // Action
 // 再放入⼀一筆資料
 stack.push(“ada");
 
 // Assert
 // 取出最後⼀一筆資料,確認是否等於剛剛放入的資料
 assertEquals("ada", stack.pop());
 }

Slide 17

Slide 17 text

真實的範例例 https://github.com/square/retrofit/tree/ master/samples

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

如何測試這段程式?

Slide 20

Slide 20 text

直接檢查 console 的輸出

Slide 21

Slide 21 text

延伸思考 •如果測試的時候沒有網路路怎麼辦? •如果輸出不是輸出到 console,⽽而是某個 GUI 的介 ⾯面怎麼辦?

Slide 22

Slide 22 text

原本的程式流程 System.out Main() Retrofit 取回 Contributor 輸出 Contributor

Slide 23

Slide 23 text

修改後的程式流程 Contributor Presenter Contributor App Contributor Manager 取回 Contributor 輸出 Contributor

Slide 24

Slide 24 text

修改後的程式流程 • ContributorManager — 使⽤用 retrofit 取得 contributor 的資訊 • ContributorPresenter — 在螢幕上顯⽰示 contributor 的資 訊 • ContributorApp — 使⽤用 ContributorManager 跟 ContributorPresenter 取得並顯⽰示 contributor 的資訊

Slide 25

Slide 25 text

新的架構 Contributor
 App Contributor
 Manager Contributor
 Presenter ContributorApp(manager, presenter) Main()

Slide 26

Slide 26 text

ContributorManager

Slide 27

Slide 27 text

ContributorPresenter

Slide 28

Slide 28 text

ContributorApp

Slide 29

Slide 29 text

如何對 ContributorApp 測試 • 建立 MockContributorManager 實作 ContributorManager • 建立 MockContributorPresenter 實作 ContributorPresenter • 當建立 ContributorApp 時,使⽤用剛剛建立的 test double • 執⾏行行 ContributorApp.execute(),檢查執⾏行行的結果

Slide 30

Slide 30 text

Demo 程式碼:https://goo.gl/ZHjRhk

Slide 31

Slide 31 text

咦,這樣好像在測假的? 假的!

Slide 32

Slide 32 text

使⽤用單元測試的理理由 • 使⽤用 Mock 隔離不相⼲干的程式碼 • ContributorApp 的邏輯可能很複雜 • 之後可能包含 filter 的邏輯等... • 測試執⾏行行的時間可以很短

Slide 33

Slide 33 text

還是可以⽤用整合測試補⾜足

Slide 34

Slide 34 text

Testability

Slide 35

Slide 35 text

讓程式更更具備可測試性 •關注點分離 •依賴注入

Slide 36

Slide 36 text

關注點分離 • 類似「單⼀一職責原則」 • ⼀一個物件負責⼀一件事,要避免⼀一個物件擁有太多職責 • Wiki: https://en.wikipedia.org/wiki/ Separation_of_concerns

Slide 37

Slide 37 text

依賴注入 • 物件中所有使⽤用的其他物件不是由⾃自⼰己⽣生成,⽽而是透過外 部⽣生成後注入 • Wiki: https://en.wikipedia.org/wiki/Dependency_injection

Slide 38

Slide 38 text

參參考資料 • 搞笑談軟⼯工
 http://teddy-chen-tw.blogspot.tw/search/label/ %E6%B8%AC%E8%A9%A6 • 三⼗十天快速上⼿手TDD
 https://dotblogs.com.tw/hatelove/series/1? qq=30%E5%A4%A9%E5%BF%AB%E9%80%9F%E4%B8%8 A%E6%89%8BTDD

Slide 39

Slide 39 text

讀書會推廣 • 預計時間:每週⼀一 19:00 ~ 20:00 @2F會議室 • 書籍:暫定「Work Effectively with Legacy Code」