As mentioned in Chapter 4, “The Testing Pyramid,” integration tests perform checks on how different parts of your app interact together. You can use this level of test to verify the behavior of how classes work together within your app, with the Android framework, and with external libraries. It’s the next level up from unit tests.
Unit tests are great for ensuring that all your individual pieces work. Integration tests take it to the next level by testing the way these parts work together and within the greater Android environment.
In this chapter, you’ll:
Learn what an integration test is and where are the best places to use them.
Understand the dependency many integration tests have on the Android framework and how to handle it.
Write integration tests using the test-driven development (TDD) pattern to learn these concepts in the context of TDD.
Getting started
To learn TDD with integration tests, you’ll work on a Wishlist app. With this app, you can keep track of wishlists and gift ideas for all your friends and loved ones. You will continue working on this app in the next chapter.
Find the starter project for this app in the materials for this chapter, and open the starter project in Android Studio. Build and run the app. You’ll see a blank screen with a button to add a list on the bottom. Clicking the button, you see a field to add a name for someone’s wishlist. Enter all you want right now, but it won’t save yet. You’ll be able to see it when you finish the implementation. But don’t worry — you’ll see the results of your labor in lovely green tests until then!
When there are wishlists saved and displayed, you can click on them to show the detail of the items for that list and added items. You will write tests for the ViewModel of this detail screen in this chapter.
In the end, this is what the app will look like:
Explore the files in the app for a moment. The ones you need to be familiar with in this chapter are:
DetailViewModel.kt: This contains the logic for the detail screen, and is the class you will be testing.
Repository.kt: This is the interface for the data repository in this app.
RepositoryImpl.kt: This is the implementation of the Repository interface.
When to use integration tests
Integration tests tend to be slower than unit tests, but quicker than UI tests. Because of this, you want to first put everything you can into unit tests. You move to integration tests when you need to test something that you cannot do without interacting with another part of your app or an external element.
Pevuligfh, pqud wue yilg vi pwaele e eqal qonh nuf caz’y xidc uz em izunoceiv, bou fofh mu aku om akgitfefuij zixm. Xabuxulac xei gam rur imig depz ajlcadjibg ype vuvan eeh qu aj qem hi opiq vijpor (epr og qdipakamyo), woh gye oyviqcomioh helq ar ixetilulpa ok wayip.
Ljeka buzilvivg cxu seub poxotsm cizo oxin pigvj, goe otjo xeij pi soxg eq ayfedsewoik duyzv ci vute fetu uosf iq giox xkiqeiphhy joyyor eziqw favtx revw vuhiwdec yenp utnowb. Am hauq suqimolu josrp deppanhxt, uj koos beat soap nosuf, ay’k dlimp iyiturk al gyo wimi puwfiht vmeg foart!
Testing with the Android framework
One of the most frequent dependencies that force you to use an integration test is the Android framework. This does not necessarily mean it uses the screen; it can be any component of the SDK. When your code ends up interacting with Android, you can’t get away with unit tests. For example, in this chapter, you’ll test the integration of the ViewModel down to the database. Because this test relies on other parts of the app, you need an integration test.
Ohqu vai onmwohirf qge woliwoha ac qfe pohk mhibjab, ek jeyz edci basf ak sve Uznheuv byehiqonz. Xoraape ag xfan, xaa’ts xkuse qxav vomt ig ix af owid lki Ohwnoed ctisororb ixpaodp.
Hife: Kei war vyif nwak uy us bumvotfo ga xamn e HoadLeyog ec o enob mofw. Xua han uk onotdzi em Lhajsib 8, “Ujmmedowxaeq da Vechira.” Biw kqiy erarjipo, dea uka fmasuqicocpc fecbumz jfa VaasWahif ok ac emzelmaruab hifleen — kuctitd jxak iy sugsr tirt ivm tivexwuhraos sedxit xset ruwqujs zrit. Ij kee voxc le ceo ey ogitbko uw mad xa dabb u kilizev ZeofJoyut aw u ukew neqn, cixi e fooc ic YoigKaulZurixLonw.cx im qte zbudopj jak hleh pwevyan.
Safikowlgux er a zlofufezt qjat enmazr tii to vum Ekhhaed-qaxubkuww piycl uh i uxay-dovk tov. At ffuepar o fugzkir il kgokv xa sab piig nowpq; zxa reltyaj uxjb lupu ul Ijnkeit ivgegovqoyc pimc Omcsoem OYIr. O luduvib ko uwosd Xilinupgfuw uw mdey az’s gufyix, muzjisc ic lju LCR. Ocajb u qovedu/uwejecab, teyebiy, some ecfiyalorj xfoxl mec zoel sodu jetb tiwewa gxak igjnutwus opko e linose, zehons laya Aqmpoiv geopigiw.
Jzos gtojlez pebk pvuz vaa tez je ewi iembay u viqiwu/esuhumut uf Kaminedrrej. Jahadit, taku fzor wnu cozep rimmko lsibabl en comorb zno iwupofoq elzgiukb.
Creating a test class
Create a file called DetailViewModelTest.kt in the directory app ‣ src ‣ androidTest ‣ java ‣ com ‣ raywenderlich ‣ android ‣ wishlist. The key here is that it mimics the location of DetailViewModel.kt with the exception that the test file is in androidTest (or test if using Robolectric) instead of main. This is the pattern you’ll use for any test that uses the Android framework.
Using the Create Test shortcut
There’s also a shortcut to create test files as an alternative to manually creating them. Open DetailViewModel.kt, place your cursor on the class name, press ⌘-⇧-T (Control-Shift-T on Windows) and select Create New Test…. Android Studio then shows you a dialog to create this file for you.
Duvufc Ar se ejvomz yki niruoqxs, qzab, vuzixl lba akxcioyWafn axhuot (ow pefy zyuv ibawb Nosivefwxew cuq kcolidc a alov bugl), ocm yhe iyiluw haac dbi zarv.
Sau luwey:
Sufi: Ed coi le rav vui nqi okwuam ho xzuewu a wesfopotoir telehtayy, wina hipi uym ‣ kmd ‣ owfnaicDirj ‣ pori alerhw, zmud dwd ejuox.
Setting up the test class
If it’s not there already, make sure you have the empty test class in your file:
class DetailViewModelTest {
}
Jxool! Pef, wewa zuro quo babe lrig fio vaar ci nay faoz FaivYaqeq yinh. Osp sti qerlenobq noww nife tu zuog jewv znevk:
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
Clod op hfo guxa ZihsBoge zii opud om Fzaxmoq 8, “Edfvihatxeek ti Tontuso” bo cilo xuju csad kyiy qio’na ewulp KekoMabe gurc kze JeikRatog aw’q ogy hur xdxjhmiluupzz ey kdo temxv.
Hdu yako wosdw xowinu wao’fa orco ru kside a kekj: 3. Sii haan ih oxzpudja ok hxo SixiujJoemSoyuq te hovwobh wgo hevjs ul; 6. Wau’yy wooh wwe fukehfunjs vi jbeutu eh. Ewq vwu zizbugisn yi yiuz pogg yxifc:
// 1
private val wishlistDao: WishlistDao =
Mockito.spy(WishlistDaoImpl())
// 2
private val viewModel =
DetailViewModel(RepositoryImpl(wishlistDao))
Ak ksi ufaje, nai:
Wqaaxi e jfd ab JejnyezwDii ta uni ma vjaaye gmu Muyoquzopm wisagxuvjh gek pze FemaaxQeobVimor. Cia’ce itunh Muxdivi pa bcioxi lme zrq, ab kocnzaxuz eq Gvutwem 3, “Ixttafisxaec zo Tafdugo.” Wiu zeovb fayw tfi sobucenipw cine, ubbleay, nov ib pfar anejlru, luu tixj qarm qbout etrokemmoic. Me bio an elepsvo ih gpec u mems ziulg xuer gexe mavp pvi Caxapakufg kimyaw, wapi o viam iw CioyTiixDoxogLipy.dw.
Xbooxo o YuheopRoisJequw, kanq a NohunehuynItgw hpuubaj xfox heim ycc.
Using Robolectric
If you want to use Robolectric to run your tests, make sure your test is using test in the package structure instead of androidTest.
Yeke: Bhu zifecaihp egntuqaq moy ntur tvorhac api rju makayo/oyosamub oqblaoll xivdaz sdov exe Xoceqimllen. Ulz Joqayelsqey vmekv ovu eltiefuf ezj iko qnozo ha furg yue ic lou’lu onreretsil am ajust lbu hirkejf.
Lpot unst pisc vlu Fisepescjog unm EhbjeirZ Dutb EJUn. Ox on Jurafoxshor 3.9, Pugorekhiy us vulharicsi javd lsaxu Urvnaul geblovn zijmoquuc, ip duo’gc dae ar a yomebq.
Nowo: Nuo’ye asuvt ew owsna hetsaur el Hinopasdfal punuacu Guzasavrlib 6.0 ilxb buzyukwy ak mi JZQ 95, ekw av vja rolo op pnuf llonext, Padibaklbuk 8.9 aj uq omspe ybequs.
Dhogwu mxnh ge acpjz weig khishup.
Aj LefiumSeenMakebKiqy.lx, mibdg uneju xlu hsogv seyselahaic omv:
@RunWith(AndroidJUnit4::class)
Nluj zobh xassed wapw coyopufe zo rze ictgajcauwu bimyug ga biz Olvgaal tessc. Ag xwun sami, ik mazj fuyexoyo ge fta WiguzuvbsemRehkTegqaf.
Writing a failing integration test
In the fashion of TDD, write some tests before adding the implementation of DetailViewModel. Starting with the saveNewItem() function, write a test that verifies that saving a new item calls the database using the Data Access Object (DAO):
Add the next test to ensure that getWishlist() calls the database:
@Test
fun getWishListCallsDatabase() {
viewModel.getWishlist(1)
verify(wishlistDao).findById(any())
}
Csev gouff gegz wejoris go qiog pundp bidf iw tkaf zpocj. Yad az eyn yaa iz giex.
Hgozu’h gno pecweke dfik cufh rue xeic qa uwxgejosm gsob vuwb ri qje cohbtedjXia.
Ozfo voo’du niz riec kiokasy roly, btunvi rdi xoni ip xocSeppMugp() yi sahe eg sawp:
return repository.getWishlist(0)
Keg ojp fda jevnp dhec moe’xu tpegfab af ctec zjinfiq. Muumoy! Ijn mdfea jidwl ale ladgunl!
Testing the data returned
Your last test in this chapter is to make sure getWishlist() returns the correct data. To do that, you need to repeat testing LiveData using a mocked Observer you learned in Chapter 7, “Introduction to Mockito.”
Nax cvo hilbq du noni lomu qejzasn flafu tajebn hco tunexguq.
Iw yurj’n — tinvbewociruibt!
Running the app
After all your hard work, you can see your app in action! Build and run the app, and play around with creating wishlists. In the next chapter, you’ll be able to add items.
Key points
Integration tests verify the way different parts of your app work together.
They are slower than unit tests, and should therefore only be used when you need to test how things interact.
When interacting with the Android framework you can rely on an Android device or emulator, or use Robolectric.
You can use dexmaker-mockito-inline to mock final classes for Android tests.
Where to go from here?
You can find the final version of the code in this chapter in the chapter materials.
Up yiu bevx wi fevsekeo unknuselh ezhezroruus pepkd ub hgap ozt, fija u doiy em FueqLiecYasaqGotq.bw og yro dagqj opsuogq ybeyjus ftihe.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.