• Ei tuloksia

Android-sovellusten testaaminen

N/A
N/A
Info
Lataa
Protected

Academic year: 2022

Jaa "Android-sovellusten testaaminen"

Copied!
81
0
0

Kokoteksti

(1)

Juho Niemist¨o

Helsinki 15.1.2014 Pro gradu -tutkielma HELSINGIN YLIOPISTO Tietojenk¨asittelytieteen laitos

(2)

Matemaattis-luonnontieteellinen Tietojenk¨asittelytieteen laitos Juho Niemist¨o

Android-sovellusten testaaminen Tietojenk¨asittelytiede

Pro gradu -tutkielma 15.1.2014 67 sivua + 10 liitesivua

Android, testaus, yksikk¨otestaus, toiminnallinen testaus, mobiilisovellukset Kumpulan tiedekirjasto, sarjanumero C-

Googlen kehitt¨am¨a Android on noussut viime vuosina markkinaosuudeltaan suurimmaksi mobii- lilaitteiden k¨aytt¨oj¨arjestelm¨aksi. Kuka tahansa voi kehitt¨a Androidille sovelluksia, joiden kehit- amiseen tarvittavat v¨alineet ovat ilmaiseksi saatavilla. Erilaisia sovelluksia onkin kehitetty jo yli miljoona.

Sovellusten laatu on erityisen t¨arke¨a Android-alustalla, jossa kilpailua on runsaasti ja sovellusten hinta niin alhainen, ettei se muodosta estett¨a sovelluksen vaihtamiselle toiseen. Sovelluskauppa on my¨os aina saatavilla suoraan laitteesta. T¨am¨a asettaa sovellusten testaamisellekin haasteita.

Toisaalta sovellukset tulisi saada nopeasti sovelluskauppaan, mutta my¨os sovellusten laadun pit¨aisi olla hyv¨a. Testity¨okalujen pit¨aisi siis olla helppok¨aytt¨oisi¨a, ja tehokkaita. Androidille onkin kehitetty lukuisia testausty¨okaluja Googlen omien ty¨okalujen lis¨aksi.

ass¨a tutkielmassa tutustutaan Android-sovellusten rakenteeseen, niiden testaamiseen ja Android- alustalla toimiviin automaattisen testauksen ty¨okaluihin. Erityisesti keskityt¨an yksikk¨o- ja toimin- nallisen testauksen ty¨okaluihin. Yksikk¨otestity¨okaluista vertaillaan Androidin omaa yksikk¨otestike- hyst¨a Robolectriciin. Toiminnallisen testauksen ty¨okaluista vertaillaan Uiautomatoria, Robotiumia ja Troydia.

ACM Computing Classification System (CCS):

-Software and its engineeringSoftware testing and debugging -Software and its engineeringOperating systems

Tekij¨a — F¨orfattare — Author

Ty¨on nimi — Arbetets titel — Title

Oppiaine — L¨aro¨amne — Subject

Ty¨on laji — Arbetets art — Level Aika — Datum — Month and year Sivum¨ar¨a — Sidoantal — Number of pages

Tiivistelm¨a — Referat — Abstract

Avainsanat — Nyckelord — Keywords

ailytyspaikka — F¨orvaringsst¨alle — Where deposited

Muita tietoja — ¨ovriga uppgifter — Additional information

(3)

Sis¨ alt¨ o

1 Johdanto 1

2 Android-sovellusten rakenne ja kehityssykli 3

2.1 Historia . . . 3

2.2 Android-sovellusten kehitt¨aminen . . . 3

2.3 Android-sovellusten rakenne . . . 4

2.4 Aktiviteetit . . . 7

2.5 Palvelut . . . 10

2.6 Sis¨all¨ontarjoajat . . . 11

2.7 Aikeet . . . 12

2.8 Android manifest . . . 13

2.9 Android-sovelluksen julkaiseminen . . . 14

3 Ohjelmistojen testaaminen ja mobiilisovellusten testaamisen eri- tyispiirteit¨a 15 3.1 Testaamisen perusk¨asitteit¨a . . . 15

3.2 Testaaminen osana ohjelmistotuotantoprosessia . . . 16

3.3 Mobiilisovellusten testaamisen erityispiirteit¨a . . . 18

3.4 Testity¨okalujen arviointikriteereist¨a . . . 19

4 Android-sovellusten testaaminen ja Androidin mukana tulevat tes- tity¨okalut 21 4.1 Android-testien ajoymp¨arist¨o . . . 21

4.2 Komponenttikohtaiset yksikk¨otestiluokat . . . 22

4.3 MonkeyRunner . . . 23

4.4 Uiautomator ja Uiautomatorviewer . . . 24

4.5 Monkey . . . 25

5 Yksikk¨otestity¨okalujen vertailua 27

(4)

5.1 Robolectric . . . 28

5.2 Aiempaa tutkimusta . . . 28

5.3 Testiprojekti . . . 29

5.4 Robolectricin asentaminen . . . 30

5.5 Aktiviteetin elinkaarimetodien yksikk¨otestaus . . . 31

5.6 Toiminta j¨aljittelij¨akehysten kanssa . . . 37

5.7 Testisyklin nopeus . . . 40

5.8 Yksikk¨otestauksen haasteita . . . 41

5.9 Analyysi . . . 43

6 Toiminnallisen testauksen ty¨okalujen vertailua 45 6.1 Robotium . . . 46

6.2 Troyd . . . 46

6.3 Aiempaa tutkimusta . . . 47

6.4 Testiprojekti . . . 48

6.5 Testitapaus . . . 50

6.6 Asennukset . . . 51

6.7 Robotium-testit . . . 53

6.8 Troyd-testit . . . 55

6.9 Uiautomator-testit . . . 56

6.10 Testien suoritusnopeudet . . . 58

6.11 Analyysi . . . 59

7 Yhteenveto 61

L¨ahteet 64

Liitteet

1 Yksikk¨otesteiss¨a testatun sovelluksen l¨ahdekoodi

(5)

Googlen kehitt¨am¨a Android on noussut viime vuosina markkinaosuudeltaan suurim- maksi mobiililaitteiden k¨aytt¨oj¨arjestelm¨aksi. Kuka tahansa voi kehitt¨a¨a Androidille sovelluksia, ja niiden kehitt¨amiseen tarvittavat v¨alineet ovat ilmaiseksi saatavilla.

Erilaisia sovelluksia onkin kehitetty jo yli miljoona.

Mobiilisovellusten kehitt¨amiseen liittyy monia haasteita. Niit¨a ovat muun muassa rajalliset laitteistoresurssit, k¨aytett¨avyys pienell¨a n¨ayt¨oll¨a sek¨a yksityisyyteen ja tietoturvaan liittyv¨at kysymykset. Androidilla on esimerkiksi Applen iOS-alustaan verrattuna omana haasteenaan laitteiden valtava kirjo. Android-laitteita valmista- vat kymmenet eri valmistajat, ja ne vaihtelevat kameroista tablettien kautta di- gibokseihin. Laitteissa on hyvin eritehoisia prosessoreita. My¨os lis¨alaitteita, kuten gps-vastaanottimia tai kiihtyvyysantureita, on vaihtelevasti.

Sovellusten laatu on erityisen t¨arke¨a¨a Android-alustalla, jossa kilpailua on runsaasti ja sovellusten hinta useimmiten niin alhainen, ettei se muodosta estett¨a sovelluk- sen vaihtamiselle toiseen. Sovelluskauppa on my¨os aina saatavilla suoraan laittees- ta. N¨am¨a kilpailutekij¨at asettavat sovellusten testaamisellekin haasteita. Toisaalta sovellukset tulisi saada nopeasti sovelluskauppaan, mutta my¨os sovellusten laadun pit¨aisi olla hyv¨a.

Sovellusten laatua voidaan parantaa automaattisilla testausty¨okaluilla. Testien au- tomatisointi tarkoittaa, ett¨a kerran kirjoitettua testisarjaa voidaan ajaa helposti uu- delleen. T¨am¨a mahdollistaa esimerkiksi testivetoisen kehityksen yksikk¨otestity¨oka- lujen avulla ja regressiotestauksen jatkuvan integraation ty¨okaluissa. Jotta testaus ei hidastaisi liikaa sovelluksen ohjelmointia, testausty¨okalujen pit¨aisi olla helppok¨ayt- t¨oisi¨a ja tehokkaita. Androidille onkin kehitetty monia testausty¨okaluja Googlen omien ty¨okalujen lis¨aksi.

Tutkimuksen tavoitteena on perehty¨a Android-sovellusten rakenteeseen, niiden tes- taamiseen ja Android-alustalla toimiviin automaattisen testauksen ty¨okaluihin. Tu- tustun kirjallisuudessa esiteltyihin sek¨a Androidin kehitysty¨okalujen mukana tule- viin testausty¨okaluihin. Kirjallisuuskatsauksen lis¨aksi vertailen ty¨okaluja testaamal- la niiden avulla esimerkkisovellusta ja analysoin testien perusteella niiden puutteita ja vahvuuksia.

K¨asittelen t¨ass¨a tutkielmassa vain Androidille Javalla kehitettyj¨a natiivisovelluksia.

Androidille voi kehitt¨a¨a sovelluksia my¨os muun muassa html5:ll¨a ja erilaisilla ty¨o- kaluilla, jotka generoivat automaattisesti natiivikoodia useille mobiilialustoille. Osa

(6)

testausty¨okaluista mahdollistaa toki my¨os t¨allaisten sovellusten testaamisen. Keski- tyn vain automaattisiin testausty¨okaluihin, joten esimerkiksi manuaaliseen k¨aytet- t¨avyystestaukseen liittyv¨at prosessit ja ty¨okalut on rajattu t¨am¨an ty¨on ulkopuolelle.

Keskityn yksikk¨o- ja toiminnallisiin testity¨okaluihin. Yksikk¨otestity¨okaluja k¨aytt¨a- v¨at useimmiten sovelluksen ohjelmoijat itse sovelluksen koodausvaiheessa. Yleist¨a on my¨os yksikk¨otestien kirjoittaminen jo ennen vastaavan ohjelmakoodin kirjoitta- mista. Toiminnallisissa testeiss¨a testataan sovellusta hieman korkeammalta tasolta ja pyrit¨a¨an varmistamaan haluttu toiminnallisuus kokonaisuudessaan sovelluksessa.

N¨am¨a ty¨okalut olen valinnut huomion kohteeksi, koska toiminnallinen ja yksikk¨o- testaus ovat yleisimm¨at testauksen muodot mobiilisovelluksia kehitett¨aess¨a ja ty¨o- kaluvalikoima on my¨os monipuolisin. Toiminnallinen ja yksikk¨otestaus ovat my¨os useimmiten automatisoituja testaamisen vaiheita.

Toisessa luvussa esittelen Androidin kehitysty¨okaluja sek¨a arkkitehtuuria sovellusten kehitt¨aj¨an n¨ak¨okulmasta. Luvussa tutustutaan Androidin t¨arkeimpiin komponent- teihin: aktiviteetteihin, palveluihin ja sis¨all¨ontarjoajiin sek¨a komponenttien v¨aliseen kommunikointiin aikeiden avulla. Lis¨aksi esittelen Android manifestin ja Android- sovellusten julkaisun.

Kolmannessa luvussa k¨asitell¨a¨an ohjelmistojen testaamisen perusasioita, testausta osana ohjelmistotuotantoprosessia sek¨a mobiilisovellusten testaamisen erityispiirtei- t¨a. Lis¨aksi pohditaan testausty¨okalujen arviointia ja laatukriteerej¨a. Nelj¨anness¨a lu- vussa k¨asitell¨a¨an Android-sovellusten testauksen perusteita sek¨a esitell¨a¨an Androi- din kehitysty¨okalupaketin mukana tulevia testity¨okaluja, kuten Monkeyrunner, Mon- key ja Uiautomator.

Viidenness¨a luvussa syvennyt¨a¨an yksikk¨otestity¨okaluihin. Vertailen Androidin yk- sikk¨otestikehyst¨a avoimen l¨ahdekoodin Robolectriciin, joka pyrkii tarjoamaan Androidin oman yksikk¨otestikehyksen ominaisuudet Javan omassa virtuaalikonees- sa, jotta testien ajaminen olisi nopeampaa. Selvit¨an luvussa my¨os yksikk¨otestike- hysten yhteensopivuutta j¨aljittelij¨akehysten kanssa.

