測試驅(qū)動(dòng)開發(fā)TDD(1)
今兒接到一需求如下:
比如一個(gè)給定的數(shù)字2975,讓你去猜。6次機(jī)會(huì)。如果第一次輸入2509,系統(tǒng)會(huì)提示 1A2B:其中數(shù)字“2”位置猜對&&數(shù)字也猜對。稱為1A,而“9”和“5”數(shù)字猜對了但是位置沒有猜對。稱為2B。。如果輸入2975那么就是4個(gè)數(shù)字都猜對了并且位置也是對的系統(tǒng)提示4A0B。民間俗稱猜數(shù)字游戲:百度百科傳送門:http://baike.baidu.com/view/358630.htm。
做個(gè)簡單分析??蛻舳溯斎胍粋€(gè)數(shù)字,經(jīng)過游戲內(nèi)部的猜測,返回一個(gè)結(jié)果給客戶端。嗯,還好,不算難。由于準(zhǔn)備做TDD實(shí)踐。所以我們Test First.Why? 如果您對TDD不是很了解。就跟我一起做下去,顯然我也是新手。我們的目標(biāo)是“沒有蛀牙!”。
第一步:筆和紙拿出來。思考思考如何把這個(gè)小游戲拆分了。然后我們一步一步去完成它。寫一個(gè)To-Do-List。
To-Do-List:
猜測數(shù)字
輸入驗(yàn)證
生成答案
輸入次數(shù)
輸出猜測結(jié)果
...............
暫時(shí)想起這么多。比如還有選擇游戲難度、輸入日志、重新開始游戲、中途退出等等。
今天我要完成這個(gè)游戲的核心功能(猜測數(shù)字),我稱它為Guesser。傳入一個(gè)數(shù)字,返回一個(gè)結(jié)果。分析一下它可能輸出的幾種情況:4a0b(全對)、 0a4b(數(shù)字全對,位置全錯(cuò))、2a2b(一半一半)、0a0b(全錯(cuò))。這4個(gè)CASE應(yīng)該Cover了所有情況了。如果有補(bǔ)充,請F(tuán)ollow。
今天的TO-DO-LIST:
假設(shè)我們這局游戲的答案是2975。
輸入“2975” 輸出4a0b。
輸入“2957” 輸出2a2b。
輸入“9257” 輸出0a4b。
輸入“1348” 輸出0a0b。
完成Guesser類.
新建一個(gè)TEST 寫測試。
開始第一個(gè)CASE:輸入2975 與答案正匹配,輸出4a0b 。
[TestMethod] public void Test1() { var inputNumber = "2975"; var actual = new Guesser().Guess(inputNumber); Assert.AreEqual("4a0b", actual); } |
這個(gè)測試方法的命名一眼好像看不出它要測什么。單獨(dú)看測試的名字很是迷茫。我們修改一下讓它看起來很整潔。一眼看上去就知道是啥意思。要測試什么。
[TestMethod] public void should_return_4a0b_when_input_numbers_all_figures_and_positions_are_right() { var inputNumber = "2975"; var actual = new Guesser().Guess(inputNumber); Assert.AreEqual("4a0b", actual); } |
修改完之后在看這個(gè)方法的命名。 是不是清晰了很多??吹椒椒ǖ拿麘?yīng)該就能夠猜測到此方法是在什么情況下測試什么功能。
OK。我們的第一個(gè)CASE搞定了。Run一下。

編譯不通過!因?yàn)闆]有Guesser類。沒有Guess方法。
為了讓CASE過。我們必須創(chuàng)建Guesser類以及Guess方法。
public class Guesser { public string Guess(string inputNumber) { throw new System.NotImplementedException(); } } |
現(xiàn)在編譯沒錯(cuò)誤了。在Run。
有異常:System.NotImplementedException: The method or operation is not implemented.
鬧心。為了不鬧心。Guess方法里簡單實(shí)現(xiàn)。最簡單的就是直接返回"4a0b"。這里還是簡單的實(shí)現(xiàn)實(shí)現(xiàn)。
public class Guesser { private const string AnswerNumber = "2975"; public string Guess(string inputNumber) { var ACount = 0; var BCount = 0; for (var index = 0; index < AnswerNumber.Length; index++) { if (AnswerNumber[index]==inputNumber[index]) { ACount++; } } return string.Format("{0}a{1}b", ACount, BCount); } } |
OK。但是我們內(nèi)部實(shí)現(xiàn)如此簡單。不知道是否滿足第二個(gè)CASE呢。
完成一個(gè)CASE要把它劃掉。
To-Do-List:
輸入“2975” 輸出4a0b。
輸入“2957” 輸出2a2b。
輸入“9257” 輸出0a4b。
輸入“1348” 輸出0a0b。
完成Guesser類.
來第二個(gè)CASE:輸入9257與答案不匹配,但是所有數(shù)字都正確,輸出0a4b 。
有了第一個(gè)CASE的經(jīng)驗(yàn),這里我們也同樣注意命名。
[TestMethod] public void should_return_2a2b_when_input_numbers_all_figures_right_and_2_positions_right() { var inputNumber = "2957"; var actual = new Guesser().Guess(inputNumber); Assert.AreEqual("2a2b", actual); } Run..... |
沒有PASS:Assert.AreEqual failed. Expected:<2a2b>. Actual:<2a0b>.
我們接著去改guess方法,保證第二個(gè)CASE PASS。
public class Guesser { private const string AnswerNumber = "2975"; public string Guess(string inputNumber) { var aCount = 0; var bCount = 0; for (var index = 0; index < AnswerNumber.Length; index++) { if (AnswerNumber[index]==inputNumber[index]) { aCount++; continue; } if (AnswerNumber.Contains(inputNumber[index].ToString())) { bCount++; } } return string.Format("{0}a{1}b", aCount, bCount); } } |
運(yùn)行所有CASE...pass.別忘記劃掉To-Do-List
posted on 2014-01-16 11:38 順其自然EVO 閱讀(289) 評論(0) 編輯 收藏 所屬分類: selenium and watir webdrivers 自動(dòng)化測試學(xué)習(xí)