您的位置:軟件測(cè)試 > 開源軟件測(cè)試 > 開源單元測(cè)試工具 >
單元測(cè)試技巧:如何手動(dòng)設(shè)置待測(cè)試Bean的屬性
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2013/2/27 15:19:50 ] 推薦標(biāo)簽:

在JUnit測(cè)試中,通常作為POJO的Java Bean都是一組簡(jiǎn)單的getter/setter方法,需要測(cè)試的不是這些Bean本身,而是對(duì)Bean的屬性設(shè)置后,測(cè)試業(yè)務(wù)方法是否正常工作,例如,一個(gè)注冊(cè)用戶的類方法void register(Account account),需要對(duì)傳入的Account Bean做初始化設(shè)置,然后,根據(jù)業(yè)務(wù)規(guī)則決定register方法是否應(yīng)該執(zhí)行成功或者拋出IllegalArgumentException。
 
倘若按照常規(guī)的Unit測(cè)試,需要考慮用戶輸入的許多種組合,在testXxx()方法中編寫模擬用戶輸入的代碼是冗長而繁瑣的,不如直接通過Swing窗口手動(dòng)設(shè)置Bean的屬性,然后再執(zhí)行業(yè)務(wù)方法,這樣,雖然引入了輸入界面,需要人工干預(yù)測(cè)試過程,卻大大簡(jiǎn)化了編寫測(cè)試用例的麻煩。
 
在TCK測(cè)試中,對(duì)許多UI組件的測(cè)試正是采用這種半自動(dòng)的方法,因?yàn)橹挥袦y(cè)試人員本身才能看到UI測(cè)試的結(jié)果正確與否,計(jì)算機(jī)很難判斷一個(gè)類似fillRect()的方法到底有沒有在屏幕上正確繪制出來。
 
基于這種思想,為了測(cè)試許多種不同輸入的組合,我們決定編寫一個(gè)能根據(jù)Bean的屬性自動(dòng)生成輸入窗口的小工具,以便在Unit測(cè)試過程中,能夠由測(cè)試人員手動(dòng)設(shè)定Bean的屬性和期望的結(jié)果,然后,繼續(xù)測(cè)試。
 
為了實(shí)現(xiàn)這個(gè)目的,我們?cè)O(shè)計(jì)了一個(gè)小工具,它能夠?qū)崿F(xiàn):
 
1.根據(jù)傳入的Bean自動(dòng)為每個(gè)public setXxx()方法生成輸入框;
 
2.由測(cè)試人員手動(dòng)設(shè)置Bean的屬性,然后,選擇“Success”,“Failure”以決定這次測(cè)試的數(shù)據(jù)應(yīng)該產(chǎn)生正確或錯(cuò)誤的結(jié)果。
 
3.可以連續(xù)多次循環(huán)測(cè)試,直到測(cè)試人員點(diǎn)擊“End”,結(jié)束本次測(cè)試。
 
整個(gè)工具被封裝在一個(gè)BeanInputDialog類中,它繼承自JFrame,只暴露了一個(gè)public static方法。下面,我們以一個(gè)Account Bean為例,測(cè)試用戶輸入的屬性是否合法。
 
Account定義了4個(gè)字段和一個(gè)validate()方法來驗(yàn)證輸入,如果不符合輸入,validate()方法會(huì)拋出IllegalArgumentException。我們編寫一個(gè)簡(jiǎn)單的TestCase:
 
package com.crackj2ee.test.util;
import junit.framework.TestCase;
public class AccountTest extends TestCase {
    public void testAccount() {
        int expect;
        for(;;) {
            Account account = new Account(); // 待測(cè)試的Bean
            expect = BeanInputDialog.inputBean(account); // 用戶在此輸入
            // 注意:直到用戶輸入完成,inputBean()方法才會(huì)返回,它是一個(gè)同步方法
            // inputBean()方法返回一個(gè)int,表示本次測(cè)試的期望值
            if(expect==BeanInputDialog.EXPECT_END) // 期望測(cè)試結(jié)束,退出循環(huán)
                break;
            if(expect==BeanInputDialog.EXPECT_SUCCESS) { // 期望測(cè)試成功
                account.validate();
            }
            if(expect==BeanInputDialog.EXPECT_FAILURE) { // 期望測(cè)試失敗
                try {
                    account.validate();
                    fail("Not catch IllegalArgumentException!"); // 沒有捕獲到預(yù)期的異常
                }
                catch(IllegalArgumentException e) {
                    // OK!捕獲到預(yù)期的異常
                }
            }
        }
    }
}
 
在Unit測(cè)試過程中,可以不斷設(shè)置Bean的屬性,以滿足多種組合的測(cè)試用例。下面分別輸入合法和非法的用戶名,然后點(diǎn)擊期望值測(cè)試:
 
需要注意的是,由于屬性的獲取是通過反射得到的,考慮到通常的設(shè)計(jì)原則,我們只讀取public的setXxx()方法。
如果在測(cè)試人員輸入前,Bean已經(jīng)有了一些初始值,這個(gè)工具也能通過反射得到相應(yīng)的getXxx()方法的值。要注意的是,對(duì)boolean和Boolean類型的屬性,是根據(jù)getXxx()取得而不是根據(jù)isXxx()取得的。
目前,可以處理的屬性類型包括java.lang.String,java.util.Date,short,int,long,float,double,boolean及其包裝類型Short,Integer,Long,F(xiàn)loat,Double和Boolean。還可以對(duì)其擴(kuò)展,以便支持更多的類型。

軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd