![Android 單元測(cè)試和 UI 測(cè)試初步實(shí)踐_第1頁(yè)](http://file4.renrendoc.com/view/50d4fe11efa775545a15721f465e5faa/50d4fe11efa775545a15721f465e5faa1.gif)
![Android 單元測(cè)試和 UI 測(cè)試初步實(shí)踐_第2頁(yè)](http://file4.renrendoc.com/view/50d4fe11efa775545a15721f465e5faa/50d4fe11efa775545a15721f465e5faa2.gif)
![Android 單元測(cè)試和 UI 測(cè)試初步實(shí)踐_第3頁(yè)](http://file4.renrendoc.com/view/50d4fe11efa775545a15721f465e5faa/50d4fe11efa775545a15721f465e5faa3.gif)
![Android 單元測(cè)試和 UI 測(cè)試初步實(shí)踐_第4頁(yè)](http://file4.renrendoc.com/view/50d4fe11efa775545a15721f465e5faa/50d4fe11efa775545a15721f465e5faa4.gif)
![Android 單元測(cè)試和 UI 測(cè)試初步實(shí)踐_第5頁(yè)](http://file4.renrendoc.com/view/50d4fe11efa775545a15721f465e5faa/50d4fe11efa775545a15721f465e5faa5.gif)
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第第頁(yè)Android單元測(cè)試和UI測(cè)試初步實(shí)踐
采用Mockito框架mock一個(gè)測(cè)試用的DataManager和V層代理NewsContract.View。所謂的mock就是創(chuàng)建一個(gè)類(lèi)的虛假的對(duì)象,在測(cè)試環(huán)境中,用來(lái)替換掉真實(shí)的對(duì)象,以達(dá)到驗(yàn)證對(duì)象方法調(diào)用情況,或是指定這個(gè)對(duì)象的某些方法返回特定的值等;@Before注解的方法會(huì)在執(zhí)行測(cè)試用例之前執(zhí)行,這里做一個(gè)初始化的操作,主要是Mockito框架的初始化及presenter的初始化;@After注解的方法會(huì)在執(zhí)行測(cè)試用例之后執(zhí)行,這里做一個(gè)presenter的detach()操作,防止出現(xiàn)內(nèi)存泄露等問(wèn)題;@Test注解的方法是實(shí)際執(zhí)行的(測(cè)試方法)。這里根據(jù)之前的業(yè)務(wù)代碼邏輯:環(huán)境初始化:由于NewsPresenter的業(yè)務(wù)邏輯中是需要DataManager返回一個(gè)NewsResultBean實(shí)例才能進(jìn)行后續(xù)的操作,而mock的話(huà)只能返回一個(gè)空對(duì)象,所以在代碼前兩行筆者通過(guò)Mockito的when()方法,在程序調(diào)用DataManager#getNews()方法時(shí)返回一個(gè)空的NewsResultBean實(shí)例。執(zhí)行操作:執(zhí)行P層的NewsPresenter#getNews()。在業(yè)務(wù)邏輯中,執(zhí)行此方法之后,會(huì)先調(diào)用DataManager#getNews(),然后將數(shù)據(jù)交給V層的代理。驗(yàn)證結(jié)果正確性:一般來(lái)說(shuō),我們要驗(yàn)證一個(gè)方法執(zhí)行結(jié)果是否正確,最簡(jiǎn)單的方法的就是看執(zhí)行完的方法輸出是否與預(yù)期輸出相一致。但在這里,NewsPresenter#getNews()為一個(gè)void方法,沒(méi)有返回值,那么該怎么驗(yàn)證呢?其實(shí)這個(gè)方法也是有輸出的,輸出就是:調(diào)用了DataManager#getNews()方法,獲取到數(shù)據(jù)后調(diào)用NewsContract.View#showNews(news)顯示數(shù)據(jù)。所以這里主要驗(yàn)證的是DataManager#getNews()和NewsContract.View#showProgress(),NewsContract.View#showNews(news)和NewsContract.View#hideProgress()這三個(gè)方法是否有被調(diào)用到,這里運(yùn)用到Mockito的verify()方法。至此,一個(gè)Android的單元測(cè)試用例編寫(xiě)完成。通過(guò)AndroidStudio直接運(yùn)行此單元測(cè)試用例,結(jié)果如下:
需要明白一個(gè)點(diǎn):?jiǎn)卧獪y(cè)試它只是測(cè)試一個(gè)方法單元,它不是測(cè)試一整個(gè)APP的功能流程,即單元測(cè)試不會(huì)涉及到(數(shù)據(jù)庫(kù))或網(wǎng)絡(luò)等復(fù)雜的外部環(huán)境。比如說(shuō)這里我們只測(cè)試到NewsPresenter#getNews()方法,并沒(méi)有測(cè)試NewsFragment的整個(gè)初始化到顯示的過(guò)程是否正常,數(shù)據(jù)是否有誤。(這樣的測(cè)試往往稱(chēng)之為集成測(cè)試)
AndroidUI測(cè)試實(shí)踐
創(chuàng)建新用例如果要編寫(xiě)一個(gè)新的本地UI測(cè)試用例,只需打開(kāi)你想測(cè)試的java代碼文件,然后點(diǎn)擊類(lèi)名??T(Windows:Ctrl+Shift+T)選擇要生成的方法選擇androidTest文件夾,對(duì)應(yīng)于本地UI測(cè)試完成。
增加依賴(lài)庫(kù)需要Espresso框架支持,所以在build.gradle中增加(注意是androidTestImplementation):
androidTestImplementationandroidx.test:runner:1.1.0androidTestImplementationandroidx.test:rules:1.1.0androidTestImplementationandroidx.test.espresso:espresso-core:3.0.2androidTestImplementationandroidx.test.espresso:espresso-contrib:3.0.2androidTestImplementationandroidx.test.espresso:espresso-intents:3.0.2androidTestImplementationandroidx.test.espresso.idling:idling-concurrent:3.0.2androidTestImplementationandroidx.test.espresso:espresso-idling-resource:3.0.2
編寫(xiě)測(cè)試代碼筆者主要測(cè)試的代碼為NewsDetailActivity,主要功能是加載intent傳遞過(guò)來(lái)的新聞標(biāo)題和新聞原文地址,然后在Toolbar中顯示新聞標(biāo)題,在(Web)view中加載此新聞。
對(duì)應(yīng)著,實(shí)際編寫(xiě)測(cè)試代碼的時(shí)候,可以構(gòu)造一個(gè)測(cè)試用的intent,在intent中加入需要的測(cè)試數(shù)據(jù),然后啟動(dòng)這個(gè)activity,檢查數(shù)據(jù)是否正確即可。這里我們借助Espresso框架,它有三個(gè)重要的組成部分:ViewMatchers(根據(jù)視圖id或其他屬性匹配指定的View),ViewActions(執(zhí)行View的某些行為,例如點(diǎn)擊事件),ViewAssertions(檢查View的某些狀態(tài),例如指定View是否顯示在屏幕上)。
新創(chuàng)建的UI測(cè)試代碼如下:
/***CreatedbyXuon2023/04/09.*/@RunWith(AndroidJUnit4.class)@LargeTestpublicclassNewsDetailActivityTest{@RulepublicActivityTestRuleNewsDetailActivitynewsDetailActivityActivityTestRule=newActivityTestRule(NewsDetailActivity.class,true,false);@BeforepublicvoidsetUp(){Intentintent=newIntent(InstrumentationRegistry.getInstrumentation().getTargetContext(),NewsDetailActivity.class);intent.putExtra(Constants.NEWS_URL,TestConstants.NEWS_DETAIL_ACTIVITY_TEST_URL);intent.putExtra(Constants.NEWS_IMG,TestConstants.NEWS_DETAIL_ACTIVITY_TEST_IMG);intent.putExtra(Constants.NEWS_TITLE,TestConstants.NEWS_DETAIL_ACTIVITY_TEST_TITLE);newsDetailActivityActivityTestRule.launchActivity(intent);IdlingRegistry.getInstance().register(newsDetailActivityActivityTestRule.getActivity().getCountingIdlingResource());}@TestpublicvoidshowNewsDetail(){onView(withId(R.id.toolbar)).check(matches(isDisplayed()));onView(withId(R.id.iv_news_detail_pic)).check(matches(isDisplayed()));onView(withId(R.id.clp_toolbar)).check(matches(isDisplayed()));onView(withId(R.id.clp_toolbar)).check(matches(withCollapsingToolbarLayoutText(is(TestConstants.NEWS_DETAIL_ACTIVITY_TEST_TITLE))));}@AfterpublicvoidtearDown(){IdlingRegistry.getInstance().unregister(newsDetailActivityActivityTestRule.getActivity().getCountingIdlingResource());}}
在其中:
在類(lèi)聲明的開(kāi)頭,添加了兩個(gè)注解@RunWith(AndroidJUnit4.class)和@LargeTest;@RunWith注解可以改變JUnit測(cè)試用例的的默認(rèn)執(zhí)行類(lèi),由于這里是需要Android環(huán)境且使用到Espresso框架,所以@RunWith選擇AndroidJUnit4類(lèi)。@LargeTest表示此測(cè)試用例會(huì)使用到外部文件系統(tǒng)或者網(wǎng)絡(luò),并且運(yùn)行時(shí)間大于1000ms。
聲明了一個(gè)變量newsDetailActivityActivityTestRule并用@Rule注解,newsDetailActivityActivityTestRule是ActivityTestRule的實(shí)例化對(duì)象。ActivityTestRule主要用來(lái)測(cè)試單個(gè)Activity,這個(gè)Activity將在@Test和@Before前啟動(dòng)。它其中包含一些基礎(chǔ)功能,例如啟動(dòng)Activity,獲取當(dāng)前Activity實(shí)例等;同樣的,這里@Before注解的方法會(huì)在執(zhí)行測(cè)試用例之前執(zhí)行,這里構(gòu)造一個(gè)測(cè)試用intent,最后通過(guò)newsDetailActivityActivityTestRule#launchActivity(intent)方法啟動(dòng)待測(cè)試Activity,并做一個(gè)IdlingResource的綁定;@After注解的方法會(huì)在執(zhí)行測(cè)試用例之后執(zhí)行,這里做一個(gè)IdlingResource的解綁操作;什么是IdlingResource呢?
通常來(lái)說(shuō),大多數(shù)APP在設(shè)計(jì)業(yè)務(wù)功能的過(guò)程中,會(huì)有很多的異步任務(wù),例如使用Rxjava發(fā)起網(wǎng)絡(luò)請(qǐng)求等,但是Espresso并不知道你的異步任務(wù)什么時(shí)候結(jié)束,如果單純使用Thread.sleep()等待異步回調(diào)的結(jié)果又過(guò)于"硬核',所以需要借助于IdlingResource這個(gè)類(lèi)。
它需要在業(yè)務(wù)代碼中添加相關(guān)的邏輯。例如在NewsDetailActivity中,會(huì)接收到intent傳遞過(guò)來(lái)的新聞圖片地址,然后使用Glide異步加載此圖片,大致代碼如下:
publicclassNewsDetailActivityextendsAppCompatActivity{@BindView(R.id.iv_news_detail_pic)privateImageViewivNewsDetailPic;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_news);//省略部分代碼邏輯//開(kāi)始發(fā)起異步操作,App開(kāi)始進(jìn)入忙碌狀態(tài)EspressoIdlingResource.increment();//開(kāi)始加載圖片Glide.with(context).asBitmap().load(imgUrl).into(newGlideDrawableImageViewTarget(mAvatar){@OverridepublicvoidonResourceReady(@NonNullBitmapresource,@NullableTransition?superBitmaptransition){super.onResourceReady(resource,transition);//異步操作結(jié)束,將App設(shè)置成空閑狀態(tài)if(!EspressoIdlingResource.getIdlingResource().isIdleNow()){EspressoIdlingResource.decrement();}}});}//省略代碼@VisibleForTestingpublicIdlingResourcegetCountingIdlingResource(){returnEspressoIdlingResource.getIdlingResource();}}publicclassEspressoIdlingResource{privatestaticfinalStringRESOURCE=GLOBAL;//Espresso提供了一個(gè)實(shí)現(xiàn)好的CountingIdlingResource類(lèi)//如果沒(méi)有特別(需求)的話(huà),直接使用它即可privatestaticCountingIdlingResourcecountingIdlingResource=newCountingIdlingResource(RESOURCE);publicstaticvoidincrement(){countingIdlingResource.increment();}publicstaticvoiddecrement(){countingIdlingResource.decrement();}publicstaticIdlingResourcegetIdlingResource(){if(countingIdlingResource==null){countingIdlingResource=newCountingIdlingResource(RESOURCE);}returncountingIdlingResource;}}
再加上我們?cè)跍y(cè)試代碼中聲明的IdlingRegistry.getInstance().register()和IdlingRegistry.getInstance().unregister()方法,根據(jù)APP是否處于忙碌狀態(tài)來(lái)判斷異步任務(wù)是否完成,這樣Espresso就能做到對(duì)異步任務(wù)進(jìn)行相應(yīng)的測(cè)試。
@Test注解的方法是實(shí)際執(zhí)行的測(cè)試方法。這里根據(jù)之前的業(yè)務(wù)代碼邏輯:環(huán)境初始化:模擬了測(cè)試的intent數(shù)據(jù)執(zhí)行操作:加載intent傳遞過(guò)來(lái)的數(shù)據(jù)驗(yàn)證結(jié)果正確性:檢查對(duì)應(yīng)的UI樣式是否正常顯示測(cè)試數(shù)據(jù),這里主要利用Espresso的幾個(gè)重要的API:onView():獲得視圖view,這里通過(guò)withId()方法搜索,即根據(jù)id來(lái)獲取對(duì)應(yīng)的viewcheck():檢驗(yàn)視圖view,可以檢查視圖文本是否匹配或者視圖是否顯示等,主要依靠match()方法返回對(duì)應(yīng)的匹配類(lèi),Espresso也自帶很多已封裝好的ViewMatchers供使用以鏈?zhǔn)酱a的形式編寫(xiě)驗(yàn)證測(cè)試結(jié)果的代碼,例如onView(withId(R.id.toolbar)).check(matches(isDisplayed()));意思就是獲取id為R.id.toolbar的view,檢查這個(gè)view是否正常顯示。
如果Espresso自帶的ViewMatchers不能滿(mǎn)足需求的話(huà),我們也可以自定義一個(gè)matcher,例如onView(withId(R.id.clp_toolbar)).check(matches(withCollapsingToolbarLayoutText(is(TestConstants.NEWS_DETAIL_ACTIVITY_TEST_TITLE))));,我們獲取到的view是一個(gè)CollapsingToolbarLayout,是一個(gè)特殊樣式的Toolbar,我們要檢查其中的標(biāo)題是否與測(cè)試數(shù)據(jù)相匹配,我們可以編寫(xiě)自定義的Matcher:
publicstaticMatcherViewwithCollapsingToolbarLayoutText(MatcherStringstringMatcher){returnnewBoundedMatcherView,CollapsingToolbarLayout(CollapsingToolbarLayout.class){@OverridepublicvoiddescribeTo(D
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 華東師大版八年級(jí)上冊(cè)數(shù)學(xué)聽(tīng)評(píng)課記錄《15.2.2利用統(tǒng)計(jì)圖表傳遞信息》
- 湘教版數(shù)學(xué)七年級(jí)上冊(cè)2.5《整式的加法和減法》聽(tīng)評(píng)課記錄6
- 滬教版數(shù)學(xué)九年級(jí)下冊(cè)27.3《正多邊形與圓》聽(tīng)評(píng)課記錄4
- 八年級(jí)數(shù)學(xué)上冊(cè) 12.2 三角形全等的判定 第2課時(shí) 用“SAS”判定三角形全等聽(tīng)評(píng)課記錄 新人教版
- 小學(xué)數(shù)學(xué)蘇教版六年級(jí)下冊(cè)《分?jǐn)?shù)和百分?jǐn)?shù)的實(shí)際應(yīng)用(總復(fù)習(xí))》公開(kāi)課聽(tīng)評(píng)課記錄
- 新北師大版數(shù)學(xué)一年級(jí)下冊(cè)《買(mǎi)鉛筆》聽(tīng)評(píng)課記錄
- 2025年煤制合成氨合作協(xié)議書(shū)
- 五年級(jí)上冊(cè)數(shù)學(xué)口算題
- 四年級(jí)教師教學(xué)計(jì)劃
- 一年級(jí)蘇教版數(shù)學(xué)下冊(cè)《認(rèn)識(shí)圖形》聽(tīng)評(píng)課記錄
- 中國(guó)太陽(yáng)能光電建筑行業(yè)現(xiàn)狀調(diào)研分析及市場(chǎng)前景預(yù)測(cè)報(bào)告(2024版)
- 關(guān)于防范遏制礦山領(lǐng)域重特大生產(chǎn)安全事故的硬措施課件
- 2025年中國(guó)成都餐飲業(yè)市場(chǎng)運(yùn)營(yíng)態(tài)勢(shì)分析及投資前景預(yù)測(cè)報(bào)告
- 2024年xx縣第三小學(xué)安全工作管理制度匯編
- 2024年榆林職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測(cè)試歷年參考題庫(kù)含答案解析
- 項(xiàng)目合作備忘錄范文
- DL∕T 1100.1-2018 電力系統(tǒng)的時(shí)間同步系統(tǒng) 第1部分:技術(shù)規(guī)范
- Interstellar-星際穿越課件
- 免疫及炎癥相關(guān)信號(hào)通路
- —橋梁專(zhuān)業(yè)施工圖設(shè)計(jì)審查要(終)
- 德龍自卸車(chē)合格證掃描件(原圖)
評(píng)論
0/150
提交評(píng)論