構(gòu)建本地單元測(cè)試

如果你的單元測(cè)試沒(méi)有依賴或者只有Android上的簡(jiǎn)單依賴,你應(yīng)該在本地開(kāi)發(fā)機(jī)器上運(yùn)行測(cè)試瞬捕。 這種測(cè)試方法是高效的鞍历,因?yàn)樗梢詭椭苊饷看芜\(yùn)行測(cè)試時(shí)將目標(biāo)應(yīng)用程序和單元測(cè)試代碼加載到物理設(shè)備或模擬器上的開(kāi)銷(xiāo)。 因此肪虎,運(yùn)行單元測(cè)試的執(zhí)行時(shí)間大大減少劣砍。 使用這種方法,通常使用模擬框架(如Mockito)來(lái)實(shí)現(xiàn)任何依賴關(guān)系扇救。

配置測(cè)試環(huán)境

在您的Android Studio項(xiàng)目中刑枝,必須將用于本地單元測(cè)試的源文件存儲(chǔ)在module-name / src / test / java /。 創(chuàng)建新項(xiàng)目時(shí)迅腔,此目錄已存在装畅。

您還需要為項(xiàng)目配置測(cè)試依賴關(guān)系,以使用JUnit 4框架提供的標(biāo)準(zhǔn)API沧烈。 如果您的測(cè)試需要與Android依賴關(guān)系交互掠兄,請(qǐng)包括Mockito庫(kù)以簡(jiǎn)化本地單元測(cè)試。 要了解有關(guān)在本地單元測(cè)試中使用模擬對(duì)象的更多信息锌雀,請(qǐng)參閱下面的Mocking Android dependencies蚂夕。

在應(yīng)用程序的頂級(jí)build.gradle文件中,您需要將這些庫(kù)指定為依賴關(guān)系:

dependencies {
    // Required -- JUnit 4 framework
    testCompile 'junit:junit:4.12'
    // Optional -- Mockito framework
    testCompile 'org.mockito:mockito-core:1.10.19'
}

創(chuàng)建一個(gè)本地單元測(cè)試類

你的本地單元測(cè)試類應(yīng)該寫(xiě)成一個(gè)JUnit 4測(cè)試類腋逆。 JUnit是Java最受歡迎和廣泛使用的單元測(cè)試框架双抽。 這個(gè)框架的最新版本,JUnit 4闲礼,允許你以比它的前任版本更清潔和更靈活的方式編寫(xiě)測(cè)試。 與以前的基于JUnit 3的Android單元測(cè)試的方法不同,使用JUnit 4柬泽,您不需要擴(kuò)展junit.framework.TestCase類慎菲。 您也不需要在測(cè)試方法名稱前加上'test'關(guān)鍵字,或者使用junit.framework或junit.extensions包中的任何類锨并。

要?jiǎng)?chuàng)建基本的JUnit 4測(cè)試類露该,請(qǐng)創(chuàng)建一個(gè)包含一個(gè)或多個(gè)測(cè)試方法的Java類。 測(cè)試方法以@Test注釋開(kāi)始第煮,包含練習(xí)和驗(yàn)證要測(cè)試的組件中的單個(gè)功能的代碼解幼。

以下示例顯示如何實(shí)現(xiàn)本地單元測(cè)試類。 測(cè)試方法emailValidator_CorrectEmailSimple_ReturnsTrue驗(yàn)證被測(cè)應(yīng)用程序中的isValidEmail()方法是否返回正確的結(jié)果包警。

以下示例顯示如何實(shí)現(xiàn)本地單元測(cè)試類撵摆。 測(cè)試方法emailValidator_CorrectEmailSimple_ReturnsTrue驗(yàn)證被測(cè)應(yīng)用程序中的isValidEmail()方法是否返回正確的結(jié)果。

import org.junit.Test;
import java.util.regex.Pattern;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class EmailValidatorTest {

    @Test
    public void emailValidator_CorrectEmailSimple_ReturnsTrue() {
        assertThat(EmailValidator.isValidEmail("name@email.com"), is(true));
    }
    ...
}

