Brian的雜記
  • Introduction
  • Brian's 雜記
    • My Awesome API
    • FB 大頭貼
    • 硬體雜記
    • PHP
    • project
      • 模擬器
      • WAMP
    • WinMerge
    • 雜記
      • LINQ
      • 方法
      • Grid View
      • namespace
      • global
      • 物件導向
      • Excel
      • VS2017
      • single sign on
      • Master
      • Https
      • 憑證
      • 略過憑證不符
      • NLog
      • 團隊開發
      • .NET Core
      • 共用網路上的芳鄰
      • 爬蟲
      • NPOI
      • RSS
      • 多執行緒
      • 記憶體回收
      • 密碼學
        • BCrypt
        • AES
      • 主機環境建置
      • Session
      • Error
      • IIS 相關
      • 無障礙相關
      • 介面
        • 影像地圖
      • telnet
        • smtp
      • nslookup
      • 協助客戶解決問題
      • 驗證欄位
      • 網站管理
      • 工具整理
    • 正規表示法
    • 影像處理
    • IntelliJ Idea
    • 觀念
      • Clean Code
        • 命名
        • 函式
        • 註解
        • 編排
        • 物件及資料結構
        • 錯誤處理
        • 邊界
        • 單元測試
        • 類別
      • Java 程式風格
      • Design Pattern
        • 單例模式
      • 同步
      • 畫圖
        • ER-Model
        • 類別圖
        • Use Case
        • 有限狀態機
      • 資料 API 文件 分析
      • CORS & SSL
      • 利用DISC幫助溝通
      • OAS
    • 檔案上傳
      • FileStore
      • App Engine
      • Google Storage
    • OAuth vs Open ID
    • MIME
    • 虛擬桌面
    • 待看資料
    • Selenium
    • CDN
    • HTTP
    • 編碼
    • 2nd-ML100Days
      • jupyter
    • 微服務
      • 設計
        • 1 ~ 5
        • 6
        • 7
        • 8
        • 9
    • Gradle
    • Maven
    • Error
    • 批次檔 BAT
    • Kurento
    • WebSocket & WebRTC
  • 需求面能力
    • User Story
  • Google Cloud Platform
    • Compute Engine
  • Python
    • 基本語法
    • Pandas
    • 套件
    • Matplotlib
    • Encoder
    • jupyter
  • Java
    • Java
      • File
      • Exception
      • 物件導向觀念
      • 加密
      • HTTP
      • 集合
      • Stream()
      • Web
      • ResultSet
      • JDK6
      • JDK8
    • 讀取、複寫MP3 Tag
    • Log4j2
    • Servlet
      • 容器
    • JSP
    • JBOSS
    • JWT
    • PreparedStatement
    • Error
    • Spring
      • Spring Boot
        • @Value
        • Build
      • RequestParameter
      • Error
      • Autowired
      • JPA
      • FeignClient
      • WebSocket
      • thymeleaf
      • Security
      • Test
      • Scheduled
      • Redirect
    • IntelliJ
  • Linux
    • Linux
    • Shell Script
    • Cygwin(在Windows執行Linux指令)
  • 前端
    • HTML
      • Link
    • CSS
      • Position
      • padding color
      • display
    • JS
      • jQuery
        • Select2
      • fancybox
      • ES6
      • 效能
      • GoogleMap API
        • Marker
        • InfoWindow
      • 事件
      • CKEditor
      • TGOS
      • JSON
      • QRcode
      • 核心概念
        • 物件 變數 型別
          • number
          • String
          • boolean
          • null & undefined
          • Symbol
        • JS 物件概念
        • 深入理解JS 函式物件
        • 更多ES2015/ES6 全新語言特性
      • Promise
    • 效果應用
  • 資料庫
    • 注意事項
    • MariaDB
    • MySQL
      • inner join 和 join
      • 字串比對
      • 倒數資料
    • SQL
      • DDL 資料定義語言
      • DML 資料操縱語言
      • DCL 資料控制語言
      • TCL 交易控制語言
      • T-SQL
      • CTE
      • JOIN
    • Oracle
    • MSSQL 操作
      • 新增使用者
      • SQL 指令
      • Sequence
    • 差異比較
    • MyBatis
    • Workbench 操作
    • SQL Injection
  • 版本控制
    • Gitlab
      • sign up
      • sign in
      • add project
      • add members
    • SourceGit
      • install
    • SmartGit
      • install
      • operate
      • git 操作雜記
    • TortoiseGit
    • Git
    • TFS
    • SVN
  • Test
    • 軟體測試原則
    • 演算法
    • XMind
      • install
    • Jenkins
      • 建置
    • HTTPie
    • Postman
    • 測試驅動開發
    • 撰寫測試的觀念
    • 測試框架
    • IoC & DI
    • 隔絕相依性的方式
    • JUnit
    • NUnit
    • 習慣
    • 虛設常式
  • Angular
    • hello world
    • ng-options
    • ES6
    • Build & Conponect
    • HttpClient
    • 部署
  • ASP.NET Web Form
    • Chapter 2
      • 2-1
        • 小東西
    • 略過請求驗證
  • Go
