在《初入Android單元測(cè)試》中我們對(duì)Android單元測(cè)試有了一個(gè)大概的了解,我們直接進(jìn)入項(xiàng)目測(cè)試環(huán)節(jié)。直接用代碼來(lái)學(xué)習(xí)單元測(cè)試。
我們寫(xiě)單元測(cè)試,一般都會(huì)用到一個(gè)或多個(gè)單元測(cè)試框架,在這里,我們介紹一下JUnit4這個(gè)測(cè)試框架。這是Java界用的廣泛,也是基礎(chǔ)的一個(gè)框架,其他的很多框架,包括我們后面會(huì)看到的Robolectric,都是基于或兼容JUnit4的。
在Android工程中引入JUnit
在Android項(xiàng)目里面使用JUnit是很簡(jiǎn)單的,你只需要將JUnit這個(gè)library加到你的dependencies里面。
testCompile 'junit:junit:4.12'
當(dāng)然,如果你是通過(guò)Android Studio來(lái)創(chuàng)建的項(xiàng)目,那么這個(gè)dependency默認(rèn)是加上了的,所以你甚至這步都可以省略。
JUnit基本的使用
當(dāng)我們通過(guò)Android Studio創(chuàng)建好項(xiàng)目之后,我們?cè)趕rc/androidTest/java下,會(huì)看到自動(dòng)生成了的單元測(cè)試代碼
雖然代碼很少,但是在看代碼之前,我們也先來(lái)學(xué)習(xí)一下JUnit中的一些知識(shí)點(diǎn)。
@Test : 通過(guò)給某個(gè)方法添加這個(gè)注解,JUnit會(huì)把它當(dāng)作是一個(gè)需要測(cè)試的方法。
assertEquals(expected, actual):驗(yàn)證expected的值跟actual是一樣的,如果是一樣的話,測(cè)試通過(guò),不然的話,測(cè)試失敗。
可以看到自動(dòng)生成的代碼中有一個(gè)useAppContext()的方法,該方法上面也標(biāo)注了@Test注解,所以該方法是一個(gè)可以測(cè)試的方法,里面只有兩行代碼,它的作用是判斷當(dāng)前測(cè)試的app包名是否等于"com.whyalwaysmea.junit"(當(dāng)然,你的代碼此處應(yīng)該是你自己的包名)
點(diǎn)擊左側(cè)的運(yùn)行按鈕,可以直接對(duì)該方法進(jìn)行測(cè)試運(yùn)行了。如果包名和字符串相等,那么測(cè)試方法會(huì)運(yùn)行成功,如果包名和字符串不相等,那么測(cè)試方法會(huì)報(bào)錯(cuò),具體的可以看所打印出來(lái)的log
JUnit的更多方法
更多的注解:
@Before: 如果一個(gè)方法被@Before修飾過(guò)了,那么在每個(gè)測(cè)試方法調(diào)用之前,這個(gè)方法都會(huì)得到調(diào)用。
@After: 每個(gè)測(cè)試方法運(yùn)行結(jié)束之后,會(huì)運(yùn)行的方法。比如一個(gè)測(cè)試文件操作的類(lèi),那么在它的測(cè)試類(lèi)中,可能@Before里面需要去打開(kāi)一個(gè)文件,而每個(gè)測(cè)試方法運(yùn)行結(jié)束之后,都需要去close這個(gè)文件。這個(gè)時(shí)候可以把文件close的操作放在@After里面,讓它自動(dòng)去執(zhí)行。
類(lèi)似的,還有@BeforeClass和@AfterClass。@BeforeClass的作用是,在跑一個(gè)測(cè)試類(lèi)的所有測(cè)試方法之前,會(huì)執(zhí)行一次被@BeforeClass修飾的方法,執(zhí)行完所有測(cè)試方法之后,會(huì)執(zhí)行一遍被@AfterClass修飾的方法。
@Ignore: 很多時(shí)候,因?yàn)槟承┰颍ū热缯酱a還沒(méi)有實(shí)現(xiàn)等),我們可能想讓JUnit忽略某些方法,讓它在跑所有測(cè)試方法的時(shí)候不要跑這個(gè)測(cè)試方法。要達(dá)到這個(gè)目的也很簡(jiǎn)單,只需要在要被忽略的測(cè)試方法前面加上@Ignore可以了
更多驗(yàn)證:
assertEquals(expected, actual, tolerance)
這里傳入的expected和actual是float或double類(lèi)型的,大家知道計(jì)算機(jī)表示浮點(diǎn)型數(shù)據(jù)都有一定的偏差,所以哪怕理論上他們是相等的,但是用計(jì)算機(jī)表示出來(lái)則可能不是,所以這里運(yùn)行傳入一個(gè)偏差值。如果兩個(gè)數(shù)的差異在這個(gè)偏差值之內(nèi),則測(cè)試通過(guò),否者測(cè)試失敗。
assertTrue(boolean condition)
驗(yàn)證contidion的值是true
assertFalse(boolean condition)
驗(yàn)證contidion的值是false
assertNull(Object obj)
驗(yàn)證obj的值是null
assertNotNull(Object obj)
驗(yàn)證obj的值不是null
assertSame(expected, actual)
驗(yàn)證expected和actual是同一個(gè)對(duì)象,即指向同一個(gè)對(duì)象
assertNotSame(expected, actual)
驗(yàn)證expected和actual不是同一個(gè)對(duì)象,即指向不同的對(duì)象
注意:上面的每一個(gè)方法,都有一個(gè)重載的方法,可以在前面加一個(gè)String類(lèi)型的參數(shù),表示如果驗(yàn)證失敗的話,將用這個(gè)字符串作為失敗的結(jié)果報(bào)告。
比如:
assertEquals("Current user Id should be 1", 1, currentUser.id());
當(dāng)currentUser.id()的值不是1的時(shí)候,在結(jié)果報(bào)道里面將顯示"Current user Id should be 1",這樣可以讓測(cè)試結(jié)果更具有可讀性,更清楚錯(cuò)誤的原因是什么。
總結(jié)
該篇主要介紹了JUnit的一些基本使用,當(dāng)然他的功能不僅于此,畢竟他是java項(xiàng)目中使用廣泛的單元測(cè)試框架。