Kuudennessa luvussa k¨asitell¨a¨an toiminnallisen testauksen ty¨okaluja. Vertailen Androidin kehitysty¨okalujen mukana tulevan Uiautomator-ty¨okalun lis¨aksi Robo- tium ja Troyd -testity¨okaluja. Kukin n¨aist¨a ty¨okaluista tarjoaa hieman erilaisen l¨a- hestymistavan ja abstraktiotason toiminnallisten testien kirjoittamiseen. Viimeisess¨a luvussa on yhteenveto.

(7)

2 Android-sovellusten rakenne ja kehityssykli

T¨ass¨a luvussa esitell¨a¨an Androidin historiaa, kehitysty¨okaluja ja sovelluksen julkai- sua sek¨a Android-sovellusten arkkitehtuuria ja p¨a¨akomponentit.

2.1 Historia

Androidin kehityksen aloitti Android Inc. -niminen yritys vuonna 2003. Google osti sen vuonna 2005. Kaksi vuotta my¨ohemmin, marraskuussa 2007 Androidin ensim- m¨ainen versio julkaistiin ja samalla kerrottiin, ett¨a sen kehityksest¨a vastaa Open Handset Alliance, johon kuului Googlen lis¨aksi puhelinvalmistajia, kuten HTC ja Samsung, operaattoreita, kuten Sprint Nextel ja T-Mobile sek¨a komponenttivalmis- tajia, kuten Qualcomm ja Texas Instruments.

Ensimm¨ainen Androidille julkaistu kaupallinen laite oli HTC Dream -¨alypuhelin, joka julkaistiin lokakuussa 2008. Loppuvuodesta 2010 Android nousi ¨alypuhelinten markkinajohtajaksi. Syksyll¨a 2012 Androidilla oli jo tutkimuksesta riippuen 50-70 prosentin markkinaosuus ja laitevalikoima on kasvanut ¨alypuhelimista muunmuassa tablet-tietokoneisiin, digibokseihin ja kameroihin [wik].

2.2 Android-sovellusten kehitt¨ aminen

Android-sovelluksia kehitet¨a¨an p¨a¨as¨a¨ant¨oisesti Java-ohjelmointikielell¨a. Yleisin k¨ay- tetty ohjelmointiymp¨arist¨o on Eclipse [ecl], johon Google tarjoaa liit¨ann¨aisen¨a oh- jelmistokehitysty¨okalut Android-sovellusten kehitt¨amiseen. Yksi Android-sovellus on Eclipsess¨a oma projektinsa, josta Eclipse osaa k¨a¨ant¨a¨a Android-laajennoksen avul- la asennusvalmiita sovelluspaketteja. Android-projekti on jaettu kansioihin, joista t¨arkeimm¨at ovat src-kansio, josta l¨oytyy sovelluksen l¨ahdekoodi, res-kansio, johon lis¨at¨a¨an sovelluksen ulkoasun m¨a¨arittelyyn, kuvatiedostoihin ja lokalisaatioon liit- tyvi¨a tietoja. Gen-kansiossa on Android-laajennoksen automaattisesti luomia Java- luokkia, joiden avulla res-kansion tiedostot liitet¨a¨an osaksi Java-sovellusta.

Itse sovelluksen ohjelmointi on p¨a¨aosin kuin tekisi mit¨a tahansa Java-ohjelmaa.

Eclipsen Android-laajennoksen avulla Eclipse osaa neuvoa Androidin kirjastoluok- kien k¨ayt¨oss¨a ja itse sovelluskoodi on tavanomaista Javaa. Sovellusta voi ajaa Eclip- sest¨a k¨asin joko Android-emulaattorissa tai tietokoneeseen usb-kaapelilla liitetyss¨a Android-laitteessa. Emulaattorin hallinta onnistuu suoraan Eclipsest¨a ja sovellusta

(8)

ajaessa Eclipse kysyy, halutaanko sovellus ajaa emulaattorissa vai liitetyss¨a laittees- sa. T¨am¨an j¨alkeen sovellusta voi testata manuaalisesti. Sovelluksesta on mahdollista saada debug- ja lokitietoa Eclipseen Android-laajennoksen avulla.

Android-sovellusten testausta varten tehd¨a¨an Eclipsess¨a oma testiprojekti, johon testit kirjoitetaan. Testiprojekti k¨aytt¨a¨a varsinaista sovellusprojektia testien koh- teena. Androidin Java-pohjaiset testity¨okalut ovat JUnit-laajennoksia, joten testej¨a kirjoitetaan kuin JUnit-testej¨a. Testit voi ajaa suoraan Eclipsest¨a joko emulaatto- rissa tai Android-laitteessa. Jokaisella testien ajokerralla sovellus k¨a¨annet¨a¨an, pake- toidaan ja asennetaan kohdelaitteseen, jonka j¨alkeen testit ajetaan. Testien tulokset n¨akyv¨at Eclipsess¨a: jos testi ei mene l¨api, syy t¨ah¨an n¨akyy Eclipsess¨a.

Google julkaisee Androidille ilmaista ohjelmistokehitysty¨okalua (Android SDK), joka k¨a¨ant¨a¨a sovelluksen ja pakkaa sen kuvien ja muiden resurssien kanssa apk-tiedostoksi (Android Application Package). Apk-tiedosto sis¨alt¨a¨a kaikki yhden sovelluksen asen- tamiseen tarvittavat tiedot. Android-sovellusten kehitt¨amiseen tarvitsee k¨ayt¨ann¨os- s¨a Javan kehitysty¨okaluista (SDK) version 5 tai uudemman, Androidin SDK:n, Eclipsen sek¨a Android-laajennoksen (Android Development Tools, ADT) Eclipselle [ZG11, 25].

Androidin SDK:n mukana tulee minimoitu versio Androidin j¨arjestelm¨akirjastoista, joista ovat mukana kirjastoluokkien rajapinnat, joiden avulla Eclipse osaa opastaa rajapintojen k¨ayt¨oss¨a. Rajapinnan takana ei ole kuitenkaan oikeaa toteutusta, jo- ten esimerkiksi yksikk¨otestit, jotka menev¨at kirjastoluokkiin asti, eiv¨at toimi Eclip- sest¨a Javalla ajettaessa. Androidin Eclipse-laajennos toimii siltana Android SDK:n ja Eclipsen v¨alill¨a mahdollistaen SDK:n tarjoamien ominaisuuksien hy¨odynt¨amisen suoraan Eclipsest¨a k¨asin.

SDK:n mukana tulevaa Android-emulaattoria voi ajaa Androidin eri j¨arjestelm¨aver- sioilla ja laitteistoprofiileilla, jotta on mahdollista testata sovelluksen toimivuutta erilaisissa Android-ymp¨arist¨oiss¨a. Emulaattori kykenee my¨os jossain m¨a¨arin simu- loimaan lis¨alaitteiden, kuten kiihtyvyysanturin, toimintaa. Suurin puute emulaatto- rissa on sen heikko suoritusnopeus [ZG11, 25-50].

2.3 Android-sovellusten rakenne

Android on rakennettu Linuxin ytimen version 2.6 p¨a¨alle, ja koko Androidin j¨ar- jestelm¨akoodi on avointa, mik¨a tarkoittaa, ett¨a mik¨a tahansa valmistaja voi tehd¨a Androidin pohjalta oman mobiilik¨aytt¨oj¨arjestelm¨ans¨a. Esimerkiksi Amazon on jul-

(9)

kaissut Kindle Fire -tabletteja oman Android-johdannaisen k¨aytt¨oj¨arjestelm¨an p¨a¨al- le [kin].

Jokainen sovellus on k¨aytt¨aj¨an¨a j¨arjestelm¨ass¨a. Sovellusten oikeudet on rajattu si- ten, ett¨a ne p¨a¨asev¨at k¨asiksi vain kyseiseen sovellukseen liittyviin resursseihin. So- velluksen ollessa k¨aynniss¨a se py¨orii omana prosessina Linux-prosessien tavoin, jota Android-k¨aytt¨oj¨arjestelm¨a hallitsee. Androidin turvallisuusratkaisu noudattaa v¨a- himm¨an mahdollisen tiedon periaatetta: sovelluksella on vain ne oikeudet, joita se v¨ahint¨a¨an tarvitsee toimintaansa. Kaikkia ylim¨a¨ar¨aisi¨a oikeuksia varten t¨aytyy erik- seen pyyt¨a¨a lupa.

Kuva 1: Androidin t¨arkeimpien komponenttien luokkahierarkia

Android-sovellukset koostuvat nelj¨ast¨a komponenttityypist¨a: aktiviteeteista (acti- vities), palveluista (services), sis¨all¨ontarjoajista (content providers) sek¨a l¨ahetys- ten vastaanottajista (broadcast receivers). Komponenttien v¨alinen kommunikointi on p¨a¨aosin tapahtumapohjaista; eri komponentit eiv¨at keskustele suoraan keske- n¨a¨an, vaan kaikki siirtym¨at komponenttien v¨alill¨a tapahtuvat k¨aytt¨oj¨arjestelm¨an v¨a- litt¨amien tapahtumaviestien perusteella. T¨am¨an vaikutuksesta Android-sovellukset voivat helposti k¨aytt¨a¨a toiminnassaan j¨arjestelm¨an ja toisten sovellusten tarjoamia komponentteja.

Kuvassa 1 on esitelty Androidin peruskomponenttien muodostama luokkahierarkia.

Vain aktiviteeteilla ja palveluilla on yhteinen yliluokka Context, l¨ahetysten vastaa- nottajat ja sis¨all¨ontarjoajajat periv¨at vain Javan Object-luokan. Kuvaa on yksinker-

(10)

taistettu siten, ett¨a Contextin ja Activityn ja Servicen v¨alill¨a olevia Wrapper-luokkia on j¨atetty kuvaamatta perint¨ahierarkiassa. Context-luokka tarjoaa aktiviteettien ja palveluiden k¨aytt¨o¨on sovelluksen globaaliin tilaan liittyvi¨a tietoja.

Aktiviteetti kuvaa yht¨a sovelluksen k¨aytt¨oliittym¨an kerrallaan muodostavaa n¨aky- m¨a¨a. Sovelluksen k¨aytt¨oliittym¨a koostuu useista aktiviteeteista, jotka muodostavat yhten¨aisen sovelluksen, mutta jokainen aktiviteetti on toisistaan riippumaton. Eri sovellukset voivat my¨os k¨aynnist¨a¨a toistensa aktiviteetteja, mik¨ali vastaanottava so- vellus sen sallii. Esimerkiksi kamera-sovellus voi k¨aynnist¨a¨a s¨ahk¨oposti-sovelluksen s¨ahk¨opostinkirjoitus-aktiviteetin, jos ottamansa kuvan haluaa jakaa s¨ahk¨opostilla.

Aktiviteetit ovat Androidissa Activity-luokan aliluokkia.

Palvelut ovat taustaprosesseja, jotka suorittavat pitk¨akestoisia operaatioita, kuten tiedon lataamista verkosta tai musiikin soittamista taustalla samalla, kun k¨aytt¨aj¨a k¨aytt¨a¨a toista sovellusta. Palvelut eiv¨at tarjoa k¨aytt¨oliittym¨a¨a ja toiset komponentit, kuten aktiviteetit, voivat k¨aynnist¨a¨a niit¨a. Palvelut ovat Service-luokan aliluokkia.

Sis¨all¨ontarjoajat vastaavat sovelluksen tarvitseman tiedon lukemisesta ja kirjoitta- misesta pitk¨akestoiseen muistiin. Tallennuspaikkana voi olla laitteen tiedostoj¨arjes- telm¨a, SQLite-tietokanta, verkko tai ylip¨a¨ans¨a mik¨a tahansa kohde, johon sovelluk- sella on luku- tai kirjoitusoikeudet. Sovellukset voivat k¨aytt¨a¨a toistensa sis¨all¨ontar- joajia, mik¨ali sovellus julkaisee ne muiden sovellusten k¨aytt¨o¨on. Sis¨all¨ontarjoajat ovat ContentProvider-luokan aliluokkia.

L¨ahetysten vastaanottajat reagoivat j¨arjestelm¨anlaajuisiin viesteihin ja tapahtumiin.

T¨allaisia ovat esimerkiksi ilmoitus, ett¨a akku on lopussa tai ett¨a k¨aytt¨aj¨a on sulkenut tai avannut n¨ayt¨on. Ne voivat my¨os l¨ahett¨a¨a j¨arjestelm¨anlaajuisia tapahtumavies- tej¨a muille sovelluksille. L¨ahetysten vastaanottajat ovat BroadcastReceiver-luokan aliluokkia ja tapahtumat Intent-luokan aliluokkia.