Powered by GitBook
On this page
  • 單元測試
  • TDD的三大法則
  • 讓測試程式整潔
  • 整潔的測試
  • 可讀性
  • 可讀性
  • 可讀性
  • 建造-操作-檢查
  • 特定領域的測試語言
  • 雙重標準
  • 一個測試一個斷言(Assert) *
  • 一個測試一個概念
  • F.I.R.S.T.
  • 總結

Was this helpful?

  1. Brian's 雜記
  2. 觀念
  3. Clean Code

單元測試

單元測試

一但有一套已通過的測試程式,要確保任何需要使用到程式碼的人,都可以方便的使用這些測試程式。 也要確認測試程式和程式碼被包在同一個套件內。

TDD的三大法則

第一法則:在撰寫一個單元測試前,不可撰寫任何產品程式。

第二法則:只撰寫剛好無法通過的單元測試,不能編譯也算無法通過。

第三法則:只撰寫剛好能通過當前測試失敗的產品程式。

倘若像這樣子寫程式,會被限制在一個約30秒的循環內,測試程式和產品程式是一起被撰寫的:測試只比產品早一點撰寫而已。

倘若這樣寫,每天會產生許多的測試程式,日積月累會產生令人卻步的管理問題。

讓測試程式整潔

倘若認為 測試程式 < 產品程式,而輕率、隨便的話,測試程式的可讀性越差,就越難修改。

由於測試程式有可能因為產品的演進而修改,當測試程式無法維護後,就只能整個拋棄。

而一旦拋棄測試程式,就會導致不敢修改產品程式,因為修改了這個,不知道會導致哪裡出問題,最後就整組壞光光

測試程式是用來保障產品程式的擴充、彈性、再利用性,有個好的測試程式,才能安心的改產品程式。

而好的測試程式,當然也要整潔,它和產品程式同樣重要。

不論產品程式的設計多麼好,沒有了測試,你將不願意改變,因為你害怕會導致其他尚未察覺的錯誤。

整潔的測試

是什麼造就了一個整潔的測試?

三件事

可讀性

可讀性

可讀性

超重要說三次(被揍)

可讀性在單元測試裡可能比產品程式還重要。

是什麼讓測試程式具有可讀性?

答案和讓所有程式具有可讀性一樣:

闡明性(clarity) 簡明性(simplicity) 言簡意賅的表達力(density of expression)

在一個測試程式裡,應該盡可能用最少的表達式來產生豐富的說明。

建造-操作-檢查

去參考 Test > JUnit 的 3A法則。

操作這些測試資料以後,是否產生預期的結果。

特定領域的測試語言

有時候測試程式過於繁瑣、太著重在細節,導致不易閱讀,而為了閱讀必須去了解細節。 這時候可以重構,建立一個特定領域的語言,藉此表達在做的事情。

