Yksikkötestaaminen

Yksikkötestaaminen () on tietokoneohjelman testaamisen ja laadunvarmistuksen menetelmä, jossa lähdekoodin osat testataan yhdessä tai erikseen. Se on testaamisen alin taso ja eroaa koko ohjelman testaamisesta yhtenä kokonaisuutena. Se toteutetaan, jotta voidaan varmistaa ettei itse koodauksessa ole tapahtunut virheitä. Koska yksikkötestaus koskee itse koodia, sen suorittaa yleensä ohjelman kehittäjä.

Yksikkö tarkoittaa sovelluksen osaa. Yleensä yksikkö on yksittäinen toiminto, mutta esimerkiksi olio-ohjelmoinnissa yksikkö voi olla kokonainen luokka. Testeistä saadaan kattavia rakentamalla niitä ensin pienimmille testattaville yksiköille ja sen jälkeen niiden välisille yhteyksille. Ongelmien kartoittamiseksi jokainen testitapaus tulee testata erikseen. 

Yksikkötestauksen tavoitteena on eristää ohjelman jokainen osa ja osoittaa, että yksittäiset osat toimivat oikein. Yksikkötesti tarjoaa tiukan sopimuksen, joka koodinpalan on täytettävä. Yksikkötestaus löytää ongelmat kehityssyklin alkuvaiheessa. Vikoja voi ilmetä ohjelmoijan toteutuksessa ja yksikön määrityksessä. Testisarjan kirjoittaminen pakottaa miettimään syötteitä, lähtöjä ja virheolosuhteita, joiden avulla yksikön käyttäytyminen saadaan määriteltyä paremmin. Yksikkötestauksen kustannukset ovat huomattavasti alhaisemmat, kuin näiden virheiden löytäminen ohjelmistokehityksen loppuvaiheessa. 

Yksikkötestaaminen tyypillisesti voidaan suorittaa automatisoidusti, mutta myös manuaalisesti suorittaminen on mahdollista.

Ohjelman eri osat voidaan testin ajaksi korvata yksinkertaistetuilla korvikkeilla. Korvattavat osat eivät kuulu varsinaiseen testattavaan yksikköön.

Yksikkötestaamisen lisäksi voidaan tehdä integraatiotestaaminen, jossa eri yksiköt testataan yhtenäisenä kokonaisuutena.

Standardit, kuten IEC 61508, voivat vaatia ohjelman yksikkötestaamista.

Haittapuolet ja rajoitteet 
Testien kehittäminen voi vaatia paljon aikaa: jokaista Java-koodiriviä kohden tarvitaan keskimäärin 3–5 JUnit-koodiriviä riittävän kattavuuden saavuttamiseen.Tämä voi johtaa siihen, että investointi yksikkötestaukseen ei ole vaivan arvoista. Usein jos ohjelma on hyvin buginen, myös yksikkötestin koodi toimii kehnosti. Kuitenkin testien kirjoittamista ja ylläpitoa voidaan nopeuttaa parametroiduilla testeillä. Ne mahdollistavat yhden testin suorittamisen useita kertoja eri tulosarjoilla, joka vähentää testikoodin päällekkäisyyttä. Tavalliset yksikkötestit on suljettuja menetelmiä ja testaavat muutamia ehtoja, kun taas parametroidut testit testaavat minkä tahansa parametrin. 

Yksikkötestauksessakaan ei voida havaita jokaista ohjelman virhettä, koska se ei voi arvioida jokaista suorituspolkua muissa kuin triviaalisimmissa ohjelmissa. Tätä ongelmaa ei voida ratkaista. Tämän lisäksi yksikkötestaus määritelman mukaan testaa vain yksiköiden toimivuutta, joka johtaa siihen, ettei integrointivirheitä tai laajempia järjestelmätason virheitä huomata. Järjestelmätason virheiksi voidaan määritellä useissa yksiköissä suoritettuja toimintoja tai ei-toiminnallisia testialueita, kuten suorituskykyä. Tämän takia yksikkötestaus tulee tehdä muiden ohjelmistojen testaustoimintojen yhteydessä, jotta testauksesta saadaan tarpeeksi kattava. Yksikkötestaus ei vastaa integraatiotestausta, jolloin integrointi oheislaitteiden kanssa tulee sisällyttää itse integraatiotestaukseen.

Yksi haaste on yksikkötestien kirjoittamiseen liittyvä, realististen ja hyödyllisten testien asettamisen vaikeus. Asiaankuuluvat alkuehdot tulee luoda testiä tehdessä, jotta testattava sovelluksen osa käyttäytyy kuin osa koko järjestelmää. Jos alkuehdot puuttuvat tai ne eivät ole asetettu oikein, testi ei käytä koodia realistisessa kontekstissa joka heikentää testin arvoa ja tarkkuutta.

Jotta yksikkötestauksesta hyödytään, tulee pitää kirjaa suoritetuista testeistä ja kaikista muutoksista, jotka on tehty ohjelmiston yksikön lähdekoodiin. Versionhallintajärjestelmän käyttö on välttämätöntä. Jos myöhempi versio ei läpäise tiettyä testiä, jonka sen aiempi versio oli läpäissyt, löytyy versionhallinnasta luettelo lähdekoodin muutoksista, joita on tehty yksikössä tämän ajankohdan jälkeen. Tällöin voidaan tarkastella missä kohtaa virhe on sattunut. Tämän lisäksi on tärkeä ottaa käyttöön kestävä prosessi, joka varmistaa, että testitapausten epäonnistumiset tarkistetaan säännöllisesti ja niihin puututaan välittömästi. Jos tämä prosessi unohdetaan, testien tehokkuus heikkenee ja positiivisten tulosten määrä vähenee.

Sulautetun järjestelmäohjelmiston yksikkötestaus on ainutlaatuinen haaste yksikkötestauksessa. Koska tämä ohjelmisto kehitetään eri alustalle kuin, millä se lopulta ajetaan, testiohjelmaa ei voida suorittaa kovinkaan helposti ohjelman käyttöympäristössä kuten vaikka työpöytäohjelmien kanssa.

Testaamisen työkalut 
Yksikkötestauskehykset ovat useimmiten kolmannen osapuolen tuotteita, joita ei jaeta osana kääntäjäpakettia. Ne auttavat yksinkertaistamaan yksikkötestausprosessia, koska ne on kehitetty useille eri kielille.

Yksikkötestaamiseen on useita alustoja kuten JUnit, NUnit ja KUnit.

Kielitason yksikkötestauksen tuki 
Jotkin ohjelmointikielissä tukevat suoraan ykikkötestausta. Tämä tarkoittaa, että niiden kielioppi mahdollistaa yksikkötestien suoran ilmoittamisen ilman kirjaston tuontia.

Kielet, joissa on sisäänrakennettu yksikkötestaustuki:

 Apex 
 Cobra
 Crystal
 D
 Go
 Julia

 LabVIEW
 MATLAB
 Python
 Racket
 Ruby
 Rust

Joillakin kielillä ei ole sisäänrakennettua yksikkötestaustukea, mutta niillä on perustettu yksikkötestauskirjastot tai -kehykset. Näitä kieliä ovat:

 ABAP
 C++
 C#
 Clojure
 Elixir
 Java
 JavaScript
 Objective-C

 Perl
 PHP
 PowerShell
 R (testthat)
 Scala
 Tcl
 Visual Basic .NET
 Xojo (XojoUnit)

Lähteet 

Ohjelmiston testaaminen