Android-sovellukset k¨aytt¨av¨at usein hyv¨akseen toisten sovellusten komponentteja.

Sovellukset eiv¨at pysty suoraan kutsumaan toisiaan. Halutessaan hy¨odynt¨a¨a tois- ten sovellusten ominaisuuksia sovellus luo uuden aikeen, jonka j¨arjestelm¨a v¨alitt¨a¨a tiettyjen s¨a¨ant¨ojen perusteella sopivalle vastaanottajalle (katso luku 2.7).

Android-sovelluksilla ei ole yksitt¨aist¨a main-metodia, joka k¨aynnist¨aisi ohjelman, kuten usein sovelluksissa on tapana. Sovellus voi sen sijaan k¨aynnisty¨a vastaanot- tamansa aikeen johdosta monen eri komponentin kautta. Lis¨aksi sovellus saatetaan joutua k¨aynnist¨am¨a¨an ja sulkemaan useita kertoja esimerkiksi k¨aytt¨aj¨an vaihtaessa puhelimen suuntausta tai vastaanotettaessa puhelua, joten sovelluksen pit¨a¨a pys-

(11)

ty¨a tehokkaasti palautumaan keskeytyneeseen tilaansa. Sovelluksella on siis lukuisia mahdollisia k¨aynnistymis- ja sulkeutumispolkuja. T¨am¨an takia ohjelmakomponent- tien elinkaaren hallinta on t¨arke¨a osa sovelluksen rakentamista.

Android-sovelluksissa pyrit¨a¨an erottamaan sovelluksen Java-toteutus ja lokalisoin- ti mahdollisimman hyvin toisistaan. T¨am¨a tapahtuu resurssien (resource) avulla.

Androidin resurssi-luokka tarjoaa sovellukselle p¨a¨asyn lokalisoituihin resursseihin siten, ettei Java-koodissa tarvitse ottaa kantaa lokalisaatioon. T¨arkein lokalisoi- tu resurssi on sovelluksen tekstit, mutta my¨os grafiikan ja layoutin voi m¨a¨aritell¨a kielen tai laitteen n¨ayt¨on koon perusteella. Itse resurssitekstit m¨a¨aritell¨a¨an xml- muotoisessa tiedostossa.

Android-sovelluksilla on xml-muotoinen Manifest-tiedosto, jossa m¨a¨aritell¨a¨an sovel- luksen komponentit, niiden n¨akyvyys ja mink¨alaisia tapahtumia ne osaavat hallita.

Manifestissa m¨a¨aritell¨a¨an my¨os mit¨a rajoitteita sovellus asettaa k¨aytett¨aviss¨a ole- valle Android-versiolle, puhelimen ominaisuuksille, kuten lis¨alaitteiden saatavuudel- le ja n¨aytt¨oresoluutiolle, ja mit¨a oikeuksia sovellus vaatii toimiakseen. N¨ain voidaan varmistaa, ett¨a sovellusta ei asenneta laitteelle, jossa ei ole sovelluksen v¨altt¨am¨att¨a tarvitsemia ominaisuuksia [andb].

2.4 Aktiviteetit

Aktiviteetti kuvaa yht¨a sovelluksen k¨aytt¨oliittym¨an n¨akym¨a¨a. L¨ahes aina aktiviteet- ti on koko n¨ayt¨on kokoinen - eli kaikki, mit¨a puhelimen ruudulla n¨akyy yl¨areunan status-palkkia lukuunottamatta on samaa aktiviteettia - mutta ne voivat olla my¨os pienempi¨a tai leijua osittain toisen aktiviteetin p¨a¨all¨a. Kuitenkin vain yksi aktivi- teetti kerrallaan voi olla aktiivinen - eli reagoida k¨aytt¨aj¨an sy¨otteisiin. Yksi sovelluk- sen aktiviteeteist¨a on yleens¨a p¨a¨aaktiviteetti, joka k¨aynnistyy silloin, kun k¨aytt¨aj¨a avaa sovelluksen.

Aktiviteettien elinkaaren hallinta on Android-sovelluksen kriittisimpi¨a osia, koska j¨arjestelm¨an resurssit ovat yleens¨a hyvin rajalliset ja Android-laitteiden k¨aytt¨o¨on liittyy tyypillisesti tihe¨a vaihtelu eri sovellusten v¨alill¨a. T¨all¨oin on t¨arke¨a¨a, ett¨a so- vellus luovuttaa varaamansa resurssit muiden sovellusten k¨aytt¨o¨on, kun sovellus vaihtuu, ja vastaavasti osaa palautua takaisin pys¨aytett¨aess¨a olleeseen tilaan k¨ayt- t¨aj¨an palatessa sovellukseen. N¨aiden vaihdosten pit¨aisi lis¨aksi tapahtua mahdolli- simman nopeasti, jotta j¨arjestelm¨an toiminta olisi k¨aytt¨aj¨an n¨ak¨okulmasta sulavaa sovellusten tilojen vaihtamisen yhteydess¨a.

(12)

Kuva 2: Aktiviteetin elinkaari [andb]

Aktiviteetilla voi olla pitk¨akestoisemmin kolme eri tilaa. Aktiviteetti on aktiivises- sa tilassa (resumed) silloin, kun se on n¨ayt¨on etualalla ja k¨aytt¨aj¨a k¨aytt¨a¨a juuri sit¨a aktiviteettia. Keskeytetyss¨a (paused) tilassa aktiviteetti on, kun se on osittain n¨akyviss¨a, mutta jokin toinen aktiviteetti on aktiivisena sen p¨a¨all¨a. Keskeytetyt ak- tiviteetit ja niiden tilat pysyv¨at muistissa, joskin jos laitteen muisti on lopussa, j¨ar- jestelm¨a saattaa tuhota sen. Aktiviteetti on pys¨aytetty (stopped) silloin, kun jokin toinen aktiviteetti peitt¨a¨a sen kokonaan n¨akyvist¨a. T¨allainenkin aktiviteetti s¨ailyy muistissa, jos laitteen resurssit ovat riitt¨av¨at, mutta j¨arjestelm¨a voi tuhota sen koska vain, jos resursseja tarvitaan muiden aktiviteettien k¨aytt¨o¨on.

Aktiviteetin siirtyminen eri tilojen v¨alill¨a tapahtuu j¨arjestelm¨an kutsuessa aktivi- teetin takaisinkutsumetodeita. Mahdolliset tilasiirtym¨apolut n¨akyv¨at kuvassa 2.

(13)

Aktiviteetin koko elinkaari tapahtuu onCreate()- ja onDestroy()-kutsujen v¨alill¨a. Ak- tiviteetin tulisi tehd¨a kaikki kerran suoritettavat tilanalustusteht¨av¨at kutsuttaessa onCreate()-metodia, kuten ulkoasun m¨a¨arittely tai koko aktiviteetin elinkaaren ajan tarvittavan tiedonsiirtos¨aikeen avaus. Vastaavasti onDestroy()-kutsussa aktiviteetin tulisi vapauttaa kaikki loputkin aktiviteetin varaamat resurssit.

Aktiviteetin k¨aytt¨aj¨alle n¨akyv¨a elinkaari on onStart()- ja onStop()-kutsujen v¨alil- l¨a. onStart()-metodia kutsutaan, kun aktiviteetti tulee n¨akyv¨aksi k¨aytt¨aj¨alle, ja onStop()-metodia kutsutaan, kun jokin toinen aktiviteetti on peitt¨anyt kyseisen ak- tiviteetin kokonaan. N¨akyv¨an elinkaaren aikana tulisi yll¨apit¨a¨a niit¨a resursseja, joita tarvitaan k¨aytt¨aj¨an kanssa kommunikointiin sek¨a sellaisia, jotka saattavat muuten vaikuttaa k¨aytt¨aj¨alle n¨akyv¨a¨an k¨ayt¨oliittym¨a¨an. Esimerkiksi l¨ahetystenvastaanot- tajaa on hyv¨a kuunnella t¨all¨a v¨alill¨a mahdollisten j¨arjestelm¨anlaajuisten k¨aytt¨oliit- tym¨a¨an vaikuttavien tapahtumien varalta. onStart()- ja onStop()-kutsuja voi tulla lukuisia aktiviteetin koko elinkaaren aikana. onRestart()-metodia kutsutaan, jos ak- tiviteetti on jo luotu aiemmin ja pys¨aytetty sitten onStop()-kutsulla. onRestart()- kutsua seuraa aina onStart()-kutsu.

Aktiviteetti on aktiivisena n¨ayt¨on etualalla onResume()- ja onPause()-kutsujen v¨a- lill¨a. Kun aktiviteetti on etualalla, k¨aytt¨aj¨a k¨aytt¨a¨a juuri sit¨a ja se on kaikkien muiden aktiviteettien p¨a¨all¨a. onResume() ja onPause() -kutsuja voi tulla tihe¨asti, esimerkiksi aina kun laitteen n¨aytt¨o menee lepotilaan tai tulee jokin ilmoitus akti- viteetin p¨a¨alle, joten niiden toteutus ei saa olla liian raskas.

Androidin j¨arjestelm¨a voi tuhota sovelluksen prosessin onPause()-, onStop()- tai onDestroy()-kutsun j¨alkeen. T¨am¨an takia pysyv¨aksi tarkoitettu tieto on tallennetta- va onPause()-kutsun j¨alkeen. Tallennus voidaan tehd¨a esimerkiksi toteuttamalla ta- kaisinkutsumetodi onSaveInstanceData(), jota kutsutaan aina, ennen kuin j¨arjestel- m¨a mahdollistaa aktiviteetin tuhoamisen. onSaveInstanceData() saa parametrinaan Bundle-olion, johon voi tallentaa tietoja nimi-arvo-pareina. Sama Bundle-olio tulee aktiviteetille onCreate()- ja onRestoreInstanceState()-metodeille. Tiedon palautuk- sen voi tehd¨a kummassa tahansa n¨aist¨a metodeista. Activity-luokka tarjoaa my¨os oletustoteutuksen onSaveInstanceData()- ja onRestoreInstanceState()-metodeista, jotka osaavat monissa tapauksissa suorittaa tiedon tallennuksen ja palautuksen. Ak- tiviteetin tilanpalautusta tarvitaan usein, esimerkiksi aina kun k¨aytt¨aj¨a vaihtaa so- velluksen suuntaa pysty- ja vaakasuuntien v¨alill¨a.

Aktiviteettien vaihtumisen yhteydess¨a takaisinkutsujen j¨arjestys on aina sama.

Kun aktiviteetti A k¨aynnist¨a¨a aktiviteetti B:n, ensin kutsutaan aktiviteetti A:n

(14)

onPause()-metodia, sitten aktiviteetti B:n onCreate(), onStart()- ja onResume()- metodeita per¨akk¨ain. Viimeiseksi kutsutaan aktiviteetti A:n onStop()-metodia, mi- k¨ali aktiviteetti B peitt¨a¨a sen kokonaan. N¨ain esimerkiksi aktiviteetti A:n onPause()- metodissa tietokantaan tallennetut tiedot ovat k¨ayt¨oss¨a aktiviteetti B:t¨a k¨aynnistet- t¨aess¨a. Jos muutoksia taas tekee onStop()-metodissa, ne tapahtuvat vasta aktiviteet- ti B:n k¨aynnistytty¨a [andb].

2.5 Palvelut

Kuva 3: Palvelun elinkaari [andb]

Palvelut ovat pitk¨akestoisia taustaoperaatioita. Muut sovelluskomponentit voivat k¨aynnist¨a¨a niit¨a, ja ne jatkuvat vaikka k¨aytt¨aj¨a lopettaisi kyseisen sovelluksen k¨ayt- t¨amisen. Palvelu voi esimerkiksi soittaa musiikkia, suorittaa verkkotransaktioita, kommunikoida sis¨all¨ontarjoajien kanssa tai tehd¨a levykirjoitusta.

(15)

Palveluita on kahdenlaisia. K¨aynnistett¨av¨at (started) palvelut suorittavat teht¨av¨an- s¨a kun niiden startService()-metodia kutsutaan. T¨allainen palvelu voi jatkaa py¨o- rimist¨a taustalla, vaikka sovellus suljettaisiin. Tyypillisesti k¨aynnistett¨av¨a palvelu tekee jonkin yhden operaation, kuten tiedoston latauksen tai l¨ahett¨amisen, ja lo- pettaa sitten itsens¨a. K¨aynnistett¨av¨at palvelut eiv¨at yleens¨a palauta palautusarvo- na kutsujalle mit¨a¨an. K¨aynnistett¨avien palveluiden tulee sulkea itsens¨a operaation valmistuttua kutsumalla stopSelf()-metodia. My¨os muut komponentit voivat sulkea palvelun kutsumalla stopService()-metodia.