要測(cè)試應(yīng)用程序中的組件是否返回預(yù)期結(jié)果害晦,請(qǐng)使用junit.Assert方法執(zhí)行驗(yàn)證檢查(或斷言)特铝,以便將受測(cè)試組件的狀態(tài)與某些預(yù)期值進(jìn)行比較。 為了使測(cè)試更可讀壹瘟,可以使用Hamcrest matchers(例如is()和equalTo()方法)將返回的結(jié)果與預(yù)期結(jié)果進(jìn)行匹配鲫剿。

Mock Android dependencies

默認(rèn)情況下,Gradle的Android插件針對(duì)android.jar庫(kù)的修改版本執(zhí)行本地單元測(cè)試稻轨,該版本不包含任何實(shí)際代碼灵莲。 相反,從單元測(cè)試中調(diào)用Android類的方法會(huì)拋出異常殴俱。 這是為了確保你只測(cè)試你的代碼政冻,不依賴于Android平臺(tái)的任何特定的行為(當(dāng)沒(méi)有明確模擬時(shí))。

您可以使用模擬框架在代碼中存根外部依賴關(guān)系粱挡,以便輕松測(cè)試您的組件是否按照預(yù)期的方式與依賴關(guān)系交互赠幕。 通過(guò)用模擬對(duì)象替換Android依賴項(xiàng),您可以將單元測(cè)試與Android系統(tǒng)的其余部分隔離询筏,同時(shí)驗(yàn)證這些依賴關(guān)系中的正確方法是否被調(diào)用榕堰。 Java的Mockito mocking框架(1.9.5及更高版本)提供了與Android單元測(cè)試的兼容性。 使用Mockito嫌套,您可以配置模擬對(duì)象以在調(diào)用時(shí)返回一些特定值逆屡。

要使用此框架將mock對(duì)象添加到本地單元測(cè)試,請(qǐng)遵循以下編程模型:
1> 在build.gradle文件中包含Mockito庫(kù)依賴關(guān)系踱讨,如配置測(cè)試環(huán)境中所述魏蔗。
2> 在單元測(cè)試類定義的開(kāi)始,添加@RunWith(MockitoJUnitRunner.class)注釋痹筛。 這個(gè)注釋告訴Mockito測(cè)試運(yùn)行器驗(yàn)證你的框架的使用是正確的莺治,并簡(jiǎn)化了你的模擬對(duì)象的初始化廓鞠。
3> 要為Android依賴項(xiàng)創(chuàng)建模擬對(duì)象,請(qǐng)?jiān)谧侄温暶髦疤砑覢Mock注釋谣旁。
4> 要存根依賴關(guān)系的行為床佳,可以使用when()和thenReturn()方法指定條件并返回值。

以下示例顯示如何創(chuàng)建使用mock Context對(duì)象的單元測(cè)試榄审。

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import android.content.SharedPreferences;

@RunWith(MockitoJUnitRunner.class)
public class UnitTestSample {

    private static final String FAKE_STRING = "HELLO WORLD";

    @Mock
    Context mMockContext;

    @Test
    public void readStringFromContext_LocalizedString() {
        // Given a mocked Context injected into the object under test...
        when(mMockContext.getString(R.string.hello_word))
                .thenReturn(FAKE_STRING);
        ClassUnderTest myObjectUnderTest = new ClassUnderTest(mMockContext);

        // ...when the string is returned from the object under test...
        String result = myObjectUnderTest.getHelloWorldString();

        // ...then the result should be the expected one.
        assertThat(result, is(FAKE_STRING));
    }
}

要了解有關(guān)使用Mockito框架的更多信息砌们,請(qǐng)參閱Mockito API reference和示例代碼中的SharedPreferencesHelperTest類。

如果Android.jar中的Android API拋出的異常對(duì)于測(cè)試有問(wèn)題搁进,您可以更改行為浪感,以使方法通過(guò)在項(xiàng)目的頂級(jí)build.gradle文件中添加以下配置來(lái)返回null或零:

android {
  ...
  testOptions {
    unitTests.returnDefaultValues = true
  }
}

