測試驅(qū)動開發(fā)應(yīng)該是一種思維而不僅是實(shí)踐
相信對敏捷熟悉的朋友對測試驅(qū)動開發(fā)(TDD)的概念都不會陌生。測試驅(qū)動開發(fā)強(qiáng)調(diào)通過預(yù)定義的測試標(biāo)準(zhǔn)驅(qū)動開發(fā)寫出符合標(biāo)準(zhǔn)的代碼。不過現(xiàn)在越來越多人會把TDD等同于單元測試驅(qū)動開發(fā),即UTDD。我并不否認(rèn)UTDD的價值,不過我更想強(qiáng)調(diào)應(yīng)該把TDD當(dāng)作一種思維。TDD的思維其實(shí)非常合理,做任何事情都應(yīng)該有一個預(yù)期的目標(biāo)和標(biāo)準(zhǔn),如果目標(biāo)和標(biāo)準(zhǔn)不清晰,就很難確保產(chǎn)出的價值。
“The original description of TDD was in an ancient book about programming. It said you take the input tape, manually type in the output tape you expect, then program until the actual output tape matches the expected output. After I’d written the first xUnit framework in Smalltalk I remembered reading this and tried it out. That was the origin of TDD for me. When describing TDD to older programmers, I often hear, “Of course. How else could you program?” Therefore I refer to my role as ‘rediscovering’ TDD.”
—Kent Beck, re-discoverer and namer of Test-Driven Development
從Kent Beck的表述來看,TDD最初也更像是一種思維,并且應(yīng)該是理所當(dāng)然的做事方式。
回到研發(fā)工作當(dāng)中,測試驅(qū)動開發(fā)可以在很多環(huán)節(jié)里體現(xiàn),同樣,我們也可以主觀地把TDD的思維運(yùn)用到各個環(huán)節(jié)當(dāng)中去。例如:
契約測試
契約測試是期望消費(fèi)者和提供者之間基于預(yù)先定義的契約進(jìn)行協(xié)作的實(shí)踐。所以我們可以認(rèn)為契約測試符合測試驅(qū)動開發(fā)的思維,這樣的協(xié)作過程規(guī)范了寫作標(biāo)準(zhǔn),避免了傳統(tǒng)的口頭或文檔承諾帶來的交付結(jié)果與預(yù)期不匹配的問題。
需求驗(yàn)收標(biāo)準(zhǔn)
在敏捷團(tuán)隊中教練會經(jīng)常強(qiáng)調(diào)驗(yàn)收標(biāo)準(zhǔn)的重要性,而實(shí)際上驗(yàn)收標(biāo)準(zhǔn)對任何一個團(tuán)隊都不可忽略。驗(yàn)收標(biāo)準(zhǔn)在需求梳理過程中,迭代計劃階段都成為團(tuán)隊參考的重要依據(jù)。而在Thoughtworks推行的實(shí)踐中,“開卡”也是把驗(yàn)收標(biāo)準(zhǔn)的價值進(jìn)一步延伸的實(shí)踐。
“開卡”的做法是在具體的開發(fā)人員準(zhǔn)備開發(fā)某一個用戶故事之前,需要基于自己對需求的理解并結(jié)合驗(yàn)收標(biāo)準(zhǔn)向產(chǎn)品、測試以及相關(guān)人員講述對需求的理解。通過這種方式對齊需求驗(yàn)收標(biāo)準(zhǔn),降低功能開發(fā)產(chǎn)生偏差的風(fēng)險,同時也是質(zhì)量內(nèi)建的有力措施。當(dāng)然,除了開卡之外,還有行為驅(qū)動開發(fā)(BDD)等實(shí)踐都是把驗(yàn)收標(biāo)準(zhǔn)與研發(fā)過程有效結(jié)合的實(shí)踐。而類似的實(shí)踐都符合測試驅(qū)動開發(fā)的思維。
標(biāo)準(zhǔn)驅(qū)動
通過以上的實(shí)踐我們能理解測試驅(qū)動開發(fā)的思維,會強(qiáng)調(diào)先有參考標(biāo)準(zhǔn),再基于標(biāo)準(zhǔn)去實(shí)現(xiàn)交付。自然我們也可以把這種思維進(jìn)一步擴(kuò)展到更多的層面,比如通過預(yù)定義的標(biāo)準(zhǔn)驅(qū)動團(tuán)隊的行為。而在現(xiàn)實(shí)情況下卻也并不容易。
不管哪種場景下,遇到的第一個問題就是如何制定標(biāo)準(zhǔn)、如何確保達(dá)成共識的標(biāo)準(zhǔn)、標(biāo)準(zhǔn)如何保持更新。
很多團(tuán)隊對標(biāo)準(zhǔn)的第一印象往往是固化了大家的行為,對團(tuán)隊要求又提高了,推廣時阻礙太多等等。而基于這些擔(dān)心和固有印象一直守著原有的工作模式不想改變。
第二個關(guān)鍵點(diǎn)則是如何驅(qū)動。標(biāo)準(zhǔn)驅(qū)動在有了標(biāo)準(zhǔn)之后面對的就是如何產(chǎn)生驅(qū)動力的問題。我也見過太多的團(tuán)隊標(biāo)準(zhǔn)都是有的,卻發(fā)現(xiàn)總是不能按照標(biāo)準(zhǔn)執(zhí)行。有人說標(biāo)準(zhǔn)不適合自己,有人說標(biāo)準(zhǔn)太多影響現(xiàn)有工作,也有人說標(biāo)準(zhǔn)增加了工作復(fù)雜性。所以,往往在標(biāo)準(zhǔn)沒有執(zhí)行之前就被否定了。而讓團(tuán)隊愿意依據(jù)標(biāo)準(zhǔn)執(zhí)行無非從兩個角度入手:
第一是標(biāo)準(zhǔn)要與團(tuán)隊甚至個人痛點(diǎn)相結(jié)合;
第二是標(biāo)注的產(chǎn)出要獲得團(tuán)隊的共識和認(rèn)可。
回到本文主題上,測試驅(qū)動開發(fā)的運(yùn)用是在理解測試驅(qū)動開發(fā)思維的前提下,找到適合的場景運(yùn)用適合的實(shí)踐的過程。從我們比較熟知的UTDD到ATDD,再到BDD以及本文延伸出的很多觀點(diǎn),都不是對所有團(tuán)隊通用的。與敏捷本身類似,思維永遠(yuǎn)是實(shí)踐的基礎(chǔ)!