Sidotut (bound) palvelut ovat sellaisia, ett¨a sovelluskomponentit sitovat palvelun nii- hin kutsumalla bindService()-metoida. Sidotut palvelut tarjoavat asiakas-palvelin- rajapinnan sitovalle komponentille. Palvelu voi vastaanottaa pyynt¨oj¨a ja palaut- taa vastauksia niihin. Palvelun elinkaari on sama kuin sen sitoneen komponentin.

Useampi komponentti voi sitoa saman palvelun yht¨a aikaa. T¨all¨oin palvelu sulkeu- tuu kun viimeinenkin niist¨a lopettaa toimintansa. Sitominen vapautetaan kutsumal- la unbindService()-metodia.

Useimmiten k¨aynnistett¨av¨at ja sidotut palvelut ovat erillisi¨a, mutta joissain tilanteis- sa sama palvelu voi toimia sek¨a k¨aynnistett¨av¨an¨a ett¨a sidottuna palveluna. K¨aynnis- tett¨avi¨a palveluita k¨aytet¨a¨an tyypillisesti pitk¨akestoisiin taustaoperaatioihin, jotka suoritetaan taustalla ilman ett¨a k¨aytt¨aj¨a puuttuu niiden toimintaan. Sidotut palve- lut taas voivat tarjota sovellukselle mink¨a tahansa palvelurajapinnan, jonka kanssa sovellus voi kommunikoida palvelun elinkaaren ajan.

Palveluiden elinkaari on esitetty kuvassa 3. Aktiviteettien tavoin koko palvelun elin- kaari tapahtuu onCreate()- ja onDestroy()-kutsujen v¨aliss¨a ja palvelun alustus ta- pahtuu onCreate()-metodissa. Sidotun palvelun aktiivinen elinkaari on onBind()- ja onUnbind()-kutsujen v¨alill¨a. K¨aynnistett¨av¨an palvelun elinkaari puolestaan alkaa onStartCommand()-kutsusta kunnes se sulkee itsens¨a stopSelf()-kutsulla. onBind()- ja onStartCommand()-metodit saavat parametrinaan aikeen, jonka niit¨a kutsunut komponentti antoi bindService()- tai startService()-metodille [andb].

2.6 Sis¨ all¨ ontarjoajat

Sis¨all¨ontarjoajat tarjoavat p¨a¨asyn pysyv¨asti tallennettuun tietoon. Ne kapsuloivat tiedon ja tarjoavat mekanismit tiedon yksityisyyden hallintaan. Sis¨all¨ontarjoajat toi- mivat rajapintana tiedon ja sovelluskoodin v¨alill¨a. Kun sis¨all¨ontarjoajan tietoon ha- lutaan p¨a¨ast¨a k¨asiksi, k¨aytet¨a¨an ContentResolver-oliota Context-luokassa, joka sit-

(16)

ten kommunikoi itse sis¨all¨ontarjoajan kanssa.

Sis¨all¨ontarjoajat eiv¨at ole v¨altt¨am¨att¨omi¨a sovelluksessa, jos sovelluksen s¨ail¨om¨a¨an tietoon ei tarvitse p¨a¨ast¨a k¨asiksi sovelluksen ulkopuolelta. Sovellustenv¨aliseen kom- munikointiin sis¨all¨ontarjoajat tarjoavat vakiorajapinnan, joka pit¨a¨a huolen proses- sienv¨alisest¨a kommunikoinnista ja tietoturvallisuudesta.

Androidin mukana tulee valmiiksi toteutetut sis¨all¨ontarjoajat esimerkiksi musiikille, videotiedostoille ja k¨aytt¨aj¨an yhteystiedoille. N¨am¨a sis¨all¨ontarjoajat ovat kaikkien sovellusten k¨aytett¨aviss¨a [andb].

2.7 Aikeet

Suurin osa Android-sovellusten kommunikaatiosta on tapahtumapohjaista. Niin ak- tiviteetit, palvelut kuin sis¨all¨ontarjoajatkin k¨aynnistet¨a¨an l¨ahett¨am¨all¨a niille aie (in- tent). Tapahtumia k¨aytet¨a¨an Androidissa, koska niiden avulla komponentit voidaan sitoa toisiinsa ajonaikaisesti ja vasta silloin, kun niit¨a varsinaisesti tarvitaan. Itse aie-oliot ovat passiivisia tietorakenteita, joissa on abstrakti kuvaus operaatiosta, jo- ka halutaan suoritettavan, tai l¨ahetysten (broadcast) tapauksessa kuvaus siit¨a, mit¨a on tapahtunut.

Aikeiden kohde voidaan nimet¨a ekspliittisesti ComponentName-kent¨ass¨a. T¨all¨oin annetaan kohdekomponentin t¨aydellinen nimi paketteineen, jolloin kohde voidaan tunnistaa yksik¨asitteisesti. T¨am¨an muodon k¨aytt¨aminen vaatii, ett¨a kutsuva kom- ponentti tiet¨a¨a kohdekomponentin nimen. Sovelluksensis¨aisess¨a kommunikoinnissa t¨am¨a onnistuu, mutta sovellustenv¨alisess¨a kommunikoinnissa useinkaan ei. T¨all¨oin kohde p¨a¨atell¨a¨an implisiittisesti muista aikeelle annetuista kentist¨a.

Action-kent¨ass¨a annetaan tapahtuma, joka aikeella halutaan k¨aynnist¨a¨a, esimerkik- si puhelun aloitus, tai l¨ahetysten vastaanottajien tapauksessa j¨arjestelm¨ass¨a tapah- tunut tapahtuma, kuten varoitus akun loppumisesta. Intent-luokassa m¨a¨aritell¨a¨an lukuisia vakioita erilaisia tapahtumia varten, mutta niiden lis¨aksi sovellukset voivat m¨a¨aritell¨a my¨os omia tapahtumia.

Data-kent¨ass¨a annetaan tapahtumaan liittyv¨an tiedon osoite (URI) ja tyyppi (MI- ME). N¨ain vastaanottava komponentti tiet¨a¨a mink¨atyyppist¨a tietoa aikeeseen liit- tyy, ja mist¨a se l¨oytyy. Category-kent¨ass¨a kerrotaan, mink¨a tyyppisen komponentin odotetaan k¨asittelev¨an aikeen. N¨ait¨akin Intent-luokka tarjoaa valmiita, mutta omien k¨aytt¨o on mahdollista.

(17)

Aikeen vastaanottava komponentti voidaan p¨a¨atell¨a kahdella tavalla. Komponentti valitaan ekplisiittisesti, jos ComponentName-kent¨ass¨a on arvo. T¨all¨oin muiden kent- tien arvoista ei v¨alitet¨a. Muussa tapauksessa Action-, Data- ja Category-kenttien arvojen perusteella selvitet¨a¨an, mit¨a soveltuvia vastaanottavia komponentteja j¨ar- jestelm¨a¨an on asennettuna. T¨ass¨a k¨aytet¨a¨an apuna aiesuotimia (intent filter).

Sovellukset voivat m¨a¨aritell¨a aiesuotimia, jotta j¨arjestelm¨a tiet¨a¨a, mitk¨a sovellukset voivat ottaa vastaan aikeita. Aiesuotimet ovat komponenttikohtaisia, ja ne m¨a¨a- rittelev¨at, mit¨a tapahtumia, tietotyyppej¨a ja kategorioita ne tukevat. Aiesuotimia k¨aytet¨a¨an hyv¨aksi implisiittisess¨a kohteen m¨a¨arittelyss¨a. Jos kohde on m¨a¨aritelty eksplisiittisesti komponentin nimell¨a, aiesuotimilla ei ole vaikutusta [andb].

2.8 Android manifest

Jokaiseen Android-sovellukseen kuuluu AndroidManifest.xml-tiedosto, joka sis¨alt¨a¨a j¨arjestelm¨alle v¨altt¨am¨at¨ont¨a tietoa sovelluksen ajamiseksi. Manifestissa m¨a¨aritell¨a¨an sovelluksen Java-paketti, joka toimii samalla sovelluksen yksil¨ollisen¨a tunnisteena.

Manifestissa on my¨os listattu sovelluksen komponentit, aktiviteetit, palvelut, sis¨al- l¨ontarjoajat ja l¨ahetysten vastaanottajat, joista sovellus koostuu, sek¨a niiden toimin- nallisuus ulkopuolelta tulevien aikeiden kannalta. Lis¨aksi manifestissa ilmoitetaan, mit¨a oikeuksia sovellus tarvitsee toimiakseen sek¨a mit¨a oikeuksia toisilla sovelluksil- la pit¨a¨a olla, jotta ne voivat k¨aytt¨a¨a kyseisen sovelluksen palveluita. N¨aiden tietojen lis¨aksi manifestissa m¨a¨aritell¨a¨an sovelluksen vaatimukset ymp¨arist¨olt¨a¨an: mik¨a on sovelluksen vaatima Android APIn minimiversio sek¨a mit¨a kirjastoja sovellus tar- vitsee toimiakseen [andb].

Jos sovellus tarvitsee v¨altt¨am¨att¨a laitteelta tiettyj¨a ominaisuuksia, on mahdollista suodattaa sovellus pois Androidin sovelluskaupan hauista, jos sit¨a haetaan laitteella, joka ei tue sovelluksen vaatimia ominaisuuksia. T¨arkeimm¨at suotimet ovat Androidin API:n minimiversio, tiettyjen lis¨alaitteiden olemassaolo ja n¨ayt¨on koko.

<uses-sdk>-direktiivill¨a (directive) m¨a¨aritell¨a¨an Androidin APIn minimiversio. Jos

laitteessa on k¨ayt¨oss¨a pienempi API-versio kuin direktiivill¨a annettu, sovellusta ei n¨aytet¨a hakutuloksissa.<support screens>-direktiivi m¨a¨arittelee, mill¨a n¨ayt¨on kool- la sovellus toimii. Tavallisesti m¨a¨arittelem¨all¨a jokin tuettu koko sovelluskauppa olet- taa, ett¨a laite tukee sen lis¨aksi my¨os isompia n¨aytt¨okokoja muttei pienempi¨a. On my¨os mahdollista m¨a¨aritell¨a erikseen kaikki tuetut n¨aytt¨okoot.

<uses-feature>-direktiivill¨a voidaan m¨a¨aritell¨a mit¨a ominaisuuksia sovellus vaatii.

(18)

N¨ait¨a on sek¨a laitteistotasolla, kuten kamera, kiihtyvyysanturi tai kompassi, ett¨a ohjelmistotasolla, kuten vaikka liikkuvat taustakuvat, joiden py¨oritt¨amiseen kaikis- sa Android-laitteissa ei riit¨a resursseja. <uses-feature>-direktiivi¨a k¨aytet¨a¨an, kun sovellus ei lainkaan toimi ilman kyseist¨a ominaisuutta [anda].

2.9 Android-sovelluksen julkaiseminen

Kuva 4: Android-sovelluksen kehityskaari [andb]

Kuvassa 4 on kuvattu yksinkertaistettu Android-sovelluksen kehityskaari. Kun sovel- lus on kehitetty ja testattu, on viimeisen¨a vaiheena sen julkaisu. Android-sovellukset julkaistaan yleens¨a Google Play -sovelluskaupassa [goo]. Sovelluksia voi julkaista kuka tahansa. Julkaistakseen sovelluksia julkaisijan t¨aytyy rekister¨oity¨a ja maksaa 25 dollarin rekister¨oitymismaksu. Sovelluksen voi julkaista halutessaan my¨os vaik- ka omilla verkkosivuillaan tai muissa sovelluskaupoissa, mutta parhaan n¨akyvyyden Android-laitteissa saa t¨all¨a hetkell¨a Google Playssa.

Julkaisua varten sovellus t¨aytyy konfiguroida julkaisua varten ja k¨a¨ant¨a¨a julkaista- va APK-tiedosto, joka ladataan sovelluskauppaan. Lis¨aksi tarvitaan sovelluskauppaa varten muutama ruutukaappaus sovelluksesta sek¨a esittelyteksti. Sovellukselle pit¨a¨a my¨os valita nimi. Sovellus voi olla joko ilmainen tai maksullinen ja siin¨a voi olla lis¨aksi sovelluksen sis¨aisi¨a maksumekanismeja. Ainut rajoitus on, ett¨a kerran ilmai- sena julkaistua sovellusta ei saa muuttaa maksulliseksi. Ilmaiseksi ladattavissakin sovelluksissa voi kuitenkin k¨aytt¨a¨a sovelluksen sis¨aisi¨a maksumekanismeja.