這種語言並不是程式設計師拿來操縱系統的API,而是建立起一連串的函式和公用程式,來間接使用那些操縱系統的API,讓我們的測試程式更容易閱讀。

雙重標準

由於測試環境和產品環境有著不同的需求,所以測試程式和產品程式的確有不同的軟體工程標準。

測試程式碼必須足夠簡明、簡潔、具表達力,但不需要一樣有效率。

例如用StringBuffer的效率會較高,但是可讀性會比較差,就沒有必要在測試程式使用這樣的寫法。

有些事情,你可能永遠不會在產品環境做,但在測試環境卻非常合適。

通常這關係到記憶體大小的問題或中央處理器的效能限制

但整潔的程度永遠不會被列入這個議題的討論當中

一個測試一個斷言(Assert) *

有些學派認為JUnit裡的每個測試函式,只能有唯一的一個斷言(Assert)敘述。 這樣的準則看似嚴厲,但卻容易讓人快速瞭解。

將多個斷言合併成一個,有幾種方法 given-when-then(給定-何時-然後)慣例,替換了函式的名稱。

這個方法可以讓整個程式更容易閱讀,但這樣拆解測試程式,有可能導致重複程式碼的產生。 我們可以利用TEMPLATE METHOD(樣板方法)模式,來消除這些重複的程式碼,也就是將given-when 移到基底類別,then 放到不同的衍生類別。 或者我們也可以建立一個完全獨立的測試類別,將given/when 的部分放到@Before 函式裡,then 的部分放到@Test函式裡。

但這樣的作法,似乎有點小題大作。Uncle Bob最終還是偏好採用可讀性高就好,不一定只能一個的方式。

他也同意單一的斷言原則是個不錯的指導方針,通常會試著建立支援這個方針的特定領域測試語言,但也不害怕將多個斷言放在同一個測試裡。

但最好的目標應該是盡量減少斷言數量。

一個測試一個概念

倘若一個測試哩,測試了超過一個概念,那應該拆開成多個測試。

最好的法則應該是

在一個概念裡最小化斷言的數量,一個測試函式只測試一個概念

F.I.R.S.T.

Fast(快速):

測試要夠快,能夠被快速的運行。畢竟倘若執行一次要很久,就不會想要常常執行它。 倘若不常常執行,就無法及早發現問題,也無法輕易修正。 如此,在整理程式時,就不會覺得自在。 最後,程式就會開始腐敗。

Independent(獨立):

測試程式不該互相依賴。 一個測試不應該成為下一個測試的設定條件。 你應該要能獨立的運行各個測試,並且可以按照任何想要的順序進行測試。 當測試相互依賴,第一個測試的失敗會導致後續一系列的失敗,那就很難去找到問題。

Repeatable(可重複性):

這個程式應該可以在任何環境重複執行。 不管在產品、質量保證(QA)、在火車上時自己的筆電等等環境,都應該可以進行測試。

Self-Validating(自我驗證):

測試應該輸出布林值。 不應該要根據查看紀錄檔才能判斷,倘若如此,執行測試後可能需要很長的手動檢查時間。

Timely(及時):

撰寫測試程式要及時。單元測試要恰好在產品程式之前不久撰寫。 倘若在撰寫產品程式之後才撰寫測試程式,你可能會發現產品程式很難被測試。 因為在設計時,就不會去設計可被測試的產品程式。

總結

測試程式跟產品程式一樣重要。 或許,測試程式可能更加重要,因為測試程式保障了產品程式的可擴充彈性、可維護性、可再利用性。 所以,持續保持測試程式的整潔,努力讓它們具有表達力和簡潔。 創造出測試程式的API,讓它變成特定領域的語言,能幫助撰寫測試程式。

Previous邊界Next類別

Last updated 5 years ago

Was this helpful?

https://wujincheng.gitbooks.io/brian/content/junit.html