首先,我們寫了示例,或者叫單元測試。然后利用IDE來創建還未創建的類和方法,因為這樣比較快。領域驅動開發(DDD)可以保持設計和代碼 語言與業務一致,BDD幫助我們關注行為、價值和如何使用類的示例。在發現某些新的、不尋常的或者遺漏的東西時,這幫助我們與業務建立有用的對話,而且由 于代碼的設計和業務保持一致,對代碼的修改難度,將與引起這些修改的業務流程修改的難度一致。
當我們完成了對每個類的編碼后,我們繼續對這個類的合作者編碼,直到所有stub出來的類都有一個真正的實現。通過這種方式,我們可以保證我 們只做了那些可以為UI提供價值的事。我們不會為那些我們認為將來可能會用到的方法或數據庫列來寫代碼,因為這在當時不是問題。這也幫助我們簡化我們的設計。
好的設計可以在我們更深入理解業務流程時,簡化代碼修改,并為創建UI需要的價值提供更多的選擇。就像Chris說的,“在金融領域,選項擁 有價值和過期時間。真正的選項-真實世界中的選項-也有價值,以及一個再沒有選擇余地的時間。有時,推遲決定并保持選項是值得的!焙玫脑O計需要更長的時 間,但是這樣是值得的,因為它讓我們能夠推遲決策,或當我們有更好理解時能夠改變我們的決定。
這就是為什么我們使用好的設計實踐,和像單元測試與系統測試這樣的自動化反饋環,都是為了讓修改變得容易。
不一定非要讓開發人員來寫這些代碼,不過如果你正在寫,那么你最終會成為一個開發人員。
我們為下一件最重要的事做準備
讓我們看一個例子。
有一個簡單的愿景:noughts and crosses游戲。出于練習的目的,我們假裝沒人玩過這個游戲,也沒有人看過戰爭游戲。我們有一個很大的特性集,叫做“游戲規則”。
我們可以為這個特性集寫一個故事。
為了玩Noughts and Crosses
作為一個玩家
我希望當有三個相同圖形在一行時,有一個人獲勝
下面是這個游戲的一個場景,以及對應的UI,使用JBehave來自動化:
給定一個這樣的網格
OO.
XX.
X..
當玩家點擊a3時
網格將會變成
OOO
XX.
X..
并顯示“O 贏了!”

下面是定義GameModel應該如何工作的示例代碼:
@Test
public void shouldNotifyObserverWhenTheCurrentPlayerWins() {
// 給定一個X將要獲勝的布局
GameModel game = new GameModel();
game.playerActsAt(0, 0);
game.playerActsAt(1, 0);
game.playerActsAt(0, 1);
game.playerActsAt(2, 0);
MyGameObserver observer = new MyGameObserver();
game.addObserver(observer);
// 當X獲勝時
game.playerActsAt(0, 2);
// X應該是當前的玩家
// 而且X獲勝了
ensureThat(observer.game.currentPlayer(), is(Player.X));
ensureThat(observer.game.message(), is(“Player X wins!”);
}
一旦我們完成這些示例,就可以開始編寫代碼了-GameModel類-來幫助我們使這個示例運行通過。
在這個例子中,我們將GUI作為觀察者mock出來,使用為這個例子創建的類-MyGameObserver。通過mock每個單元的協作者,我們可以保證示例與其他協作者沒有耦合,包括那些還不存在的協作者。這讓改變變得容易。
我們沒有分數,我們不知道X是不是一直都先走,我們不知道有人獲勝后應該如何-我們可能需要重啟程序。我們只為這個場景、這個故事、這個特性集和這個愿景寫了足夠的代碼。我們保持代碼易于修改,這樣就可以在以后為更多的場景和故事添加代碼。
當我們完成時,我們就發布!
當所有的協作者都被真正實現時,我們就寫完了這個場景的代碼。
當一個故事中的所有場景完成時,我們就完成了這個故事。
當一個theme或特性集中的故事都完成時,我們就完成了這個特性集。
當涉眾確認一個愿景的所有特性集都完成時,這個愿景就可以發布了。
在每個階段,我們都努力盡快得到反饋
通過自動化示例和場景,我們能夠發現代碼是否能夠工作。
通過自動化集成和部署到真實環境或相似的環境,我們能夠發現是否有之前沒有意識到的技術問題,或者沒有考慮到的涉眾。
通過盡快給涉眾展示應用程序,我們能夠發現我們是否可以完成愿景。
在敏捷和精益方法中,還有很多其他的反饋環。這意味著我們在開始工作時要假設可能會犯錯誤。我們不需要在一開始就保證每件事都是正確的-我們可以從“剛好夠用”開始。
在每個階段,我們都努力減少浪費
精益生產努力減少庫存-那些還沒有安裝到可工作的汽車上的零件。用同樣的方法,我們努力減少那些沒有添加到可工作的特性集和愿景上的用戶故事、場景、示例和代碼。在看板系統中,信號被傳遞到每個階段中,這樣每個工作站就知道要為下一個工作站生產一些特定的東西。每個被生產出來的部分都是因為某個工 作站需要他們來滿足客戶的需要。這就是一個拉動系統。
在其他生產系統中,生產線上放著成盒的剩余零部件以備使用。人們需要圍繞這些部件工作。這些部件需要維護、保護、空間等,如果商業需求的改變超過一定程度,這些部件就要被丟棄。
在一些軟件項目中,我們也做了同樣的事。我們創建特性集是因為我們有足夠的預算。我們對詳細分析那些我們相信會在3個月后需要的故事。我們為我們認為有趣的特性創建視圖。我們創建數據庫列和表來存儲沒有人會使用的信息,以及更多的視圖來收集信息。所有這些都需要維護,需要和他們一起工作,而且在商業 需求改變時扔掉。
通過在需要使用時才生產需要的東西,精益生產線可以避免這些浪費。相似的,我們也可以在我們的項目中,通過只在需要時才創建來避免浪費。
這就是我們的拉動軟件生命周期
最有價值的軟件是還沒有寫出來的軟件。
愿景促使涉眾創建特性
特性促使BA創建用戶故事
用戶故事促使QA創建場景
場景促使UI專家設計UI
UI促使開發人員編寫代碼
代碼促使開發人員編寫更多的代碼
我們做到能夠支持下一件最重要的事
當我們完成時,就發布。
在每個階段,我們都努力盡快得到反饋
在每個階段,我們都努力減少浪費。
在生命周期中的每個角色都不需要一定是全職的-例如一個開發人員也可以做BA或QA。在這種情況下,他會帶上BA的帽子。如果一個人不考慮他將從下一個階段中得到什么-例如代碼-那么就幾乎不可能得到他在下個階段需要的東西-例如用戶故事-因此讓不同的人扮演這些角色還是值得的。
不管用什么方法論,總是有不止一種方式來實現同一個目標,不止一種方式來應用方法論,以及不止一種拉動系統適合你。
當Dan North發明BDD時,他說:“程序員想知道從何處開始,測試什么不測試什么,一次測試多少,如何為測試命名,以及理解測試失敗的原因!
這個概括應該能讓你知道從何處入手,什么好用什么不好用,一次應該做多少,如何稱呼正在做的事,以及如何在軟件生命周期的每個層次獲得反饋;這樣不管編寫什么軟件,都是好的軟件。
文章來源于領測軟件測試網 http://www.kjueaiud.com/