Sovelluksen voi julkaista vain haluamissaan maissa ja saatavuutta voi rajoittaa my¨os laitekohtaisesti tai Androidin version perusteella. Google Play mahdollistaa my¨os alfa- ja betatestauksen pienille ryhmille. Kehitt¨aj¨an hallintan¨akym¨ast¨a n¨akee tilas- totietoa sovelluksen kaatumisista ja virhetilanteista sek¨a mit¨a versioita sovellukses- ta on k¨ayt¨oss¨a ja miss¨a Androidin versioissa niit¨a ajetaan. Sovelluksesta voi tehd¨a milloin tahansa p¨aivitysversion lataamalla p¨aivitetyn APK-tiedoston sovelluskaup- paan. Google Play ilmoittaa sovelluksen ladanneille automaattisesti uuden version ilmestymisest¨a [pub].

(19)

3 Ohjelmistojen testaaminen ja mobiilisovellus- ten testaamisen erityispiirteit¨ a

T¨ass¨a luvussa esitell¨a¨an ohjelmistojen testauksen perusk¨asitteit¨a, testauksen ase- maa ohjelmistotuotantoprosessissa, mobiilisovellusten testaamisen erityispiirteit¨a se- k¨a pohditaan, miten testausty¨okaluja voi arvioida.

3.1 Testaamisen perusk¨ asitteit¨ a

Testitapaus (test case) on yksitt¨ainen testi, jolle on m¨a¨aritelty sy¨otteet, suorituseh- dot ja l¨ap¨aisykriteerit. Testisarja (test suite) taas on joukko testitapauksia. Testi- sarja voi my¨os koostua useasta testisarjasta, jolloin esimerkiksi ohjelman jokaiselle komponentille voi olla oma testisarjansa ja yksi testisarja kattaa sitten kaikki yksit- t¨aisten komponenttien testisarjat [PY08, 153].

Yksikk¨otestaus on useimmiten lasilaatikkotestausta (white box testing / structural testing / glass box testing), jolloin testej¨a voidaan kirjoittaa ohjelmakoodin perus- teella. Testeilt¨a voidaan vaatia esimerkiksi tietty¨a koodikattavuutta, jolloin varmis- tetaan, ett¨a mahdollisimman suuri osa ohjelmakoodista tulee suoritettua testien ai- kana [PY08, 154].

Toiminnallisessa testauksessa (functional testing) testattavan ohjelman sis¨aist¨a ra- kennetta ei tunneta, vaan ollaan kiinnostuneita vain sy¨otteist¨a ja niit¨a vastaavista tu- losteista. Toiminnallista testausta voidaan kutsua my¨os musta laatikko -testaukseksi (black box testing). Toiminnallisessa testauksessa ollaan kiinnostuneita ohjelman k¨aytt¨aj¨alle n¨akyv¨ast¨a toiminnasta, ja testej¨a voidaan tehd¨a esimerkiksi ohjelman m¨a¨arittelyn pohjalta [PY08, 161-162].

Fuzz-testaus on satunnaistestauksen muoto, jossa ohjelmaan kohdistetaan satunnai- sia sy¨otteit¨a ja seurataan ohjelman tulosteita. Sy¨otteit¨a voidaan my¨os luoda kie- lioppien avulla, jolloin voidaan k¨aytt¨a¨a hy¨odyksi tietoa testattavasta ohjelmasta.

Fuzz-testaus on osoittautunut tehokkaaksi tavaksi l¨oyt¨a¨a sovelluksista virheit¨a, joi- ta muut testaustavat eiv¨at paljasta. Toisaalta satunnaisuus tarkoittaa, ett¨a testej¨a pit¨a¨a suorittaa lukemattomia kertoja, jos fuzz-testaukselle halutaan kattava testi- peitto. Fuzz-testaus on havaittu erityisen tehokkaaksi turvallisuusaukkoja etsitt¨aess¨a [GLM+08].

J¨aljittely (mocking) on tekniikka, joka helpottaa yksikk¨otestien kirjoittamista. Yk-

(20)

sikk¨otestien ulkoiset riippuvuudet voidaan korvata testeiss¨a kontrolloitavilla j¨aljitte- lij¨aolioilla. T¨all¨oin testit ovat vakaampia, koska ulkopuolisten komponenttien muok- kaus ei vaikuta testeihin, testin haluttuun lopputulokseen vaikuttava ymp¨arist¨o on helppo saada haluttuun muotoon. T¨all¨oin testien on helppo testata my¨os sellaisia olosuhteita, jotka ovat harvinaisia tai vaikeita saada muokattua. Lis¨aksi j¨aljittele- m¨all¨a voidaan korvata viel¨a toteuttamattomat ulkoiset riippuvuudet j¨aljittelij¨ato- teutuksilla [MFC01].

3.2 Testaaminen osana ohjelmistotuotantoprosessia

Kuva 5: Testauksen v-malli [SLS09, 40]

Ohjelmistotuotantoprosessia l¨ahestyt¨a¨an yleens¨a jonkin elinkaarimallin kautta. Tes- tauksen n¨ak¨okulmaa edustaa testauksen v-malli, joka on esitetty kuvassa 5. Mallin yleisess¨a versiossa l¨ahdet¨a¨an siit¨a, ett¨a jokaista ohjelmistotuotantoprosessin vaihet- ta vastaa jokin testausvaihe. N¨ain testaus tehd¨a¨an ohjelmistotuotantoprosessissa n¨akyv¨aksi ja yht¨a t¨arke¨aksi osaksi kuin itse sovelluksen kehitt¨aminen. Kuvassa v:n vasemmalla haaralla on vesiputousmallin mukaiset ohjelmistotuotantoprosessin vai- heet. Ensimm¨aisen¨a vaiheena on vaatimusm¨a¨arittely. T¨ass¨a vaiheessa m¨a¨aritell¨a¨an loppuk¨aytt¨aj¨an tai asiakkaan tarpeet ja vaatimukset sovellukselle. Viimeinen vai- he on alimpana oleva sovelluksen ohjelmointi. Oikealla haaralla ovat testausvaiheet, joissa jokaisessa varmistetaan, ett¨a ohjelma t¨aytt¨a¨a vasemman haaran samalla ta-

(21)

solla olevassa vaiheessa suunnitellut vaatimukset [SLS09, 39-42].

V-mallin alimmalla tasolla on komponentti- eli yksikk¨otestaus. Siin¨a testataan oh- jelman pienempi¨a itsen¨aiseen toimintaan kykenevi¨a osasia, eli olio-ohjelmoinnin ta- pauksessa useimmiten luokkia. Android-sovellusten tapauksessa t¨all¨a voidaan ajatel- la yksitt¨aist¨a Android-komponenttia, esimerkiksi aktiviteettia, tai jopa aktiviteettia pienempi¨a osia, kuten yksitt¨aist¨a n¨akym¨a-luokkaa tai muuta toimintaa tarjoavaa alikomponenttia. Komponenttitestaus on useimmiten valkoinen laatikko -testausta ja sen suorittaminen vaatii ohjelmointitaitoa. Useimmiten sovelluksen ohjelmoijat suorittavat itse komponenttitestauksen. Komponenttitestauksella pyrit¨a¨an varmis- tamaan, ett¨a komponentti t¨aytt¨a¨a sen toiminnallisen m¨a¨aritelm¨an. Komponentti- testej¨a tehd¨a¨an usein eri kielille kehitetyill¨a automaattisilla yksikk¨otestikehyksill¨a, kuten Javan JUnitilla. Oikean toiminnallisuuden testaamisen lis¨aksi on t¨arke¨a¨a tes- tata my¨os toiminta v¨a¨arill¨a sy¨otteill¨a ja poikkeustilanteissa. Moderni tapa tehd¨a komponenttitestausta on kirjoittaa testikoodi ennen sovelluskoodia [SLS09, 43-50].

V-mallin seuraavalla tasolla on integraatiotestaus. Siin¨a vaiheessa oletetaan, ett¨a komponenttitestaus on jo tehty ja yksitt¨aisten komponenttien omaan toimintaan liittyv¨at virheet on l¨oydetty. Integraatiovaiheessa yksitt¨aisten komponentit yhdiste- t¨a¨an toisiinsa ja testataan, ett¨a niiden yhteistoiminta on oikeanlaista. Tavoitteena on l¨oyt¨a¨a mahdolliset virheet komponenttien rajapinnoista ja komponenttien v¨a- lisest¨a yhteisty¨ost¨a. Testauksessa voidaan k¨aytt¨a¨a apuna tynki¨a (stub) sellaisista komponenteista, jotka eiv¨at viel¨a ole valmiita [SLS09, 50-52].

V-mallin kolmannella testaustasolla on j¨arjestelm¨atestaus (system testing). J¨arjes- telm¨atestauksessa testataan, ett¨a t¨aysin integroitu j¨arjestelm¨a toimii kokonaisuu- tena kuten pit¨aisi. Alemmista tasoista poiketen j¨arjestelm¨atestauksessa n¨ak¨okulma on j¨arjestelm¨an tulevan k¨aytt¨aj¨an, kun alemmilla tasoilla testaus on luonteeltaan enemm¨an teknist¨a. J¨arjestelm¨atestauksessa varmistetaan, ett¨a j¨arjestelm¨a kokonai- suudessaan t¨aytt¨a¨a sille asetetut toiminnalliset ja ei-toiminnalliset vaatimukset. J¨ar- jestelm¨atestauksessa ei tulisi k¨aytt¨a¨a en¨a¨a tynki¨a, vaan j¨arjestelm¨an kaikki kompo- nentit tulisi asentaa esimerkiksi erilliseen testiymp¨arist¨o¨on testausta varten. Itse so- velluksen lis¨aksi j¨arjestelm¨atestauksen piiriin kuuluvat ohjelmiston dokumentaatio ja konfiguraatio [SLS09, 58-61].

V-mallin viimeinen vaihe on hyv¨aksynt¨atestaus. Alemmilla tasoilla sovellus on ol- lut kehitt¨aj¨an vastuulla, mutta hyv¨aksynt¨atestauksessa j¨arjestelm¨a testataan asiak- kaan n¨ak¨okulmasta. T¨all¨oin pyrit¨a¨an varmistamaan, ett¨a tuotettu j¨arjestelm¨a t¨ayt- t¨a¨a mahdollisen toimitussopimuksen ja sen k¨aytt¨aj¨at hyv¨aksyv¨at j¨arjestelm¨an. Hy-

(22)

v¨aksynt¨atestaus voi sis¨alt¨a¨a my¨os alfa tai beta -testauksen oikeilla j¨arjestelm¨an lop- puk¨aytt¨ajill¨a [SLS09, 62-63].

Testauksen jokaisessa vaiheessa ollaan kiinnostuneita validoinnista ja verifioinnista.

Validoinnissa varmistetaan, ett¨a toteutus t¨aytt¨a¨a j¨arjestelm¨an alkuper¨aisen teht¨a- v¨an, eli ett¨a rakennetaan oikeaa sovellusta. Verifioinnissa taas varmistetaan, ett¨a kehitysvaiheessa tuotettu sovelluksen osa vastaa sille tehty¨a spesifikaatiota, eli ett¨a sovellus on tehty oikein. V-mallin eri vaiheissa validoinnin ja verifikaation paino- tukset vaihtelevat. Alemman tason testauksessa on kyse enemm¨an verifikaatiosta ja ylemm¨an tason testauksessa taas validoinnista [SLS09, 41-42].

Automaattiset testity¨okalut ovat tyypillisesti sit¨a enemm¨an k¨ayt¨oss¨a, mit¨a alem- malla v-mallin testaustasolla testausta tehd¨a¨an. Varsinkin komponenttitestaus on tyypillisesti t¨aysin automatisoitua. Testauksen automatisoinnilla pyrit¨a¨an testaus- prosessin tehostamiseen, kun testien suorittaminen on nopeaa. Lis¨aksi testien luotet- tavuus paranee, kun ep¨aluotettavat manuaaliset vaiheet korvataan automaattisilla [SLS09, 201].

3.3 Mobiilisovellusten testaamisen erityispiirteit¨ a

