軟件測(cè)試實(shí)驗(yàn)單元測(cè)試工具JUNIT_第1頁(yè)
軟件測(cè)試實(shí)驗(yàn)單元測(cè)試工具JUNIT_第2頁(yè)
軟件測(cè)試實(shí)驗(yàn)單元測(cè)試工具JUNIT_第3頁(yè)
軟件測(cè)試實(shí)驗(yàn)單元測(cè)試工具JUNIT_第4頁(yè)
軟件測(cè)試實(shí)驗(yàn)單元測(cè)試工具JUNIT_第5頁(yè)
已閱讀5頁(yè),還剩18頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、武 漢 輕 工 大 學(xué)軟件測(cè)試實(shí)驗(yàn)報(bào)告實(shí)驗(yàn)一 單元測(cè)試工具JUNIT姓 名: 李婭婭 學(xué) 號(hào): 1505110015 班 級(jí): 軟工1503 指導(dǎo)老師: 丁月華 1. 實(shí)驗(yàn)?zāi)康牧私庾詣?dòng)化測(cè)試工具JUnit的架構(gòu)、功能,學(xué)習(xí)如何下載、安裝JUnit,掌握使用JUnit對(duì)Java程序進(jìn)行單元測(cè)試的方法。2. 實(shí)驗(yàn)步驟2.1 導(dǎo)入jar包右擊項(xiàng)目名,單擊Build Path中的Add Libraries.選擇User Libariry。新建一個(gè)存放Junit的包的庫(kù)將導(dǎo)入Jar包導(dǎo)入完成。2.2 編寫(xiě)第一個(gè)Junit測(cè)試類(lèi) Calculator類(lèi)編寫(xiě)被測(cè)試類(lèi)Calculator:(拷貝) priva

2、te static int result; / 靜態(tài)變量,用于存儲(chǔ)運(yùn)行結(jié)果 public void add(int n) result = result + n; public void substract(int n) result = result - 1; /Bug: 正確的應(yīng)該是 result =result-n public void multiply(int n) / 此方法尚未寫(xiě)好 public void divide(int n) result = result / n; public void square(int n) result = n * n; public void

3、 squareRoot(int n) for (; ;) ; /Bug : 死循環(huán) public void clear() / 將結(jié)果清零 result = 0; public int getResult() return result; CalculatorTest類(lèi)編寫(xiě)CalculatorTest類(lèi),用于測(cè)試Calculator類(lèi):(拷貝)public class CalculatorTest private static Calculator calculator = new Calculator(); Before public void setUp() throws Exceptio

