android 中的單元測試——使用JUnit 做本地java測試

下面介紹一下如何使用 junit框架。JUnit(https://junit.org/junit5/) 是一個(gè)很著名的java 單元測試框架雷绢。由于是基于針對java 做測試的,所以是沒有android 環(huán)境的儡炼,當(dāng)然 android 中的一些工具類也是不能使用的芒帕,比如TextUtils(android.text.TextUtils)這個(gè)類。

http://d.android.com/tools/testing
https://developer.android.com/training/testing/fundamentals

demo 示例介紹

新建項(xiàng)目

android studio新建的 android 項(xiàng)目默認(rèn)自帶 java unitTestandroid 的相關(guān)單元測試框架敲茄。

如果沒有我們可以在項(xiàng)目的gradle文件中剛添加

testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

上面三行代碼 testImplementation 'junit:junit:4.12’ 是用來添 junit

下面的兩個(gè)代碼是用來添加 runnerespresso 框架位谋。

由于沒有 android 環(huán)境的類,所以JUnit 比較適合做純java的基本類方法的單元測試堰燎。

首先來看一個(gè) android studio 創(chuàng)建的項(xiàng)目自帶的一個(gè)單元測試代碼掏父,來看看 JUnit 是如何使用的。 在項(xiàng)目中找到ExampleUnitTest這個(gè)類秆剪,位置在

Project 模式下 模塊名稱/src/test/java/{項(xiàng)目包路徑}/ExampleUnitTest.java

如圖所示:

image.png
image.png

在Project 視圖或 Android 視圖中測試文件的所在位置

ExampleUnitTest.java 這個(gè)文件的代碼如下:

package cn.com.qianli.demoforunittest;

import org.junit.Test;
import static org.junit.Assert.*;

/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="[http://d.android.com/tools/testing](http://d.android.com/tools/testing)">Testing documentation</a>
*/
public class ExampleUnitTest {
  @Test public void addition_isCorrect() throws Exception {
    assertEquals(4, 2 + 2);
  }
}

可以看到代碼還是比較簡單的赊淑,要說明的就是 @Test 是junitTest 框架中的 annotation。

我們進(jìn)入到Junit的代碼中看一下

/**
* Asserts that two longs are equal. If they are not, an
* {@link AssertionError} is thrown.
*
* @param expected expected long value.
* @param actual actual long value
*/

static public void assertEquals(long expected, long actual) {
    assertEquals(null, expected, actual);
}

/**
* Asserts that two longs are equal. If they are not, an
* {@link AssertionError} is thrown with the given message.
*
* @param message the identifying message for the {@link AssertionError} (<code>null</code>
* okay)
* @param expected long expected value.
* @param actual long actual value
*/

static public void assertEquals(String message, long expected, long actual) {
    if (expected != actual) {
        failNotEquals(message, Long.valueOf(expected), Long.valueOf(actual));
    }
}

其實(shí)仅讽,assertEquals方法是 org.junit中 Assert這個(gè)類下的一系列重載方法陶缺。如下:

image.png

當(dāng)然 Assert這個(gè)類還有其他方法:

image.png

我們在自己編寫單元測試代碼的時(shí)候可以根據(jù)情況使用合適的方法做效驗(yàn)。

我們來執(zhí)行 ExampleUnitTest 看看效果洁灵。在文件上右擊鼠標(biāo)饱岸,出現(xiàn)下面這樣的彈出框。

可以看到3個(gè)運(yùn)行選項(xiàng)徽千。

第一個(gè) :Run ‘ExampleUnitTest’

這個(gè)直接運(yùn)行測試用例苫费,看結(jié)果的。

第二個(gè):Debug ‘ExampleUnitTest’

運(yùn)行這個(gè)是可以直接進(jìn)行debug的双抽,方式和我們debug android代碼類似百框。

第三個(gè):

Run ‘ExampleUnitTest’ with Coverage

https://www.jetbrains.com/help/idea/running-test-with-coverage.html

image.png
image.png

這里我們運(yùn)行第一個(gè) Run ‘ExampleUnitTest’ 可以看到結(jié)果如下。


image.png

順便說明牍汹,如果你在右擊的時(shí)候是在某一個(gè)方法上右擊的铐维,那么執(zhí)行的是只是某一個(gè)方法內(nèi)的測試代碼。

如果右擊的時(shí)候不再任何方法內(nèi)慎菲,那么執(zhí)行的是這個(gè)測試用例文件中所有的測試方法嫁蛇。

image.png

還可以通過界面上的快捷方式來執(zhí)行測試用例。

1 的小圖標(biāo)點(diǎn)擊后是執(zhí)行 ExampleUnitTest中所有的測試case露该, 2 則是執(zhí)行addition_isCorrect 單個(gè)方法的用例棠众。

3處雙擊和2的效果一樣,執(zhí)行的是addition_isCorrect 單個(gè)方法的用例。

image.png

寫一個(gè)自己的測試用例

下面我們用一個(gè)具體的真實(shí)業(yè)務(wù)例子說明一下闸拿,在真實(shí)項(xiàng)目中測試用例的使用情況空盼。

比如,我們需要寫一個(gè)簡單的字符處理新荤。

需要將電話號碼或者銀行卡號按照 344 的格式顯示揽趾,比如 13512341234 顯示為 135 1234 1234 。銀行卡號也顯示為每4為一個(gè)間隔顯示苛骨。

我們二話不說寫一個(gè)方法簽名:

public static String toPhoneGapString(){

  return ""

}

沒有任何實(shí)現(xiàn)篱瞎,這個(gè)時(shí)候在方法簽名上右擊,

image.png
image.png

選擇Create New Test…

image.png

出現(xiàn)的對話框勾選需要?jiǎng)?chuàng)建的方法痒芝,我們勾選 toPhoneGapString():String