Mobiilisovellusten kehitt¨amiseen liittyy haasteita, jotka liittyv¨at mobiiliymp¨arist¨on rajoituksiin. N¨ait¨a ovat muun muassa p¨a¨atelaitteiden rajallinen kapasiteetti ja jatku- va kehittyminen, erilaiset standardit, protokollat ja verkkotekniikat, p¨a¨atelaitteiden monimuotoisuus, mobiililaitteiden k¨aytt¨ajien erikoistarpeet sek¨a tiukat aikavaati- mukset sovellusten saamiseksi markkinoille. Sovellusmarkkinat ovat my¨os globaalit, joten sovellusten lokalisoinnissa eri kieli- ja kulttuuriymp¨arist¨oihin aiheuttaa haas- teita.

Sovelluksia rajoittaa my¨os mobiililaitteiden pieni fyysinen koko ja laitteiden erot koossa, painossa ja n¨ayt¨on koossa. My¨os k¨aytt¨oliittymiss¨a on eroja, joskin kosketus- n¨aytt¨opuhelimet ovat vallanneet suurimman osan markkinoista viime vuosina.

Mobiilisovelluksen on oltava laadultaan hyv¨a, jotta se on helppo saada toimimaan oikein erilaisissa laiteymp¨arist¨oiss¨a. Lis¨aksi julkaisunopeus voi olla kriittinen tekij¨a markkinaosuuden valtaamisessa. Jos kilpaileva sovellus julkaistaan viikkoa aikaisem- min, voi markkina olla jo t¨aytetty sovelluksen julkaisuhetkell¨a.

VTT on kehitt¨anyt mobiilisovellusten kehitt¨amiseen ketter¨an Mobile-D- l¨ahestymistavan. Testauksen kannalta olennaista on testil¨aht¨oisen kehityksen k¨aytt¨aminen (test driven development, tdd). Mobile-D:hen kuuluu testien kirjoitta-

(23)

minen ennen tuotantokoodin kirjoitusta, yksikk¨otestien automatisointi ja kaikkien ominaisuuksien hyv¨aksynt¨atestaus asiakkaan kanssa [AHH+04].

Testil¨aht¨oisess¨a kehityksess¨a on kaksi merkitt¨av¨a¨a periaatetta: ohjelmakoodia saa kirjoittaa vain automaattisen testin korjaamiseksi ja duplikaattikoodin poistamisek- si. N¨aist¨a periaatteista seuraa tunnettu tdd-sykli: punainen, vihre¨a, refaktoroi. Ensin kirjoitetaan testi, joka ei mene l¨api, koska testin toteuttavaa ohjelmakoodia ei ole viel¨a olemassa. Vaiheen nimi on punainen, koska useimmilla yksikk¨otestity¨okaluilla lopputuloksena n¨akyy punainen palkki, jos jokin testi ei mene l¨api. Toinen vaihe on kirjoittaa juuri sen verran koodia, mit¨a tarvitaan testin l¨ap¨aisemiseksi. T¨ass¨a vai- heessa ei v¨alitet¨a miten luettavaa ja eleganttia koodi on. Vaiheen nimi on vihre¨a, koska useimmissa yksikk¨otestity¨okaluissa lopputuloksena n¨akyy vihre¨a palkki, kun testit menev¨at l¨api. Viimeisess¨a vaiheessa refaktoroidaan toisessa vaiheessa mah- dollisesti syntynyt duplikaatti- tai muuten vaikealukuinen koodi. Testit auttavat varmistamaan, ettei refaktoroidessa hajoiteta vanhaa toiminnallisuutta. Jotta t¨al- lainen ohjelmointisykli olisi mahdollinen, ohjelmistoymp¨arist¨on t¨aytyy tarjota mah- dollisuus saada nopeasti palaute pienest¨a testijoukosta, jottei ohjelmoidessa jouduta jatkuvasti odottamaan testien ajautumista [Bec03].

3.4 Testity¨ okalujen arviointikriteereist¨ a

Androidille on tehty Androidin mukana tulevien testausty¨okalujen lis¨aksi monia mui- ta testausty¨okaluja. N¨am¨a ty¨okalut erottautuvat Androidin ty¨okaluista joko pyrki- m¨all¨a toteuttamaan jonkin asian paremmin kuin vastaava Androidin oma testaus- ty¨okalu tai sitten tarjoamalla testaamiseen sellaisen l¨ahestymistavan, jota Androidin omat testausty¨okalut eiv¨at tarjoa.

Testausty¨okalujen arviointia k¨asittelev¨at muun muassa Poston ja Sexton [PS92].

Hyv¨an testausty¨okalun kriteerit ovat osin kontekstista riippuvia, mutta Poston ja Sexton m¨a¨arittelev¨at my¨os yleisempi¨a kriteerej¨a testity¨okalujen arviointiin. Usein kriteerit ovat my¨os helposti m¨a¨aritelt¨aviss¨a: jollain ty¨okalulla pystyy testaamaan asioita, joita toisella ei voi. Ei-toiminnallisista olennaisista ominaisuuksista he luet- televat ty¨okalun tehokkuuden, miten nopeasti sen k¨ayt¨on oppii, miten nopeaa testien tekeminen sill¨a on ja miten luotettava ty¨okalu on.

Michael et al. [MBS02] ovat kehitt¨aneet joukon metriikoita testity¨okalun tehokkuu- den arviointiin. Heid¨an k¨aytt¨am¨ans¨a metriikat ovat saaneet innoituksensa tavallisil- le sovelluksille kehitetyist¨a erilaisista kompleksisuusmetriikoista, kuten koodirivien

(24)

m¨a¨ar¨a tai syklomaattinen kompleksisuus. He esitt¨av¨at listan vastaavia metriikoita testity¨okalujen tehokkuuden arviointiin. N¨ait¨a arvoja voi sitten painottaa testity¨oka- lujen valinnassa haluamallaan tavalla. Metriikoita ovat muun muassa ty¨okalun kyp- syys ja k¨aytt¨aj¨akunnan koko, helppok¨aytt¨oisyys, kustomointimahdollisuudet, au- tomaattinen testitapausten generointi, muiden ohjelmointity¨okalujen tarjoama tuki ty¨okalulle, luotettavuus sek¨a suoritusnopeus. Osalle metriikoista esitet¨a¨an my¨os t¨as- m¨allisi¨a laskukaavoja, jotka helpottavat kvantitatiivisen analyysin tekemist¨a.

Spillner et al. [SLS09, 218] listaavat testity¨okalujen valintaan vaikuttavia tekij¨oit¨a:

• Miten hyvin testity¨okalu saa tietoa ja pystyy vaikuttamaan testattavaan so- vellukseen

• Testaajien tietotaito ty¨okalun k¨ayt¨ost¨a

• Miten hyvin ty¨okalu voidaan integroida k¨ayt¨oss¨a oleviin kehitysty¨okaluihin

• Miten hyvin ty¨okalu voidaan integroida muihin k¨aytett¨aviin testausty¨okaluihin

• Mill¨a alustalla ty¨okalu toimii

• Ty¨okalun valmistajan tarjoama tuki, luotettavuus ja markkina-asema

• Lisenssiehdot, hinta ja yll¨apitokustannukset

Osa kriteereist¨a on hyvin kontekstiriippuvaisia, mutta my¨os niit¨a voi soveltaa ylei- semm¨an arvioinnin tekemisess¨a. Esimerkiksi testaajien tietotaidon sijaan voidaan arvioida, miten helppoa ty¨okalun k¨aytt¨o on oppia.

(25)

4 Android-sovellusten testaaminen ja Androidin mukana tulevat testity¨ okalut

Androidin sovelluskehityspaketin mukana tulee monia Googlen kehitt¨ami¨a testaus- ty¨okaluja. Esittelen niit¨a t¨ass¨a luvussa. Samalla tutustutaan Android-sovelluksen testaamisen perusteisiin.

4.1 Android-testien ajoymp¨ arist¨ o

Kuva 6: Android-testien ajoymp¨arist¨o [andc]

Android-sovelluksen testej¨a voi ajaa joko emulaattorilla tai suoraan puhelimessa.

Androidin testisarjat perustuvat JUnit-testikehikkoon. Puhdasta JUnitia voi k¨ayt- t¨a¨a sellaisen koodin testaamiseen, joka ei kutsu Androidin rajapintaa, tai sitten voi k¨aytt¨a¨a Androidin JUnit-laajennusta Android-komponenttien testaukseen. Laajen- nus tarjoaa komponenttikohtaiset yliluokat testitapausten kirjoittamista varten. N¨a-

(26)

m¨a luokat tarjoavat apumetodeita j¨aljittelij¨oiden (mock object) luomiseen ja kompo- nentin elinkaaren hallintaan. Androidin JUnit-toteutus mahdollistaa JUnitin versio 3:n mukaisen testityylin, ei uudempaa versio 4:n mukaista.

Kuvassa 6 on esitetty Androidin testien ajoymp¨arist¨o. Testattavaa sovellusta testa- taan ajamalla testipaketissa olevat testitapaukset MonkeyRunnerilla (ks. luku 4.3).

Testipaketti sis¨alt¨a¨a testitapausten lis¨aksi Androidin instrumentaatiota, eli apuv¨ali- neit¨a sovelluksen elinkaaren hallintaan ja koukkuja, joilla j¨arjestelm¨an l¨ahett¨ami¨a ta- kaisinkutsumetodikutsuja p¨a¨asee muokkaamaan, sek¨a j¨aljittelij¨aolioita korvaamaan j¨arjestelm¨an oikeita luokkia testin ajaksi j¨aljittelytoteutuksella [andb].

4.2 Komponenttikohtaiset yksikk¨ otestiluokat

Android tarjoaa aktiviteeteille, palveluille ja sis¨all¨ontarjoajille jokaiselle oman tes- tiyliluokkansa, joka mahdollistaa komponenttikohtaisten testien helpomman toteu- tuksen. Aktiviteettien testauksessa Androidin JUnit-laajennus on merkitt¨av¨a, koska aktiviteeteilla on monimutkainen elinkaari, joka perustuu paljolti takaisinkutsumeto- deihin. N¨aiden suora kutsuminen ei ole mahdollista ilman Androidin omia testiluok- kia. Aktiviteettien testauksen p¨a¨ayliluokka on InstrumentationTestCase. Sen avulla on mahdollista k¨aynnist¨a¨a, pys¨aytt¨a¨a ja tuhota testattavana oleva aktiviteetti halu- tuissa kohdissa. Lis¨aksi sen avulla voi j¨aljitell¨a j¨arjestelm¨aolioita, kuten Context- ja Applications-luokan instansseja. T¨am¨a mahdollistaa testin erist¨amisen muusta j¨ar- jestelm¨ast¨a ja aikeiden luomisen testej¨a varten. Lis¨aksi yliluokassa on metodit k¨ayt- t¨aj¨an vuorovaikutusten, kuten kosketus- ja n¨app¨aimist¨otapahtumien l¨ahett¨amiseen suoraan testattavalle luokalle.

Aktiviteettien testaamiseen on kaksi v¨alit¨ont¨a yliluokkaa, ActivityUnitTestCase ja ActivityInstrumentationTestCase2. ActivityUnitTestCase on tarkoitettu luokan yk- sikk¨otestaamiseen siten, ett¨a se on eristetty Android-kirjastoista. N¨ait¨a testej¨a voi ajaa suoraan kehitysty¨okalussa ja tarvittaessa Android-kirjaston j¨aljittelyyn on k¨ay- t¨oss¨a MockApplication-olio. ActivityInstrumentationTestCase2 taas on tarkoitettu toiminnalliseen testaukseen tai useamman aktiviteetin testaamiseen. Ne ajetaan nor- maalissa suoritusymp¨arist¨oss¨a emulaattorilla tai Android-laitteessa. Aikeiden j¨aljit- tely on mahdollista, mutta testin erist¨aminen muusta j¨arjestelm¨ast¨a ei ole mahdol- lista.

Palveluiden testaaminen on paljon yksinkertaisempaa kuin aktiviteettien. Ne toimi- vat eristyksess¨a muusta j¨arjestelm¨ast¨a, joten testattaessakaan ei tarvita Androidin

(27)

instrumentaatiota. Android tarjoaa ServiceTestCase-yliluokan palveluiden testaa- miseen. Se tarjoaa j¨aljittelij¨aoliot Application- ja Context-luokille, joten palvelun saa testattua eristettyn¨a muusta j¨arjestelm¨ast¨a. Testiluokka k¨aynnist¨a¨a testattavan palvelun vasta kutsuttaessa sen startService() tai bindService()-metodia, jolloin j¨al- jittelij¨aoliot voi alustaa ennen palvelun k¨aynnistymist¨a. J¨aljittelij¨aolioiden k¨aytt¨o palveluiden testaamisessa paljastaa my¨os mahdolliset huomaamatta j¨a¨aneet riippu- vuudet muuhun j¨arjestelm¨a¨an, koska j¨aljittelij¨aoliot heitt¨av¨at poikkeuksen, mik¨ali niihin tulee metodikutsu, johon ei ole varauduttu.

