前言
最近有幸跟隨資深thoughtworks諮詢師熊節老師一起學習測試驅動設計,經過短暫的十幾天培訓,對測試驅動設計的基本原則、實踐模式、技巧有了一點點初步的認識。
在此之前,經常自嘲我經歷的公司實踐也似乎是tdd, 這種實踐往往都是由測試工程師來驅動開發者完成bug的修改,雖然也是測試來驅動開發,但是卻與真正的tdd大相徑庭。
什麼是tdd
在維基百科中是這樣對tdd下定義的:
測試驅動開發(英語:test-driven development,縮寫為tdd)是一種軟體開發過程中的應用方法,由極限程式設計中倡導,以其倡導先寫測試程式,然後編碼實現其功能得名。測試驅動開發始於20世紀90年代。測試驅動開發的目的是取得快速反饋並使用「illustrate the main line」方法來構建程式。
測試驅動開發是戴兩頂帽子思考的開發方式:先戴上實現功能的帽子,在測試的輔助下,快速實現其功能;再戴上重構的帽子,在測試的保護下,通過去除冗餘的**,提高**質量。測試驅動著整個開發過程:首先,驅動**的設計和功能的實現;其後,驅動**的再設計和重構。測試驅動開發也是國外許多優秀開發者向開發者們推薦的一種普遍適用的開發模式,而在熊節老師的培訓課程中,他時刻在向開發者灌輸來自tdd的三條原則,要求我們的編寫生產**前,一定應該先編寫單元測試。
定律一:在編寫不能通過的單元測試前,不可編寫生產**。
定律二:只可編寫剛好無法通過的單元測試,不能編譯也算不通過。
定律三:只可編寫剛好足以通過當前失敗測試的生產**。簡單實踐
在我之前的編碼實踐過程中,總是習慣梳理一遍邏輯後,在根據專案的實際情況對**進行重構,而隨著我自以為掌握了單元測試的技巧之後,就開始把邏輯**往單元測試上套,導致這樣的單元測試實際上並非為了實現測試,而僅僅只是程式的入口而已。
如果使用tdd的方法,則需要首先規劃需要實現的目標,然後再定義測試方法和測試需要實現的邏輯。
例如,**大概是這樣的:
我的目標是實現對schema物件的解析,測試類採用schemaunittest,並採用「should_***_when_***」的命名方式,定義了測試方法「should_return_true_when_bool」,然後定義乙個schemas的類,再定義其需要實現的需求(斷言),以及需求的實現。
對單元測試方法的命名,不同的書籍有不同的命名方法,在這個專案實踐中,採用的是should命名方法,而在之前看過的《單元測試的藝術》一書中,使用的is_when_return_***的方式,這兩者只是命名方法的不同,本質上沒有任何區別;使用xunit和mstest實際上也沒有太多區別。
此時,這個定義的方法getparameter是未實現的,所以會進入乙個「紅-綠-重構」的工作流程。
1)編寫乙個會失敗的測試,以證明產品中**或功能的缺失。編寫**時,要假設產品**已經能工作了,這樣測試的失敗就說明產品**中有缺陷。例如我定義的getparameter方法使用xunit進行測試會提示失敗, 只有在新增需要的**後,編譯才能通過。
2)編寫符合測試預期的產品**,使測試通過,產品**應該盡量簡單。
3)重構**。如果測試通過了,你就可以編寫下乙個單元測試,或者重構,消除異味或提高**可讀性。
最終,我完成了乙個這樣的方法。(即便是這樣的**,依然有許多可以進一步提公升的空間。)
顯然這是乙個邏輯非常簡單的**,但是如果採用全鍵盤操作,不使用滑鼠來完成,仍然耗費了我不少時間,這個過程中,也讓我對visual studio的快捷鍵操作更加熟練。
測試的不同階段
在我們的產品研發過程中,經常遇到以下三種不同形式的測試
三種測試從上到下實施的容易程度遞增,但是測試效果遞減。端到端測試最費時費力,但是通過測試後我們對系統最有信心。單元測試最容易實施,效率也最高,但是測試後不能保證整個系統沒有問題。
在我們的專案實踐中,更多的採用的依然是端到端測試的模式,似乎只有通過測試者的人肉測試,才能讓我們的**更加令人滿意。
單元測試事實上極少在我們的專案中得到實踐,其主要原因大概是因為要掌握單元測試方法,本身需要對開發者的主觀能動性提出了更高的要求,但是996開發者...太容易內捲化了。
總結寫好單元測試從來就是技術活,有一段時間過分在意理論概念和工具的用法,忽略了實踐,所以實際上看了好幾本書,依然不知道如何寫單元測試,這次參與了培訓,終於摸到了一點點影子。
現階段我大概可以這樣做來逐步提高自己的技能水平:
我的TDD實踐
我的tdd實踐 系列之unittest單元測試寫在前面 tdd實踐系列文章 1.tdd概念篇 2.ci持續整合 3.svn架設篇 4.unittest單元測試 1.2 特徵 與其他 相隔離 單元測試只測試一件事,否則應該懷疑是否是測試內容有誤。與其他開發人員隔離 保證最小化的變數影響單元測試,也就是...
我對TDD的實踐
上周五的討論又錯過了!真可惜。可是實在沒有辦法,最近忙的厲害。就是發表一篇blog也要趕在7 30之前,8 00監考,提前10分鐘進教室 不多說了,現在連會議記錄還沒有看完,還有寒楓天傷 wayfarer idior的文章也沒顧得上看。先把我去年的一部分教案放上來,就算對tdd的乙個補償吧。內容很簡...
TDD與VTDD系列 四 簡單例項演示TDD過程
假如要編寫乙個cmath類,其中有乙個方法abs 原形如下 class cmath 一般的程式設計習慣是直接寫 然後除錯,至於測試,則以後再說。tdd要求,在未編寫測試 前不能寫任何產品 這裡使用的測試框架是cppunit,用例 使用本系列的一和二介紹的格式,為了減少篇幅,只列出關鍵 cppunit...