l

2013年4月4日 星期四

如何提升軟體的可測試性(一)

Apr. 01 13:30~14:55

image

Teddy在《需求變來變去的情況下需要寫單元測試嗎?》這一篇提到程式設計師不願意寫單元測試的兩個原因:

  • 設計不良導致單元測試很難寫(很難測)。
  • 缺少撰寫自動化單元測試的知識或技術。

針對「設計不良導致單元測試很難寫」這個原因,我們可以說待測程式的「可測試性」

(testability)很低。不曉得鄉民們有沒有想過這些問題:什麼叫做可測試性?要怎麼設計才會讓自己的程式比較容易被測試?Teddy在《Quality Attribute Scenarios(11):Testability》這一篇從軟體架構(參考Software Architecture in Practice, 2nd)的角度來介紹testability,最近讀了《How We Test Software at Microsoft》又看到testability的說明,今天就再補充一下。

***

SOCK Model

書中列出四個提升可測試性的因素,分別是Simple、Observable、Control、Knowledge,剛好簡稱SOCK(襪子)。

  • Simple:一個一百行的程式和一個一千行的程式哪一個比較好測?應該是前者比較容易測試。同理,一個模組化做得很好的程式,和一坨義大利麵相比,前者比較容易理解,當然也比較容易測試。
  • Observable:俗話說「可觀察才可測量」,如果程式的內在結構或是外在行為不容易觀測,那麼這個程式就不容易測試。請看下面程式範例,foo()直接把字串輸出到console上,雖然說想辦法動手腳還是可以寫出從console讀到字串的自動化測試案例,但相對於直接將字串當作傳回值,輸出到console的程式還是比較難以測試。

螢幕快照 2013-04-01 下午2.22.27

 

把程式改成下面這樣子,computeS()會傳回字串,比較容易觀察因此也容易測試。

螢幕快照 2013-04-01 下午2.27.27

 

  • Control:能夠控制軟體的行為,也會讓測試變得容易許多。例如,下面這段程式要從某個檔案中讀取log資料。很不幸的這個log檔案的檔名被寫死在程式當中,為了測試這隻程式,鄉民們必須準備一隻檔名一模一樣的log檔案。

螢幕快照 2013-04-01 下午2.31.59

 

如果把程式改成下面這個版本,讓呼叫者傳入log檔的檔名,增加對待測程式的控制性,那麼便可增加可測試性。

螢幕快照 2013-04-01 下午2.35.27

 

log檔的檔名可在測試案例中指定,提高待測程式的可測試性。最近十年來很流行的Dependency Injection或是Inversion of Control設計原則,因為藉由外部注入相依性物件提升了待測程式的可控制性,不但提升了執行期間改變系統行為的彈性,也因此提升了可測試性。

螢幕快照 2013-04-01 下午2.38.16

 

  • Knowledge:對於待測程式的相關知識越充足,也會提升待測程式的可測試性。例如,假設鄉民們要測試isPrime(int value)這個判斷一個整數是否為質數的函數。如果鄉民們連質數的定義都不了解,當然也無法幫isPrime()寫測試案例(無法定義出expected result啊)。所以,提供越清楚、正確的說明文件或是任何有關待測程式的知識,便可提高程式的可測試性。

***

友藏內心獨白:Testability又是一個知易行難的非功能需求啊。

1 則留言:

  1. 不過我對Dependency Injection的Framework有點感冒,程式啟動時間變超長的。

    回覆刪除