Sis¨all¨ontarjoajien testaaminen on erityisen t¨arke¨a¨a, jos sovellus tarjoaa sis¨all¨ontar- joajiaan muiden sovellusten k¨aytt¨o¨on. T¨all¨oin on my¨os olennaista testata niit¨a k¨ayt- t¨aen samaa julkista rajapintaa, jota muut sovellukset joutuvat k¨aytt¨am¨a¨an kom- munikoidessaan sis¨all¨ontarjoajien kanssa. Sis¨all¨ontarjoajien testauksen yliluokka on ProviderTestCase2, joka tarjoaa k¨aytt¨o¨on j¨aljittelij¨aoliot ContentResolveriosta ja Contextista, jolloin sis¨all¨ontarjoajia voi testaja eristyksiss¨a muusta sovelluksesta.

Yliluokka tarjoaa my¨os metodit sovelluksen oikeuksien testaamisen. Contextin j¨al- jittelij¨aolio mahdollistaa tiedosto- ja tietokantaoperaatiot, mutta muut Androidin kirjastokutsut on toteutettu tynkin¨a (stub). Lis¨aksi tiedon kirjoitusosoite on uniikki testiss¨a, joten testien ajaminen ei yliaja varsinaista sovelluksen tallentamaa tietoa.

Sis¨all¨ontarjoajatestit ajetaan emulaattorissa tai Android-laitteella [andc].

4.3 MonkeyRunner

MonkeyRunner [monb] on Androidin sovelluskehyksen mukana tuleva ty¨okalu, joka tarjoaa rajapinnan, jolla Android-sovellusta voi ohjata laitteessa tai emulaattoris- sa. Se on l¨ahinn¨a tarkoitettu toiminnallisten testien sek¨a yksikk¨otestien ajamiseen, mutta soveltuu my¨os muihin tarkoituksiin. Sen avulla voi esimerkiksi asentaa sovel- luksia, ajaa testisarjoja ja sovelluksia ja l¨ahett¨a¨a niihin sy¨otteit¨a. Lis¨aksi monkey- runnerilla voi ottaa eri kohdista kuvakaappauksia ja verrata niit¨a referenssikuviin.

T¨all¨a tavalla voidaan tehd¨a esimerkiksi regressiotestausta.

MonkeyRunnerilla voidaan testata yht¨a aikaa monia eri emulaattoreita tai useita laitteita, jolloin voidaan testata nopeasti sovelluksen toimivuutta eri Androidin ver- sioilla ja laitteistoprofiileilla. MonkeyRunner on my¨os laajennettavissa, jolloin sit¨a voi k¨aytt¨a¨a muihinkin tarkoituksiin. MonkeyRunneria ohjataan Pythonilla ja se on toteutettu Jythonilla, joka on Javan virtuaalikoneessa py¨oriv¨a Python-toteutus.

(28)

4.4 Uiautomator ja Uiautomatorviewer

Uiautomator [uia] tarjoaa mahdollisuuden toiminnallisten musta laatikko -testien kirjoittamiseen Javalla. Uiautomator on Monkeyrunneria monipuolisempi, koska se tarjoaa laajemman rajapinnan sovelluksen tilatietojen kyselyyn ja sit¨a kautta mah- dollisuuden monipuolisempien testitapausten tekemiseen. Siin¨a on kaksi komponent- tia: Uiautomatorviewer ja Uiautomator. Uiautomatorviewer on graafinen ty¨okalu, jolla voi analysoida Android-sovelluksen k¨aytt¨oliittym¨a¨a. Uiautomator taas on ty¨o- kalu, joka tarjoaa rajapinnan ja moottorin toiminnallisten musta laatikko -testien ajamiseen.

Kuva 7: Ruutukaappaus Tomdroidin muokkausn¨akym¨ast¨a Uiautomatorilla analysoi- tuna

Uiautomatorviewer (kuvassa 7) analysoi sovelluksen n¨akym¨an komponentit. Vasem- massa osassa n¨aytet¨a¨an sovelluksesta ruutukaappaus, josta voi valita k¨aytt¨oliitty-

(29)

m¨akomponentteja analysoitavaksi. Valittu komponentti n¨aytet¨a¨an punaisella viivalla ympyr¨oityn¨a (kuvassa valittuna tallennus-painike yl¨apalkissa). Oikea puoli jakautuu kahteen osaan. Yl¨apuolella n¨aytet¨a¨an valitun komponentin sijainti n¨akym¨an kompo- nenttihierarkiassa, elementin tyyppi ja selite, sek¨a sen pikselikoordinaatti n¨ayt¨oll¨a.

Alapuolella taas on tarkemmat tiedot komponentista: sen j¨arjestysluku hierarkia- tasollaan (index), komponenttiin mahdollisesti liittyv¨a teksti (text), komponentin luokkahierarkia (class), paketti (package), siihen liitetty komponenttiselite (content- desc) sek¨a komponentin interaktioon liittyvi¨a tietoja, kuten onko se painettavissa tai valittuna. N¨ait¨a tietoja voi k¨aytt¨a¨a hyv¨akseen Uiautomator-testeiss¨a esimerkiksi komponentin valintaan.

Uiautomator-testit kirjoitetaan Javalla JUnitiin pohjautuen perim¨all¨a UIAutomatorTestCase-yliluokka, joka tarjoaa k¨aytt¨o¨on k¨aytt¨oliittym¨aelement- tien valitsemiseen tarvittavan rajapinnan ja mahdollisuuden vuorovaikutukseen niiden kanssa. UISelector-luokassa on metodeita k¨aytt¨oliittym¨aelementtien valitse- miseen ja UIObject-luokassa niiden kanssa kommunikointia varten. UIObject-oliolta voi kysy¨a assertointia varten elementin olemassaoloa ja erilaisia tilaan liittyvi¨a tietoja, kuten onko elementti k¨ayt¨oss¨a tai painettavissa.

Uiautomator on uusi ty¨okalu, joka tulee uusimpien Androidin sovelluskehysten mu- kana. Uiautomator-testej¨a voi ajaa vain laitteilla, jotka tukevat API:n versiota 16 tai uudempaa. T¨am¨a vastaa Androidin versiota 4.1, joka on julkaistu kes¨akuussa 2012.

Uiautomatorilla ei voi siis testata sovellusta vanhemmilla Android-laitteilla, joita on t¨all¨a hetkell¨a viel¨a reilusti yli puolet Androidin laitekannasta.

4.5 Monkey

Monkey [mona] on Androidin sovelluskehyksen mukana tuleva ty¨okalu, jota voi ajaa emulaattorissa tai Android-laitteessa ja joka tuottaa sovellukselle pseudosatunnai- sia sy¨otteit¨a. N¨ait¨a voivat olla esimerkiksi painallukset, eleet sek¨a j¨arjestelm¨atason viestit. Monkeyt¨a voi k¨aytt¨a¨a esimerkiksi sovelluksen stressitestaukseen tai fuzz- testaukseen.

Monkeylle voi antaa jonkin verran sen toimintaa ohjaavia parametreja. Ensinn¨akin testisy¨otteiden m¨a¨ar¨a¨a ja tiheytt¨a voi rajoittaa. Toiseksi erityyppisten sy¨otteiden osuutta voi s¨a¨at¨a¨a. Kolmanneksi testauksen voi rajoittaa tiettyyn pakettiin sovel- luksessa. T¨all¨oin Monkey pys¨aytt¨a¨a testauksen, jos se ajautuu muihin kuin halut- tuun osaan sovelluksesta. Nelj¨anneksi Monkeyn tulosteiden m¨a¨ar¨a¨a ja tarkkuutta

(30)

voi s¨a¨at¨a¨a.

Monkey pyst¨aytt¨a¨a testin, jos ohjelmasta lent¨a¨a k¨asittelem¨at¨on poikkeus tai jos j¨ar- jestelm¨a l¨ahett¨a¨a sovellus ei vastaa -virheviestin. N¨aiss¨a tapauksissa Monkey antaa raportin virheest¨a ja miten se syntyi. Monkey voi my¨os tehd¨a profilointiraportin testist¨a .

(31)

5 Yksikk¨ otestity¨ okalujen vertailua

Androidin yksikk¨otestaustapa on tehd¨a JUnit-testej¨a Androidin oman AndroidUnitTestCase-luokan aliluokkana. N¨am¨a testit ajetaan emulaattorissa Dalvik-ymp¨arist¨oss¨a. T¨ass¨a tavassa on kaksi heikkoutta, joiden takia on kehitetty my¨os kolmansien osapuolien yksikk¨otestity¨okaluja Android-ymp¨arist¨o¨on. Ensin- n¨akin testien ajaminen emulaattorissa on hitaampaa, kuin jos niit¨a voisi ajaa suoraan tavallisessa Javan virtuaalikoneessa JUnit-testein¨a. Toiseksi muutkaan testauksen apuna k¨aytett¨av¨at ty¨okalut, kuten j¨aljittelij¨a-ty¨okalut, eiv¨at v¨altt¨am¨att¨a toimi ongelmitta Dalvik-ymp¨arist¨oss¨a. T¨ass¨a luvussa vertailen Android-sovelluksen yksikk¨otestausta AndroidUnitTestCasella ja suosituimmalla Javan virtuaaliko- neessa py¨oriv¨all¨a vaihtoehdolla: Robolectricill¨a. Tavoitteena on selvitt¨a¨a, voiko Robolectricill¨a helposti korvata Androidin oman yksikk¨otestikehyksen ja pit¨a¨ak¨o Robolectricin lupaus nopeammasta testien suoritusajasta paikkansa.

Android-sovellusten yksikk¨otestauksessa kiinnostavaa on nimenomaan Androidin kirjastoluokista perivien keskeisten komponenttien testaus. Sovelluksessa mahdol- lisesti olevat muut kuin Androidin kirjastoluokista periv¨at luokat on helppo testata tavanomaisilla Javan yksikk¨otestity¨okaluilla ilman erityisesti Androidille tarkoitet- tuja ty¨okaluja samaan tapaan kuin muutkin Java-sovellukset.

Yksikk¨otestity¨okalujen testaukseen sovellan luvussa 3.4 esiteltyj¨a kriteerej¨a. T¨ar- kein kriteeri on ty¨okalujen toiminnallisuus: mit¨a niill¨a pystyy testaamaan, ja miten ne kommunikoivat testattavan sovelluksen kanssa. Yksikk¨otestity¨okaluissa toisena t¨ark¨an¨a kriteerin¨a pid¨an testien ajonopeutta, koska testivetoisessa kehityksess¨a yk- sikk¨otestej¨a ajetaan jatkuvasti ja jos testien ajoa joutuu odottamaan pitk¨a¨an, koko kehityssykli hidastuu. Koska molemmat testattavat ty¨okalut ovat JUnit-pohjaisia, niiden ty¨okalutuki on k¨ayt¨ann¨oss¨a identtinen. Androidin yksikk¨otestity¨okalut tule- vat luonnollisesti Android-kehyksen mukana, mutta Robolectric pit¨a¨a erikseen asen- taa, joten t¨am¨a vaikeuttaa Robolectricin k¨aytt¨o¨onottoa. Molemmat ty¨okalut ovat minulle uusia, joten arvioin subjektiivisesti ty¨okalujen oppimisen helppoutta sek¨a testien kirjoitusnopeutta.

Ensimm¨aisess¨a aliluvussa esitell¨a¨an lyhyesti Robolectric. Toisessa aliluvussa tutus- tutaan aiempaan tutkimukseen Androidin yksikk¨otestity¨okaluista. Seuraavassa alilu- vussa esittelen testiprojektin, jota k¨ayt¨an testity¨okalujen testaamiseen. Nelj¨annes- s¨a aliluvussa k¨asitell¨a¨an Robolectricin asentamista. Viidenness¨a aliluvussa vertai- len Robolectrici¨a ja AndroidUnitTestCasea testiprojektin elinkaarimetodien testauk-

(32)

sessa. Kuudennessa aliluvussa vertaillaan ty¨okalujen toimintaa j¨aljittelij¨akehyksen kanssa. Seuraavassa aliluvussa vertaillaan ty¨okalujen ajonopeuksia. Kahdeksannessa aliluvussa pohditaan Android-sovelluksen yksikk¨otestauksen haasteita ja viimeisess¨a aliluvussa analysoin testien tuloksia.

