Keskeisiä termejä

Testaukseen liittyy joukko vakiintuneita termejä, joita kuitenkin käytetään arjessa varsin epäjohdonmukaisesti. Arkikielessä puhumme yleensä vain bugeista (termin historiaan ja siihen, miten se päätyi tarkoittamaan myös ohjelmistovikaa, voi tutustua mm. Wikipediassa), mutta käytännössä bugi voi tarkoittaa jotain seuraavista:

  • Virhe (engl. error) on mikä tahansa ohjelmassa esiintyvä poikkeama sen spesifikaatiosta. Yksi yleinen kalliiden vikojen aiheuttaja on vaatimuksien välinen kuilu: jotain toiminnallisuutta ei ole kunnolla määritelty.

  • Vika (engl. fault, defect) aiheutuu virheellisen kohdan suorituksesta tai kun pitäisi suorittaa jotakin, mitä ei ole toteutettu. Vika ei siis välttämättä näy järjestelmän toiminnassa. Kaikki viat eivät myöskään johdu koodausvirheistä vaan niiden takana voi olla esimerkiksi vaatimusten puuttuminen tai laitteistossa oleva poikkeama.

  • Häiriö (engl. failure) on viasta johtuva näkyvä tapahtuma ohjelman ulkoisessa toiminnassa. Kaikki viat eivät siis johda häiriöön ja toisaalta yksi vika voi johtaa useampaan häiriöön eri puolilla ohjelmistoa.

kuva ns. ensimmäisestä ohjelmistobugista

Kuva ensimmäisestä löydetystä ohjelmistobugista, Naval Surface Warfare Center, Dahlgren, VA., 1988. - U.S. Naval Historical Center Online Library. Public Domain.

Ohjelman spesifikaatio kertoo ohjelman toiminnalle asetetut vaatimukset eli miten ohjelman pitäisi tai ei pitäisi toimia.

Tapoja testata

Ohjelmiston testaaminen voidaan toteuttaa hyvin eri tavoilla. Testausta voidaan myös tehdä kaikissa ohjelmistokehityksen vaiheissa, mutta tavoite aina on löytää virheet koodista mahdollisimman varhain. Tämä korostaa testaamisen keskeistä roolia osana ohjelmiston toteuttamista: sitä tehdään rinnakkain toteutustyön kanssa. Testaaminen voi olla mm.:

  • Dynaaminen testaus: ohjelmaa ajetaan joukolla sopivia syötteitä

  • Staattinen testaus: virheitä yritetään löytää koodista tutkimalla lähdekoodia tai dokumentaatiota katselmoimalla tai käyttämällä staattisen analyysin työkaluja.

  • Positiivinen testaus: käytetään “happy case” –tyyppisiä testitapauksia; yritetään varmistaa, että testattava järjestelmä tekee mitä pitäisi. Vähemmistö testeistä on positiivisia testejä.

  • Negatiivinen testaus: käytetään “unhappy case” –testejä eli tilanteita, joista vaatimukset eivät sano mitään tai juuri mitään, erilaisia virhetilanteita, yms. tilanteita, joissa ohjelman toiminnalle ei ole vaatimusten mukaista toimintaa määriteltynä.

  • Tutkiva testaus: ennalta suunniteltujen testitapausten sijaan testejä ei suunnitella tarkasti ennen testausta vaan testaaja etenee testitapausta eteenpäin vapaasti uusia testejä luoden. Testaus etenee jatkuvasti uusiin lennosta luotuihin testeihin edellisten lopputulosten perusteella.

Testaaminen voidaan myös jaotella sen mukaan, mitä ohjelmiston osaa tai toteutuksen vaihetta testataan:

  • Yksikkötestaus: automaattisesti ajattavia testejä, joilla varmistetaan yksittäisen ohjelman metodin tai moduulin toimintaa.

  • Integraatiotestaus: kehityksen aikana ajettavia testejä, jotka varmistavat että komponentit kutsuvat toisiaan oikein.

  • Järjestelmätestaus: testaa lopullista, toimivaa järjestelmää varmistaakseen, että se toimii määritellyn mukaisesti

  • Hyväksymistestaus: testaa vastaako toimitettu tuote tilattua

  • Regressiotestaus: testaa jo aiemmin testinsä läpäissyttä koodia varmistaakseen, etteivät tehdyt koodilisäykset ole rikkoneet mitään

Hyvä testi

Hyvien testitapausten keksiminen on yleensä hankalaa. Erityisen hankalaa se on ohjelman toteuttajalle. Samalla vain hyvien, kattavien testien avulla saadaan riittävästi tietoa ohjelmiston laadusta. Huonot testitapaukset saattavat antaa ohjelmiston laadusta liian ruusuisen kuvan: ohjelma näyttää toimivan niin kuin sen pitäisi vain, koska testitapaukset on valittu huonosti.

Hyvän testitapaus on pieni testi, joka testaa ohjelman käyttäytymistä:

  • Mitä testataan? Esim. laskimen jakolasku

  • Mikä on hyvä syöte? Esim. jako nollalla

  • Mikä on odotettu tulos? Esim. virheilmoitus, ohjelma ei kaadu, jotain muuta

Testitapauksia voidaan suunnitellaan joko ennen niiden suoritusta tai ns. lennosta. Jokainen testitapaus koostuu vaiheista:

  • Testitapauksen alustus: luodaan tarvittavat oliot, alustetaan muuttujat, luodaan koodiin testin tarvitsema tilanne

  • Itse testin suorittaminen: ajetaan testikoodi ja otetaan kaikki tulostus talteen

  • Tuloksen evaluointi: tutkitaan, mikä oli testin lopputulos ja kerrotaan siitä mahdollisimman selkeästi

  • Puhdistus: siivotaan testin jäljet ja vapautetaan varatut resurssit.

Ohjelmoijan vastuulle lankeaa testaamisesta erityisesti yksikkötestaaminen. Jatkuvan kehittämisen yleistyttyä jokaisen ohjelmistokehittäjän tulee myös testata koodinsa.

Ohjelmistojen testaus (kesto 16:07)

Testaus