天天看點

《Cucumber:行為驅動開發指南》——2.8 讓測試通過

本節書摘來自異步社群《cucumber:行為驅動開發指南》一書中的第2章,第2.8節,作者:【英】matt wynne , 【挪】aslak hellesy著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

既然已經有了可靠的失敗場景,那就是時候讓這個cucumber場景指導我們編寫解決方案了。

有一個非常簡單的方案能讓測試通過,但該方案其實不會有實際的幫助,不管怎樣我們先試一下,哪怕為了好玩兒:

試試運作cucumber,你會看到場景最終通過了:

很好!不過這個方案有什麼問題呢?畢竟我們說過希望做能讓測試通過的最少的工作,對不對?

事實上,這與我們之前說的不完全一樣,我們說希望做能讓測試通過的最少的、有用的工作。這裡我們做的确實讓測試通過了,但并不十分有用,暫且不說它根本沒有電腦的功能這一事實,我們先看看這行耍小聰明的代碼在測試時漏掉了什麼。

 我們沒有嘗試從指令行讀取輸入。

 我們沒有嘗試做加法運算。

在《crystal clear:小團隊的靈活開發方法》[coc04]一書中,alistair cockburn提倡在項目中盡早建構一個可行走的骨架(walking skeleton),以便發現技術選型的任何潛在問題。顯然我們的電腦非常簡單,但一樣值得我們考慮一下這條原則:為什麼我們不建構一種能通過該場景的更有用的東西,并且讓它幫助我們更多地了解自己打算使用的實作呢?

如果你不能信服這種觀點,可以嘗試将這種解決方案看成一個代碼重複的問題。我們在兩個地方寫死了4這個值:一處是場景中,另一處是電腦程式中。在更複雜的系統中,類似的重複可能不會被注意到,因而使場景變得脆弱。

讓我們強迫自己修複這個問題,可以使用kent beck在《測試驅動開發》一書中所說的三角法(triangulation)。我們使用一個新的名為scenario outline(場景輪廓)的關鍵字來為特性添加另一個場景:

joe問:我覺得很怪異,你一直在讓測試通過但毫無作用!

我們實作了一個步驟,它調用了電腦程式然後就通過了,即便這個時候“電腦”還隻是一個空檔案。這到底是怎麼回事?

記住一個步驟本身并不是一個測試,測試是整個場景,除非所有步驟都通過了,否則場景不可能通過。在我們實作所有步驟之後,隻有一種辦法能讓整個場景通過,那就是建構一個能運作加法運算的電腦!

像這樣由外向内工作的時候,我們常常會使用空電腦程式這樣的樁(stub),把它作為一個将來需要填充的預留區域。我們知道不可能永遠把空檔案留在那裡并僥幸成功,因為最終cucumber會告訴我們,要讓整個場景通過就必須回來給空檔案夾添加内容,使它能做點有用的事。

故意隻做能讓測試通過的最少的、有用的工作,這一原則看起來很懶,但實際上是一條紀律,它能保證我們的測試徹底且周密:如果測試沒有驅動我們編寫正确的軟體,那麼我們就需要更好的測試。

我們把場景轉變成了場景輪廓,這使我們可以用表格指定多個場景。另一種方法是複制并粘貼原來的整個場景然後改變其中的一些值,但我們認為使用場景輪廓在表述執行個體方面可讀性更強,并且我們想讓你體驗一下gherkin文法允許的其他寫法。我們看一下現在輸出是什麼樣子:

從摘要中的 2 scenarios (1 failed, 1 passed),我們可以看到cucumber已經運作了兩個場景,cucumber運作場景輪廓的時候,它會把執行個體(examples)表中的每一行擴充成一個場景。第一個執行個體(結果為4的那個)仍然通過了,但是第二個執行個體失敗了。

現在,肯定應該用一個更切實的解決方案重新實作我們的程式了:

首先我們讀取指令行參數argv[0],然後把它傳給ruby的eval方法。這足以算出與電腦輸入相關的結果,最後我們将結果列印到終端。

試一下,是不是兩個場景都通過了?很好!你已經建構了自己的第一個用cucumber驅動的應用程式。

繼續閱讀