5.1 Robolectric

Robolectric on yksikk¨otestausty¨okalu, jonka tarkoitus on mahdollistaa Android- koodin yksikk¨otestaus suoraan ohjelmointiymp¨arist¨oss¨a Javan virtuaalikoneessa il- man emulaattoria. Tarkoitus on mahdollistaa nopea tdd-sykli ja helpompi integrointi jatkuvan integroinnin palveluihin. Normaalisti Android-kirjaston luokat palauttavat kutsuttaessa ohjelmointiymp¨arist¨ost¨a ajoaikaisen poikkeuksen, mutta Robolectric korvaa n¨am¨a luokat varjototeutuksilla, jotka palauttavat poikkeuksen sijaan tyhj¨an oletusvastauksen, kuten null, 0 tai false, tai jos Robolectricissa on kyseist¨a metodia varten olemassa varjototeutus, se palauttaa toteutuksen m¨a¨arittelem¨an paluuarvon.

Robolectricin varjoluokkien k¨ayt¨on vaihtoehtona on jonkin j¨aljittelij¨akehyksen k¨ayt- t¨aminen Androidin kirjaston korvaamiseen, mutta t¨am¨a tapa kirjoittaa testej¨a on hyvin ty¨ol¨as, koska koodirivej¨a kertyy v¨aist¨am¨att¨a paljon. Lis¨aksi t¨all¨oin testej¨a kirjoitettaessa t¨aytyy tuntea testattavan metodin toiminta hyvin tarkasti, jotta j¨al- jittelij¨atoteutukset saadaan kirjoitettua. Robolectricin varjoluokat mahdollistavat enemm¨an musta laatikko -tyyppisen testauksen [roba].

5.2 Aiempaa tutkimusta

Sadeh et al. vertasivat Androidin aktiviteettien yksikk¨otestausta JUnitilla, Androi- din omilla yksikk¨otestity¨okaluilla sek¨a Robolectricilla [S+11]. JUnitilla testattaessa ongelmaksi muodostui, ett¨a ohjelmakoodia jouduttiin melko rajusti muokkaamaan, jotta luokkien yksikk¨otestaus onnistui. T¨am¨a tekee ohjelman yll¨apidon vaikeaksi.

JUnitin hyv¨a puoli oli eritt¨ain nopea testien ajonopeus. Robolectricill¨a testien te- keminen taas oli l¨ahes yht¨a helppoa kuin Androidin omilla ty¨okaluilla. Androidin ty¨okaluihin verrattuna Robolectricin vahvuudet olivat virhepaikkojen paikantami- sen helppous ja testien suoritusnopeus. Robolectric-testit ajautuivat viisi kertaa no- peammin kuin Androidin ty¨okaluilla ajetut testit, koska Androidin ty¨okaluilla kirjoi- tetut testit ajetaan Dalvik-emulaattorilla, Robolectric taas suoraan Javalla. Androi- din omien ty¨okalujen suurin vahvuus oli testien kirjoittamisen helppous.

(33)

Sadeh et al. eiv¨at k¨aytt¨aneet JUnit-testeiss¨a¨an mit¨a¨an j¨aljittelij¨aty¨okalua, joten tes- teiss¨a testiluokan riippuvuudet j¨aljiteltiin tekem¨all¨a niist¨a staattisia sis¨aluokkia tes- tiluokan sis¨a¨an. T¨am¨a vaatii paljon koodia ja vaikutti osaltaan siihen, miksi puhdas JUnit-testi n¨aytti niin hankalalta. Androidin kirjastoluokat on pakko erist¨a¨a testat- tavasta luokasta Javan virtuaalikoneella testattaessa, koska Androidin kehitysymp¨a- rist¨oss¨a k¨aytett¨av¨a paketti ei sis¨all¨a varsinaisesti luokkien sis¨alt¨o¨a, vaan vain niiden luokkien julkiset rajapinnat, jolloin kehitysty¨okalut osaavat auttaa niiden k¨ayt¨oss¨a, mutta varsinaista toteutusta ei ole.

Jeon & Foster [JF12] mainitsevat Robolectricin vahvuudeksi sen, ett¨a se py¨orii Ja- van virtuaalikoneessa ja n¨ain ohittaa testeist¨a hitaan vaiheen, jossa sovellus pit¨a¨a k¨a¨ant¨a¨a emulaattorille tai laitteelle testattavaksi. Robolectric ei heid¨an mielest¨a¨an kuitenkaan sovellu kokonaisten sovellusten testaamiseen, koska sen varjoluokat eiv¨at toteuta Androidin komponenteista kuin osan.

Allevato & Edwards [AE12] k¨ayttiv¨at Robolectrici¨a opetusk¨aytt¨o¨on tarkoitetun RoboLIFT-ty¨okalun kehitykseen. Robolectric auttoi heit¨a ohittamaan emulaatto- rin k¨ayt¨on ja nopeuttamaan opiskelijoiden testisykli¨a ja automaattista arviointial- goritmia. T¨ass¨a k¨ayt¨oss¨a Robolectricin ongelma oli, ett¨a se ohittaa k¨aytt¨oliittym¨an piirt¨amisen kokonaan ja muunmuassa n¨akymien onDraw()-metodia ei kutsuta ollen- kaan. T¨am¨an seurauksena esimerksi n¨akym¨an leveys on aina 0 pikseli¨a, jolloin sellai- set testit, joilla haluttiin klikata n¨ayt¨oll¨a johonkin suhteelliseen kohtaan (vaikkapa keskelle) eiv¨at toimineet oikein.

5.3 Testiprojekti

Yksikk¨otestausty¨okaluja testasin itse tehdyll¨a demoprojektilla. Kyseess¨a on yksin- kertainen peli, jonka pelin¨akym¨ast¨a on ruutukaappaus kuvassa 8. Peliss¨a ohjataan kosketusn¨ayt¨oll¨a painamalla punaista palloa ja pyrit¨a¨an v¨aist¨am¨a¨an ymp¨ariins¨a pomppivia sinisi¨a palloja. Kun peli p¨a¨attyy, palataan takaisin p¨a¨an¨akym¨a¨an, jos- ta on ruutukaappaus kuvassa 9. T¨ast¨a n¨akym¨ast¨a voi aloittaa uuden pelin ja lis¨aksi n¨akee, montako sekuntia edellinen peli kesti.

Peli koostuu kahdesta aktiviteetista, yksinkertaisemmasta MainActivitysta sek¨a hie- man monimutkaisemmasta GameActivitysta, jonka yksikk¨otestaukseen keskityn. It- se peli¨a ohjaa GameView-luokka, joka on yht¨a aikaa n¨akym¨a ja kontrolleri MVC- suunnittelumallin mukaisesti. Malleja ovat GameClock, joka kuvaa pelikelloa, sek¨a Circle, joka kuvaa yht¨a ruudulla n¨akyv¨a¨a ympyr¨a¨a. GameActivity toteuttaa lis¨aksi

(34)

Kuva 8: Ruutukaappaus testiohjelman pelin¨akym¨ast¨a

OnGameEndListener-rajapinnan, jonka avulla GameView ilmoittaa pelin p¨a¨attymi- sest¨a ja pistem¨a¨ar¨ast¨a. Pelin luokkakaavio on esitetty kuvassa 10.

5.4 Robolectricin asentaminen

Robolectricin suositeltu asennustapa on Maven, joka on yleisesti k¨ayt¨oss¨a oleva k¨a¨ant¨amis- ja riippuvuuksienhallintaty¨okalu [mav]. Koska testattava projekti ei ol- lut Maven-projekti, jouduin tekem¨a¨an Robolectric-testitkin ilman Mavenia. Ilman Mavenia asennus osoittautui haastavaksi: eri kirjastopakettien riippuvuudet eiv¨at tahtoneet mitenk¨a¨an toimia yhteen. Lopulta asennus kuitenkin onnistui tekem¨al- l¨a Robolectricin TestRunnerista oma aliluokka. Listauksessa 1 on muokattu Ro- bolectricin aliluokka testej¨a varten l¨ahteen¨a olleesta esimerkist¨a [sam]. Olennaista on, ett¨a yliluokalle sy¨otet¨a¨an konstruktoriparametrina RobolectricConfig-olio, jolle annetaan parametrina testattavan Android-sovelluksen AndroidManifest.xml sek¨a resurssi-hakemiston osoite.

Robolectric-testej¨a varten luodaan oma tavallinen Java-projekti Eclipsess¨a, joka lai- tetaan viittaamaan Android-projektin koodiin. Testiprojektin k¨a¨ann¨ospolkuun tar-

(35)

Kuva 9: Testiohjelman p¨a¨an¨akym¨a

vitaan Robolectricin jar-paketti, sek¨a Androidin android.jar sek¨a maps.jar -paketit.

Robolectricin paketin pit¨a¨a olla riippuvuuslistassa ennen Android-paketteja, jotta se toimii. T¨am¨an j¨alkeen testej¨a voi ohjelmoida kuten tavallisia JUnit-testej¨a.

5.5 Aktiviteetin elinkaarimetodien yksikk¨ otestaus

Aktiviteetin elinkaarimetodien testaus on olennaisin osa Android-sovellusten yksik- k¨otestauksesta. Listauksessa 2 on yksinkertainen aktiviteettiyksikk¨otesti Robolect- ricill¨a toteutettuna. Robolectricin testit ovat yhteensopivia JUnitin 4. version kanssa, mik¨a mahdollistaa annotaatioiden k¨ayt¨on testeiss¨a. @RunWith-annotaatiolla m¨a¨ari- tell¨a¨an testien ajossa k¨aytett¨av¨a testiajuri (runner). Testiss¨a k¨aytet¨a¨an luvussa 5.4 esitelty¨a ajuria. @Before-annotaatiolla ilmaistaan metodit, jotka on ajettava ennen testej¨a ja @Test-annotaatiolla ajettavat testit.

setUp()-metodissa alustetaan testattava aktiviteetti ja kutsutaan sen onCreate()- metodia. Robolectric havaitsee automaattisesti Androidin kirjastometodien kutsun ja korvaa ne Robolectricin toteutuksella, jotta ne toimivat testiss¨a. Siksi aktiviteetti voidaan alustaa suoraan konstruktorilla ja kutsua sen onCreate()-metodia toisin kuin

Viittaukset

LIITTYVÄT TIEDOSTOT

k¨ aytet¨ a¨ an ei-polynomisia algoritmeja; t¨ am¨ a toimii jos ongelmat ovat riitt¨ av¨ an pieni¨ a (esim. TSP ja branch-and-bound) tai pahimman tapauksen.. sy¨ otteet

Er¨as ensimm¨aisen¨a mieleen tuleva tapa luonnehtia jat- kuvuus on k¨aytt¨a¨a infinitesimaalisen pienen (eli ¨a¨aret- t¨om¨an pienen) muutoksen k¨asitett¨a: Funktio on jatku-

Aktiivisten Solmun k¨aytt¨ajien mielest¨a sivut ovat sek¨a selke¨at ett¨a informatiiviset. T¨am¨a varmasti kannustaa Solmun toimitusta jatkamaan samoilla linjoilla pyrkien

Kokei- lumateriaalia k¨ aytt¨ av¨ a opettaja ei k¨ aytt¨ anyt lis¨ an¨ a suomalaista kirjaa ja opettajan selitykset ven¨ al¨ aisen monisteen teoriaselvityksiin olivat v¨ altt¨

Osoita maksimiperiaate k¨ aytt¨ am¨ all¨ a Gaussin keskiarvolausetta ja teht¨ av¨ an 2

K¨ aytt¨ opaikkojen m¨ a¨ ar¨ ass¨ a ei-kuukausittaista kulutusta sis¨ alt¨ av¨ at k¨ aytt¨ opaikat ovat merkitt¨ av¨ a osa koko aineistosta, koska noin 25 % k¨

Ensimm¨ aisess¨ a luvussa k¨ ayd¨ a¨ an l¨ api yleist¨ a tila-avaruusmallien teo- riaa. Siin¨ a n¨ aytet¨ a¨ an, kuinka tila-avaruusmalleja voidaan k¨ aytt¨ a¨ a esit- t¨

• Kaupungin hankeinvestointi: 85 MEUR (26 teatteritalon peruskorjaus + 14 lyseon vanha rakennus + 45 uusi rakennus kirjastolle, museoille jne.).. • Nettovuokranlisäys: 3,4 MEUR