警告:將returnDefaultValues屬性設(shè)置為true應(yīng)該小心。 null/零返回值可以在測(cè)試中引入回歸饼问,這難以調(diào)試影兽,并且可能允許失敗的測(cè)試通過(guò)。 只能使用它作為最后的手段匆瓜。

運(yùn)行本地單元測(cè)試

要運(yùn)行本地單元測(cè)試赢笨,請(qǐng)按照下列步驟操作:
1> 通過(guò)單擊工具欄中的Sync Project,確保您的項(xiàng)目與Gradle同步驮吱。
2> 使用以下方法之一運(yùn)行測(cè)試:
a> 要運(yùn)行單個(gè)測(cè)試茧妒,請(qǐng)打開(kāi)“ Project”窗口,然后右鍵單擊測(cè)試左冬,然后單擊Run桐筏。
b> 要測(cè)試類中的所有方法,請(qǐng)右鍵單擊測(cè)試文件中的類或方法拇砰,然后單擊Run梅忌。
c> 要在目錄中運(yùn)行所有測(cè)試,請(qǐng)右鍵單擊目錄并選擇Run tests除破。
Gradle的Android插件編譯位于默認(rèn)目錄(src / test / java /)中的本地單元測(cè)試代碼牧氮,構(gòu)建一個(gè)測(cè)試app,并使用默認(rèn)的測(cè)試運(yùn)行器類在本地執(zhí)行它瑰枫。 然后踱葛,Android Studio將在“ Run”窗口中顯示結(jié)果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末光坝,一起剝皮案震驚了整個(gè)濱河市尸诽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盯另,老刑警劉巖性含,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鸳惯,居然都是意外死亡商蕴,警方通過(guò)查閱死者的電腦和手機(jī)叠萍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)究恤,“玉大人俭令,你說(shuō)我怎么就攤上這事〔克蓿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵瓢湃,是天一觀的道長(zhǎng)理张。 經(jīng)常有香客問(wèn)我,道長(zhǎng)绵患,這世上最難降的妖魔是什么雾叭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮落蝙,結(jié)果婚禮上织狐,老公的妹妹穿的比我還像新娘。我一直安慰自己筏勒,他們只是感情好移迫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著管行,像睡著了一般厨埋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捐顷,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天荡陷,我揣著相機(jī)與錄音,去河邊找鬼迅涮。 笑死废赞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叮姑。 我是一名探鬼主播唉地,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼戏溺!你這毒婦竟也來(lái)了渣蜗?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤旷祸,失蹤者是張志新(化名)和其女友劉穎耕拷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體托享,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骚烧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年浸赫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赃绊。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡既峡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碧查,到底是詐尸還是另有隱情运敢,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布忠售,位于F島的核電站传惠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏稻扬。R本人自食惡果不足惜卦方,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泰佳。 院中可真熱鬧盼砍,春花似錦、人聲如沸逝她。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汽绢。三九已至吗跋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宁昭,已是汗流浹背跌宛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留积仗,地道東北人疆拘。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像寂曹,于是被迫代替她去往敵國(guó)和親哎迄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,081評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理隆圆,服務(wù)發(fā)現(xiàn)漱挚,斷路器,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 一渺氧、百變怪 Mockito Mockito可謂是Java世界的百變怪旨涝,使用它,可以輕易的復(fù)制出各種類型的對(duì)象侣背,并與...
    羅力閱讀 3,922評(píng)論 3 18
  • 回顧: 《談?wù)劄槭裁磳?xiě)單元測(cè)試》 基本單元測(cè)試框架 Java單元測(cè)試框架:Junit、Mockito弧腥、Powerm...
    鍵盤(pán)男閱讀 50,540評(píng)論 19 160
  • 姚安的天氣總是那么好厦取,是吧。這種感覺(jué)很舒服管搪。 世界上最大的激勵(lì)莫過(guò)于你去努力之后發(fā)現(xiàn)原來(lái)看起來(lái)很難的事情你也可以做...
    稻城禾歡閱讀 152評(píng)論 0 0