點(diǎn)擊Ok

image.png

出現(xiàn)一個(gè)對話框讓選擇目錄俐筋,我們這個(gè)方法是一個(gè)基本的java方法,所以我們選擇test目錄下的這個(gè)目錄严衬。

就可以看到有一個(gè)新的測試用例文件生成:

image.png

寫一行簡單的測試用例代碼澄者,運(yùn)行試試看。

image.png

我們的實(shí)現(xiàn)是空的请琳,這里當(dāng)然不可能符合預(yù)期粱挡。這個(gè)時(shí)候我們需要改進(jìn)修改我們的方法toPhoneGapString

給方法簽名加入?yún)?shù) String inputStr

具體實(shí)現(xiàn)一段代碼如下:

public static String toPhoneGapString(String inputStr) {

  if (inputStr == null) {

    return "";

  }

  StringBuilder stringBuilder = new StringBuilder();

  for (int i = 0; i < inputStr.length();i++) {

    stringBuilder.append(inputStr.charAt(i));

    if((i + 1) % 4 == 3 && (i + 1) != inputStr.length()){

      stringBuilder.append(' ');

    }

  }

  return stringBuilder.toString();

}

對我們的單元測試case也做一下修改俄精,這個(gè)時(shí)候我們再次執(zhí)行單元測試文件询筏。

image.png

就可以看到舒心的綠色pass了。(話說竖慧,綠色為什么會舒心呢嫌套?)

我們再加上更多的測試用例,如下:

  1. 電話號碼多一位圾旨,以 3 4 4 1 的格式輸出灌危,也就是輸出多一個(gè)空格和多出來的數(shù)字。

  2. 電話號碼少一位碳胳,以 3 4 2 的格式輸出,

  3. 電話號碼中多空格沫勿,希望輸出正常的分割電話號碼

基于這樣的case 我們寫單元測試代碼

assertEquals("135 1234 1234 2", StringUtil.toPhoneGapString("135123412342"));

assertEquals("135 1234 123", StringUtil.toPhoneGapString("1351234123"));

assertEquals("135 1234 1234", StringUtil.toPhoneGapString("135123412 3 4"));

再次執(zhí)行挨约。

image.png

發(fā)現(xiàn)最后一個(gè)case 并沒有通過。

這個(gè)時(shí)候就是我們寫代碼的時(shí)候了产雹,修改方法诫惭,知道通過這個(gè)case位置。

只要我們在測試用例中覆蓋了所有的case蔓挖,并且保證運(yùn)行通過夕土,那么我們的小方法就是經(jīng)過測試的。

作為開發(fā)人員也就更加胸有成竹,而不是盲目自信怨绣,迷之自信了角溃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市篮撑,隨后出現(xiàn)的幾起案子减细,更是在濱河造成了極大的恐慌,老刑警劉巖赢笨,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件未蝌,死亡現(xiàn)場離奇詭異,居然都是意外死亡茧妒,警方通過查閱死者的電腦和手機(jī)萧吠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桐筏,“玉大人纸型,你說我怎么就攤上這事【琶粒” “怎么了绊袋?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铸鹰。 經(jīng)常有香客問我癌别,道長,這世上最難降的妖魔是什么蹋笼? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任展姐,我火速辦了婚禮,結(jié)果婚禮上剖毯,老公的妹妹穿的比我還像新娘圾笨。我一直安慰自己,他們只是感情好逊谋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布擂达。 她就那樣靜靜地躺著,像睡著了一般胶滋。 火紅的嫁衣襯著肌膚如雪板鬓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天究恤,我揣著相機(jī)與錄音俭令,去河邊找鬼。 笑死部宿,一個(gè)胖子當(dāng)著我的面吹牛抄腔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼赫蛇,長吁一口氣:“原來是場噩夢啊……” “哼绵患!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棍掐,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤藏雏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后作煌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掘殴,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年粟誓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奏寨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹰服,死狀恐怖病瞳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悲酷,我是刑警寧澤套菜,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站设易,受9級特大地震影響逗柴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜顿肺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一戏溺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屠尊,春花似錦旷祸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浸赫,卻和暖如春闰围,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掺炭。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凭戴,地道東北人涧狮。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親者冤。 傳聞我的和親對象是個(gè)殘疾皇子肤视,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容