軟件測試中的一種新單元測試的方法
一種新的單元測試的方法意味著什么?難道說Junit或者TestNG還不夠好?Junit(這里我提及到它因為它簡單,但是在我的討論中,TestNG 也一樣簡單 from here on I’ll nominate it only for briefness,but TestNG is the same for my discussion)把測試類作為重點,并且所有的測試都是從那里開始。這意味著事實上,被測試類被認為僅僅存在于測試代碼中,程序員只能通過它們使用的名字慣例來找到這些被測試類。
在舊版本的Junit中,你設計的測試類,需要強制繼承Junit框架中的類,并且將調用的方法需要用"test"開頭。因此按這個慣例來命名測試類和測試方法,并把他們與被測試的類和方法“連接”起來。我想你會同意,TestNG和Junit4給了我們更多的自由,去掉這些要求。不管怎樣,被測試的類和方法和我們的測試類仍然是這樣邏輯的聯系在一起,并且很多測試類仍然遵循那些舊的慣例。
但是有很多更好的方式來命名類和方法!我來介紹BDD(Behaviour Driven Development),請注意BDD不是這篇文章的重點,但是它使我這篇文章更加完美。因此,讓我們先用少許文字了解BDD吧。
BDD不僅是一個新的寫測試的方法,也是一個按約定的新的設計形式
引用behaviour-driven.org來開始我的介紹:
BehaviourDrivenDevelopment grew out of a thought experiment based on NeuroLinguisticProgramming techniques. The idea is that the words you use influence the way you think about something
BDD產生自一個基于神經語言規劃學技術的實驗的想法。這個想法是你用的語言會影響你考慮問題的方式。
這個想法是需要程序員關注用來描述一個測試類或者方法的詞語,因為所選的詞語將影響到他們對這個問題的關注點。實際上,采用BDD方法寫測試類時,相比這些被測試的類/方法本身,我們將更加關注這些被測試類/方法的行為。當然,這也將改變很多我們寫測試代碼的方式,比如,我們將對一個方法測試多次來驗證每個行為是否正確。
OK, what if I don’t believe on Neuro Linguistic Programming(神經語言規劃學)?是否我還不相信神經語言規劃學。好的,從一個純粹的開發者角度來看,我們根據我們的類和方法的行為作為約定來命名測試,因此,這個測試結果將是絕對清晰的(比如,
“shouldAcceptNullValue fails”就是一個清楚的表達,并不需要復雜的報告)。讓我們提供一個簡單的例子:
Java代碼
2. public void shouldNotPermitMethodNull() throws Exception {
3. [..]
4. }
5. @Test( expected = IllegalArgumentException.class )
6. public void shouldNotPermitEndPointNull() throws Exception {
7. }
8. @Test
9. public void shouldInitWebParams() throws Exception {
10. }
11. @Test
12. public void getHoldersResultShouldReturnHolderForRightParameters() throws Exception {
13. }
14. @Test
15. public void getHoldersResultShouldIgnoreUnknowntParameters() throws Exception {
16. }
17. @Test
18. public void getHoldersResultShouldIgnoreINParameters() throws Exception {
19. }
20. @Test
21. public void shouldRuninvokeForOneWayMethod() throws Exception {
22. }
23. @Test
24. public void shouldRuninvokeForMethods() throws Exception {
25. }
26. @Test
27. public void shouldRuninvokeForMethodsApplyingMapping() throws Exception {
28. }
你需要一個簡單的關于如何使用BDD成功應用到java上的介紹嗎(最初的主意來自Ruby’s RSpec)?可以先看看excellent post.
那么BDD就夠了嗎?
答案當然是NO。BDD是很強大,你可以試一下,但是如果你真正的用于實踐,你就會發現這些測試類和被測試類很快就會失去其聯系。在BDD中,不僅僅測試方法不再是testXXX,那些測試類也可能不再是按約定取的名稱;蛘,你可能針對同一個被測試類/方法,會擁有多個測試的方法。例如之前的那個例子,當然不是很貼切,可能一個具體的測試類,比如來測試getHolder方法的行為的測試類更好一點。
你需要幫助嗎?這是我的新的項目TestedBy
通過注釋來標注被測試類和方法,來使其與測試類和方法聯系在一起,怎么樣?不是太壞,你說呢?
我的想法或多或少從這里開始,但是不僅限于一個注釋。我很高興這個主意,因此我決定開始一個新的開源項目來提供測試工具,用來把被測試類放到中心的位置。
繼續看,我將展示給你如何通過注釋和相關工具來改變你測試的方法。
TestedBy目標在于改變觀察測試類和被測試類的角度。我們可以把被測試的類(項目中最重要的類)放在中心位置,并可從這些類連接到他們的測試類和方法。一個代碼快照可能抵得上更多的解釋:
Java代碼
2.
3. /**
4. * @param args
5. */
6. public static void main( String[] args ) {
7. TestedBySample sample = new TestedBySample();
8. System.out.print(sample.add(1, 2));
9.
10. }
11.
12. @TestedBy( testClass = "it.javalinux.testedby.TestedBySampleTest", testMethod = "addShouldWork" )
13. public int add( int i,
14. int j ) {
15. return i + j;
16. }
17. @TestedByList( {@TestedBy( testClass = "it.javalinux.testedby.TestedBySampleTest", testMethod = "addShouldWork" ),
18. @TestedBy( testClass = "it.javalinux.testedby.TestedBySampleTest", testMethod = "addShouldWork2" )} )
19. public int add2( int i,
20. int j ) {
21. return i + j;
22. }
23.
24. }
很好吧,但是它確實改變了你單元測試的方法?我覺得是,怎么樣,至少在兩個方面。
1、通過接口和約束來設計Design by interface and contracts
軟件設計中著名的詞語說“Design by interface”,仍然在我耳邊響起。因此你也當然可以“Test interface”。
很多正式的“Design by interface”意味著定義好你的接口,并且接著實現它們(可能大部分時間是由不同的人或者公司來實現)?傊,你能夠影響到的只是如一個強類型語言,例如java能為你提供的那樣:一個接口的實現必須遵循接口的簽名,類型和參數變量保持一致。你不能控制到那些具體的行為。當然,這也是一個API設計上的一個很大的局限性,因為可能導致實現完全不可預期的行為。
這里我就引出Eiffell language 和他的 design by contract (DbC)方法,約定來引導繼承過來的特征的重新定義。在java中有很多工具支持Dbc,但是我的想法是我們已經有一個很強大的方式來測試方法上的約束,并且使用更少的代碼來清楚行為:Unit Tests單元測試。
使用TestedBy,測試在接口(或者父類)上聲明,所有實現類都能運行這些測試,來驗證這些實現類的行為,是符合父類類型上的行為和約束定義的。API設計者不僅提供接口,也提供一套驗證該接口行為的測試類。因此每個實現者需要提供他們自己的實現,并且運行API設計者提供的測試,來保證實現類不僅是類型安全的,也是行為安全的。TestedBy傳遞給測試類一個被測試接口的實體類,并調用接口定義好的測試。
這是一個使用TestedBy的例子:我們已經添加了@TestedBy注釋在API接口,并提供一個@BeforeTestedBy注釋來提供一個接口的實例。TestedBy將在實現類APIImplOne和APIImplTwo上運行shouldAddTwoAndThree,測試在第一個類上成功而在第二個類上失敗。
文章來源于領測軟件測試網 http://www.kjueaiud.com/