4、n calculator.clear(); Test public void testAdd() calculator.add(2); calculator.add(3); assertEquals(5, calculator.getResult(); Test public void testSubstract() calculator.add(10); calculator.substract(2); assertEquals(8, calculator.getResult(); Ignore("Multiply() Not yet implemented") Test

5、 public void testMultiply() Test public void testDivide() calculator.add(8); calculator.divide(2); assertEquals(4, calculator.getResult(); 運(yùn)行測(cè)試在類(lèi)名上右擊,選擇Run As à Junit Test 得到Junit面板,并顯示了哪些測(cè)試是成功的,哪些是失敗的以及哪些是未執(zhí)行(直接跳過(guò)了):2.3 使用JUnit對(duì)Money類(lèi)進(jìn)行單元測(cè)試 Money類(lèi)(拷貝)public class Money private int fAmount; /貨幣

6、余額private String fCurrency; /貨幣類(lèi)型public Money(int amount, String currency)fAmount=amount;fCurrency=currency;public int amount()return fAmount;public String currency() return fCurrency; public Money add(Money m)/add方法把兩個(gè)Money對(duì)象相加,合成一個(gè)Money對(duì)象return new Money(amount()+m.amount(),currency();public boole

7、an equals(Object anObject)/equals方法判斷兩個(gè)Money對(duì)象是否相等if(anObject instanceof Money)Money aMoney=(Money)anObject;return aMoney.currency().equals(currency()&&amount()=aMoney.amount();return false; 現(xiàn)在要對(duì)Money類(lèi)的add方法進(jìn)行測(cè)試,步驟如下: MoneyTest類(lèi)(1) 創(chuàng)建對(duì)象定義幾個(gè)Money類(lèi)的對(duì)象Money result;Money m12CHF=new Money(12,&quo

8、t;CHF");Money m14CHF=new Money(14,"CHF");Money expected=new Money(26,"CHF"); /預(yù)期的運(yùn)行結(jié)果(2) addTest()在MoneyTest類(lèi)中編寫(xiě)testAdd方法,對(duì)Money類(lèi)中的add()方法進(jìn)行測(cè)試:Testpublic void testAdd()result=m12CHF.add(m14CHF);assertTrue(expected.equals(result);/判斷運(yùn)行結(jié)果是否與預(yù)期值相同(3) testEquals()Testpublic void

9、 testEquals() assertTrue(!m12CHF.equals(null); assertTrue(!m12CHF.equals(m14CHF); assertEquals(m12CHF,m12CHF); assertEquals(m12CHF,new Money(12,"CHF"); 2.3.3 運(yùn)行測(cè)試測(cè)試通過(guò)2.4 Fixture和幾個(gè)標(biāo)簽Fixture的含義就是“在某些階段必然被調(diào)用的代碼”。比如我們上面的測(cè)試,由于只聲明了一個(gè)Calculator對(duì)象,他的初始值是0,但是測(cè)試完加法操作后,他的值就不是0了;接下來(lái)測(cè)試減法操作,就必然要考慮上次加法操

10、作的結(jié)果。這絕對(duì)是一個(gè)很糟糕的設(shè)計(jì)!我們非常希望每一個(gè)測(cè)試都是獨(dú)立的,相互之間沒(méi)有任何耦合度。因此,我們就很有必要在執(zhí)行每一個(gè)測(cè)試之前,對(duì)Calculator對(duì)象進(jìn)行一個(gè)“復(fù)原”操作,以消除其他測(cè)試造成的影響。因此,“在任何一個(gè)測(cè)試執(zhí)行之前必須執(zhí)行的代碼”就是一個(gè)Fixture,我們用Before來(lái)標(biāo)注它,如前面例子中的setUp()方法所示:這里不在需要Test標(biāo)注,因?yàn)檫@不是一個(gè)test,而是一個(gè)Fixture。同理,如果“在任何測(cè)試執(zhí)行之后需要進(jìn)行的收尾工作”也是一個(gè)Fixture,使用After來(lái)標(biāo)注。2.4.1 代碼測(cè)試public class TTest BeforeClass p

11、ublic static void beforeClass() System.out.println("beforeClass"); AfterClasspublic static void afterClass() System.out.println("afterClass"); Beforepublic void before() System.out.println("before"); Testpublic void testAdd() int z = new T().add(5, 3); assertThat(z, is(

12、8); assertThat(z, allOf(greaterThan(5), lessThan(10); Test(expected = java.lang.ArithmeticException.class, timeout = 100)public void tDivide() int z = new T().divide(8, 0); Afterpublic void after() System.out.println("after");2.4.2 運(yùn)行結(jié)果在控制臺(tái)中得到運(yùn)行結(jié)果:在Junit選型卡中得到:(1) 結(jié)果分析在Junit選項(xiàng)卡中由于代碼找不到T類(lèi),而

13、使方法運(yùn)行錯(cuò)誤。在控制臺(tái)中輸出兩次before和兩次after,是因?yàn)樵陬?lèi)中test了兩個(gè)方法,每運(yùn)行一個(gè)方法,before和after下的方法就是默認(rèn)執(zhí)行。2.4.3 標(biāo)簽學(xué)習(xí)(1) Test測(cè)試方法(2) Before使用了該元數(shù)據(jù)的方法在每個(gè)測(cè)試方法執(zhí)行之前都要執(zhí)行一次,一般做初始化方法。 (3) After使用了該元數(shù)據(jù)的方法在每個(gè)測(cè)試方法執(zhí)行之后要執(zhí)行一次,一般用于釋放資源。(4) ignore該元數(shù)據(jù)標(biāo)記的測(cè)試方法在測(cè)試中會(huì)被忽略。你可以為該標(biāo)簽傳遞一個(gè)String的參數(shù),來(lái)表明為什么會(huì)忽略這個(gè)測(cè)試方法。比如:lgnore(“該方法還沒(méi)有實(shí)現(xiàn)”),在執(zhí)行的時(shí)候,僅會(huì)報(bào)告該方法沒(méi)有實(shí)

14、現(xiàn),而不會(huì)運(yùn)行測(cè)試方法。 (5) BeforeClass所有測(cè)試開(kāi)始之前運(yùn)行,一個(gè)測(cè)試類(lèi)只能有一個(gè),并且必須聲明為public static。該方法在內(nèi)存中只存在一份實(shí)例,比較適合加載配置文件。(6) AfterClass:所有測(cè)試結(jié)束之后運(yùn)行 ,一個(gè)測(cè)試類(lèi)只能有一個(gè),并且必須聲明為public static。 通常用來(lái)對(duì)資源進(jìn)行清理,比如關(guān)閉數(shù)據(jù)庫(kù)的連接。(備注:為什么需要BeforeClass 和 AfterClass ,我們來(lái)看看他們是否適合完成如下功能:有一個(gè)類(lèi)是負(fù)責(zé)對(duì)大文件(超過(guò) 500 兆)進(jìn)行讀寫(xiě),他的每一個(gè)方法都是對(duì)文件進(jìn)行操作。換句話說(shuō),在調(diào)用每一個(gè)方法之

15、前,我們都要打開(kāi)一個(gè)大文件并讀入文件內(nèi)容,這絕對(duì)是一個(gè)非常耗費(fèi)時(shí)間的操作。如果我們使用 Before 和 After ,那么每次測(cè)試都要讀取一次文件,效率及其低下。這里我們所希望的是在所有測(cè)試一開(kāi)始讀一次文件,所有測(cè)試結(jié)束之后釋放文件,而不是每次測(cè)試都讀文件。 JUnit 的作者顯然也考慮到了這個(gè)問(wèn)題,它給出了 BeforeClass 和 AfterClass 兩個(gè) Fixture 來(lái)幫我們實(shí)現(xiàn)這個(gè)功能。從名字上就可以看出,用這兩個(gè) Fixture 標(biāo)注的函數(shù),只在測(cè)試用例初始化時(shí)執(zhí)行 BeforeClass 方法,當(dāng)所有測(cè)試執(zhí)行完畢之后,執(zhí)行 AfterClass 進(jìn)行收尾工作。)JUnit

16、4的單元測(cè)試用例執(zhí)行順序?yàn)椋?BeforeClass -> Before -> Test -> After -> AfterClass。每一個(gè)測(cè)試方法的調(diào)用順序?yàn)椋?Before -> Test -> After??梢愿鶕?jù)以上給定的標(biāo)記來(lái)構(gòu)造測(cè)試類(lèi)中的測(cè)試方法,一般說(shuō)來(lái)遵守以下約定:類(lèi)放在test包中類(lèi)名用XXXTest結(jié)尾方法用testMethod命名2.5 限時(shí)測(cè)試Test(timeout=value) ,例如Test(timeout=1000)2.5.1 被測(cè)源代碼2.5.2 測(cè)試代碼 Test(timeout = 1000) public void

17、testSquareRoot() calculator.squareRoot(4); assertEquals(2, calculator.getResult();2.5.3 運(yùn)行測(cè)試在測(cè)試代碼中Timeout 參數(shù)表明了設(shè)定的時(shí)間,單位為毫秒,因此 1000 就代表 1 秒,測(cè)試的方法超過(guò)了設(shè)定的時(shí)間表示失敗。2.6 異常測(cè)試對(duì)除法運(yùn)算中的“除0異?!边M(jìn)行測(cè)試2.7 綜合練習(xí)2.7.1 測(cè)試代碼public class CalculatorTest private static Calculator calculator = new Calculator();BeforeClass publ

18、ic static void beforeClass() System.out.println("beforeClass"); AfterClasspublic static void afterClass() System.out.println("afterClass"); Beforepublic void before() System.out.println("before"); Afterpublic void after() System.out.println("after"); Before pu

19、blic void setUp() throws Exception calculator.clear(); Test public void testAdd() calculator.add(2); calculator.add(3); assertEquals(5, calculator.getResult(); Test public void testSubstract() calculator.add(10); calculator.substract(2); assertEquals(8, calculator.getResult(); Ignore("Multiply(

20、) Not yet implemented") Test public void testMultiply() Test public void testDivide() calculator.add(8); calculator.divide(2); assertEquals(4, calculator.getResult(); Test(timeout = 1000) public void testSquareRoot() calculator.squareRoot(4); assertEquals(2, calculator.getResult(); Test(expecte

21、d = ArithmeticException. class ) public void divideByZero() calculator.divide( 0 ); 2.7.2 運(yùn)行測(cè)試(1) 控制臺(tái)分析:在代碼中定義了BeforeClass和AfterClass標(biāo)簽,因此,在輸出的首尾有這標(biāo)簽下定義的輸出信息。代碼中編寫(xiě)了6個(gè)測(cè)試方法,因此對(duì)Before,After標(biāo)簽下的輸出信息打印了5遍(其中方法testMultiply使用了Ignore標(biāo)簽)。(2) Junit選項(xiàng)卡測(cè)試結(jié)果為三個(gè)通過(guò),一個(gè)忽略,一個(gè)失敗,一個(gè)錯(cuò)誤。2.8 運(yùn)行器RunWith當(dāng)把測(cè)試代碼提交給JUnit框架后,框架

22、就會(huì)通過(guò)Runner來(lái)運(yùn)行代碼。在JUnit中有很多個(gè)Runner,他們負(fù)責(zé)調(diào)用測(cè)試代碼,每一個(gè)Runner都有各自的特殊功能,你要根據(jù)需要選擇不同的Runner來(lái)運(yùn)行你的測(cè)試代碼。JUnit中有一個(gè)默認(rèn)Runner,如果你沒(méi)有指定,那么系統(tǒng)自動(dòng)使用默認(rèn)Runner來(lái)運(yùn)行你的代碼。也就是說(shuō),下面兩段代碼含義是完全一樣的:public class CalculatorTest. /該方式就是使用了默認(rèn)的Runner等價(jià)于RunWith(JUnit4ClassRunner.class)public class CalculatorTest. /聲明了Runner從上述例子可以看出,要想指定一個(gè)Ru

23、nner,需要使用RunWith標(biāo)注,并且把你所指定的Runner作為參數(shù)傳遞給它。另外一個(gè)要注意的是,RunWith是用來(lái)修飾類(lèi)的,而不是用來(lái)修飾函數(shù)的。只要對(duì)一個(gè)類(lèi)指定了Runner,那么這個(gè)類(lèi)中的所有函數(shù)都被這個(gè)Runner來(lái)調(diào)用。是對(duì)其他Runner的學(xué)習(xí):2.8.1 參數(shù)化測(cè)試RunWith(Parameterized. class )把一組組的測(cè)試數(shù)據(jù)集中放在一個(gè)集合中,這個(gè)集合作為測(cè)試類(lèi)的參數(shù),進(jìn)行集中測(cè)試,避免為每一組測(cè)試數(shù)據(jù)寫(xiě)一個(gè)測(cè)試方法。你可能遇到過(guò)這樣的函數(shù),它的參數(shù)有許多特殊值,或者說(shuō)他的參數(shù)分為很多個(gè)區(qū)域。比如,一個(gè)對(duì)考試分?jǐn)?shù)進(jìn)行評(píng)價(jià)的函數(shù),返回值分別為“優(yōu)秀,良好,

24、一般,及格,不及格”,因此你在編寫(xiě)測(cè)試的時(shí)候,至少要寫(xiě) 5 個(gè)測(cè)試,把這 5 中情況都包含了,這確實(shí)是一件很麻煩的事情。我們還使用我們先前的例子,測(cè)試一下“計(jì)算一個(gè)數(shù)的平方”這個(gè)函數(shù),暫且分三類(lèi):正數(shù)、 0 、負(fù)數(shù)。(1) 測(cè)試代碼按照之前的方法,要測(cè)試三類(lèi)就需要編寫(xiě)三個(gè)測(cè)試方法:public class AdvancedTest private static Calculator calculator = new Calculator(); Before public void clearCalculator() calculator.clear(); Testpublic void squ

25、are1() calculator.square( 2 ); assertEquals( 4 , calculator.getResult(); Testpublic void square2() calculator.square( 0 ); assertEquals( 0 , calculator.getResult(); Testpublic void square3() calculator.square( - 3 );assertEquals( 9 , calculator.getResult(); 運(yùn)行結(jié)果:為了簡(jiǎn)化類(lèi)似的測(cè)試, JUnit4 提出了“參數(shù)化測(cè)試”的概念,只寫(xiě)一個(gè)測(cè)

26、試函數(shù),把這若干種情況作為參數(shù)傳遞進(jìn)去,一次性的完成測(cè)試。代碼如下:RunWith(Parameterized. class )/更改默認(rèn)的測(cè)試運(yùn)行器為Parameterized.classpublic class SquareTest private static Calculator calculator = new Calculator(); private int param;/聲明變量存放輸入?yún)?shù)(用來(lái)計(jì)算實(shí)際結(jié)果) private int result;/聲明變量存放預(yù)期值 /聲明一個(gè)返回值為Collection的公共靜態(tài)方法,并用Parameters修飾Parameterspub

27、lic static Collection data() return Arrays.asList( new Object 2,4 , 0,0 , -3 ,9 ); /為測(cè)試類(lèi)聲明一個(gè)帶有參數(shù)的公共構(gòu)造方法,并為聲明變量賦值 public SquareTest( int param, int result) this .param = param; this .result = result; Test public void square() calculator.square(param); assertEquals(result, calculator.getResult(); 分析:首

28、先,要為這種測(cè)試專(zhuān)門(mén)生成一個(gè)新的類(lèi),而不能與其他測(cè)試共用同一個(gè)類(lèi),此例中我們定義了一個(gè)SquareTest類(lèi)。然后,你要為這個(gè)類(lèi)指定一個(gè)Runner,而不能使用默認(rèn)的Runner了,因?yàn)樘厥獾墓δ芤锰厥獾腞unner。RunWith(Parameterized.class)這條語(yǔ)句就是為這個(gè)類(lèi)指定了一個(gè)ParameterizedRunner。第二步,定義一個(gè)待測(cè)試的類(lèi),并且定義兩個(gè)變量,一個(gè)用于存放參數(shù),一個(gè)用于存放期待的結(jié)果。接下來(lái),定義測(cè)試數(shù)據(jù)的集合,也就是上述的data()方法,該方法可以任意命名,但是必須使用Parameters標(biāo)注進(jìn)行修飾。之后是構(gòu)造函數(shù),其功能就是對(duì)先前定義的兩個(gè)參數(shù)進(jìn)行初始化。(2) 測(cè)試結(jié)果2.8.2 測(cè)試套件RunWith(Suite.class)通過(guò)前面的案例學(xué)習(xí)到,在一個(gè)項(xiàng)目中,只寫(xiě)一個(gè)測(cè)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論