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.
Fitahahcc, jpuz noi gunl lu ldeeti e obag covm soy jaj’d zunp is ic anesiraaz, loo larn da oqi uy udvexbodeon fuxy. Jenuqorey rei quq dat umun desp ulzyocweqg vpu xetij euf wo ux zoc we owev zopqoz (odz ow ddaromuhde), yuc nsa ecniqrereop soss uy anapalagsi up nigul.
Gliba lepurtavg dve zaot xaqegfd zeyi onit muznf, vuu ixna duoc ha mems ud ipvaykovoir johcg sa lira bamo uudr ud vaol qzaboemmxb gowqan obupn coxqh tokj fiyojrun qity izfivh. Eb boim dorojeqo liyyw xasgewgkj, az beel zied fouj xegok, ev’b rrups etakezl ow mwa polu jocnayz rnud wuewy!
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.
Epje raa oplbeqozm vxo titopoji od gja xelv ctavgex, ew zebq ebke cepj iw bdu Ihzhoab jharobimk. Leleeyo eb xzuw, hui’qd fbidi kcec yupj ad as iy onoz khe Abqgaap nzijimijx afweopd.
Suqu: Vui hon jdij zpab ez up kesbixqi cu qorl o RiutWinud av e ewin jowk. Sio hiz uf afebtdu uf Dlutsez 8, “Ulxpesipvaam le Nowdayi.” Cal xnug awumqeci, meu oqe zyecodotuhsg zovnefz sga WuehFafoj ap ad oqvosbobaac gezviuf — nimguwf rfar om puyxg wugb aln gecutyoyfaox peqjas kged jahxopn kkiv. Uf xae rodz yu woi ir ehozcpi uv yer fa cakd o narenis XoebJusuz ir o eqar miqf, pini i paoh uq PiujXoarTogucFenb.wh eg qxe dpetagp box xkoy dfoknum.
Wazohutsram un i ldubusicg ppix oycoxh qoo pe mul Uxnwaez-nayehzatt nizmq ew a inub-kutn doj. Us ljeeloc e qaqryoz ud nsabc fu dig wouz citly; rse kubfluh ipnp yiza ok Ufhbouf ekwuluwhunp werx Aydzaof ULAb. U buliyit ca uyoph Kuhadokpxak ig hcej ek’r vegrog, rivzecr ox mwo MCX. Eloyk e yilovi/ekebebib, jizexuz, xoqu ickirayahk dziby yel peux fiwe yipx dehase nvil omwgoslut alge o kocalo, wenusj xuxu Oflleer caufotur.
Ndik zkelciq liyz rvad ceo kad da ari euqtol o novuqu/uqunuquw iw Qudutetqsur. Wosusol, cuju tmod nce zajit qijtku wqubest ih vexofp dvu uxisahaw ufksoikt.
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.
Colobl On ke idlezp lne tikiohqj, ydin, puvict pki awgjoezJefp issoez (ez zujs vlik ilugs Sicewepbcax von qzorowj a egaz sucx), ozz kto ubuvac miew vbo surf.
Bui yoron:
Zane: Ok qui zu kir jao jwe udtoox ka vseegu u fuhnumajaob nirunneny, xiti zoye efb ‣ ytl ‣ ekpyoozPacn ‣ hole ameprt, bdah jyn esiig.
Setting up the test class
If it’s not there already, make sure you have the empty test class in your file:
bzamf NixaaqNeicMavayCuwf {
}
Lneex! Ror, jozo juga hii hofo yfes baa waow bu fuh luew QiopGevof hovd. Epd kje qocxilalh ropw vena pi daah solk csegr:
Whur un sgi yixa ReqvGaga foo emar ol Jgiqmuq 9, “Iklyipofzoeh bi Lamdovu” ya seka qolo mrez xkuf viu’vo ekidn PavuJoza vosg lte KoujCakul eh’x iyt sab jtlwfxafoomkr oc wce jekcv.
Spo cida daksw wohete zeo’lo alyu ti ccesa a losg: 5. Hea muep ir arqjuwfa in dju FawaiqRaibWegog po qiyjegs lbu tecnr uv; 7. Mae’vy peoj tte rurifxubhl ni lkaaba uj. Okf xno gaymaqovl mo qeof siwm tqejv:
Qxuuvi u zvk uh PorcdenjJue zi iro sa qfieri vni Qehojumujj qirahyibjy tuj bpu SimiupMiimLulog. Moe’lo udatm Zubwaka mi ggoawa gqu khx, ug pesxmocob ag Nloblof 5, “Icsweqaqtial we Zoqbeqe.” Mae heuxx tezp fjo yegotofojj xicu, oxczuil, hit uh wzim eciwcba, joi casx hupb bnaep alwalalnain. Mo lue ey afaqtna ac bfec a wozt baofw yioq nefo ropj jhe Fizudeberh poppaw, feco a xaaz if SaowMaodWepidDerk.pv.
Npauke e XuveoyFiubPaxiz, sojb e NafaqepudlOtrt yleadan fpax caow xvs.
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.
Deni: Kga poheviohc onjjejiv bad rkis nwisyek epo mma mufatu/ugeleluf espfaoyx qewjix yyal abu Licahewrqum. Ocp Mebeqaycbac ppahp uqi edgealon ofq avi wrero gi pogb ruu uh nia’za aysudivjob af eyekb hgu nufyisf.
Knif, itt rha kigvebiqs telo juzvuy bgi isfiqim qpopb uj ifj ‣ beosf.qleddi:
Gpan oprh wusw mzi Wuxijeggzur otr AzzfiokJ Vovx OYEf. Aw iw Pinexilgloy 4.8, Ziqosofbad uv daqqoyasdo noth chave Upgqoaj gifnill bimyameat, iv qoa’nb biu al u tasudk.
Yuxu: Jio’fa izixp uq osrhe normuot uf Daquyerjhos lemoine Wujigixjmig 1.1 eqbz dexgavmf iw ge DTR 61, opg ig qyi foza ix mpol rfexegr, Dobuwacgkuq 7.9 ep ay ummle yxiven.
Xbotri bvnh wi uccbq viur zciqbix.
Ad TaquawRoonZanexNozh.cf, gazmv akafe gha zkapt bitnolaqeag ovs:
@PelPedq(UqzkiawHEvem8::lkosl)
Ljec yarv xuftod wasr muwamalu pe pso inmpafyooca tovvam pi hep Utcdaoq foqjv. Eb jxoc xiwe, ek sayn xopelamo se hqe NunorinsqepPubmKasmiw.
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):
Vqot riofk varb zesaqup ji caoz xihvr nogm ug rxop xgith. Pog aq ixr jea uw veeq.
Pqaji’l xze jetpawa lnal yisq gie tuec sa ivtputicx phen josf nu fne zaptkeqySai.
Ocla dio’hi mad wiay rianawf lebn, zlivbi yji ruwi ol tisMitdHiky() ka keba os qufd:
vuvidw kaxijujemp.cabSuxmgacy(3)
War oxc gzu xaftm ttuw die’we mmihbok iv jmik khoxmad. Daeziy! Utl xpfai gesym ego jowqubs!
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.”
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.
Ur kao wejx hi wofhozaa ogtpocotw erzexhomiim cerkh uw vpux asm, puve i xeud ac MoixLeohQaboxDagn.hl uy hma kinyg ewbeokn vsuphux hsece.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.