JUnit

JUnit on Java-ohjelmointikielelle suunniteltu testauskehys, jonka avulla voidaan kirjoittaa ja ajaa yksikkötestejä sekä tarkastella testien tuloksia. Se on avoimen lähdekoodin yksikkötestauskirjasto, jolle löytyy tuki lähes kaikista ohjelmointiympäristöistä. JUnit kuuluu xUnit-testauskehysperheeseen, joka on kehittynyt Kent Beckin vuonna 1998 Smalltalkille suunnitellusta SUnitista. Nykyään XUnit-kehyksiä on olemassa useimmille ohjelmointikielille ja kehitysalustoille. Vuonna 2002 ensi kertaa julkaistu JUnit nousi nopeasti kehittäjien suosioon ja nykyään sen on todettu olevan lähes synonyymi automatisoidulle Java-yksikkötestaukselle. JUnit-kirjaston nykyinen versio on 5 (Jupiter).

JUnit on keskeisellä tavalla vaikuttanut testikeskeisen ohjelmistokehitystavan kehitykseen (engl. Test-driven development). Testivetoinen ohjelmistokehitys perustuu ohjelman rakentamiseen pieni osa kerrallaan samalla testaten. Testivetoisessa ohjelmistokehityksessä ohjelman yksittäistä osaa tarkasteleva automaattinen testi kirjoitetaan tyypillisesti koodia ennen.

JUnit rakenne 
JUnit perustuu testimetodeita sisältäviin testiluokkiin, joista yksi tai useampia voidaan suorittaa kerralla. Jokaisen testimetodin tulos ilmaistaan testin suorittamisen jälkeen joko onnistuneena tai epäonnistuneena. Testiluokat nimetään yleensä sen luokan nimellä, johon testi liittyy ja loppuun lisätään sana "Test".

JUnit-kirjaston annotaatiot lisätään testeissä suoritettaviin metodeihin seuraavan mukaisesti:

 @BeforeEach –suoritetaan ennen jokaista testitapausta
 @BeforeClass –suoritetaan ennen luokan ensimmäistä testiä
 @AfterEach –suoritetaan jokaisen testitapauksen jälkeen
 @AfterClass – tehdään lopuksi, kun kaikki luokan testitapaukset suoritettu
 @Test –yksittäinen testitapaus

Before-metodeilla suoritetaan alustustoimenpiteitä, joko ennen jokaista luokan testitapausta tai ennen kunkin yksittäisen testin ajamista. Test-metodit suorittavat varsinaisen testauksen ja vertaamisen odotettuun arvoon. After-metodit vastaavat siivoustoimenpiteistä, ne suoritaan joko yksittäisen testitapauksen ajon jälkeen tai lopuksi, kun kaikki yksittäiset testitapaukset on läpikäyty.

JUnit-kirjaston assert-metodien avulla tarkastetaan testattavan koodin oikeanlainen toimivuus. AssertEquals-metodia käyttämällä varmistetaan, että sille annetut arvot vastaavat toisiaan. AssertEqualsille annetaan ensimmäiseksi parametriksi arvo, joka vastaa ohjelman toiminnassa oikeaa vastausta, toisena parametrina annetaan testattava arvo. Mikäli arvot eivät vastaa toisiaan, kyseinen testi on epäonnistunut.

Yhteensopivuus muihin työkaluihin 
JUnit 5 sopii yhteen useiden alustojen kanssa. Tällaisia alustoja ovat esimerkiksi IDE (integrated development environments) ja CI (continuous integration).

Ant laajennus
Apache Ant on yksi monipuolisimmista rakentajista (build tool). Ant keskittyy build.xml-tiedoston ympärille, jota käytetään projektin suorittamiseen tarvittavien tehtävien määrittämiseen. Apache Ivy on Ant laajennus, joka on luotu helpottamaan riippuvuuksien erottelua. Projektin riippuvuudet voidaan ilmoittaa ivy.xml-tiedostossa. JUnit 5 voidaan liittää osaksi Ant ympäristöä määrittämällä JaCoCo (Java code coverage tools) ivy.xml-tiedostolle. ivy.xml voidaan tämän jälkeen konfiguroida java-platform-console- ja junit- platform-runner kanssa JUnit 5 käyttöön ottamiseksi.

Maven laajennus
Maven käyttää standardisoitua ja yhtenäistä lähestymistapaa rakennusprosessissa. Maven noudattaa riippuvuuksiensa hallinnassa "convention over configuration" -paradigmaa. Mavenia voidaan käyttää missä tahansa Java-projektissa. Se käyttää POM-mallia (Project Object Model), joka on XML pohjainen lähestymistapa projektin koontivaiheiden määrittämiseen. Mavenin toimimiseksi, täytyy Mavenin reitin olla rakennettu oikein. JUnit 5 voidaan liittää toimimaan osaksi Maven-ympäristöä käyttämällä jacoco-maven-plugin-liitintä, joka tukee valmiita toimintoja JUnit 5 -testeissä.

Gradle laajennus
Gradle on rakentaja, joka lainaa monia toiminnallisuuksiaan edeltäjistään Ant ja Maven. Toisin kuin Ant ja Maven, jotka ovat XML-pohjaisia, Gradle vaatii Apache Groovy:n käyttöä, joka on Java-pohjainen ohjelmointikieli. Gradle noudattaa Mavenin "convention over configuration" -lähestymistapaa ja lisäksi samaa rakennetta src/main/java- ja src/test/java -hakemistoissa. JUnit 5 voidaan liittää toimimaan osaksi Gradle-ympäristöä käyttämällä jacoco-liitintä yhdessä JUnit 5 koontitiedoston tarjoaman alustalaajennuksen kanssa.

JUnit Lisäosamalli
JUnit seuraa lisäosamallia, jossa kaikkia ominaisuuksia ei ole sisällytetty yhteen pakettiin. JUnit tiimin päätös olla lisäämättä kaikkia ominaisuuksia suoraan JUnitin ydinversioon, mahdollistaa ydinpaketin pienemmän koon ja tarjoaa kehittäjille tilaisuuden sovittaa toiminta erilaisten lisäosien kautta ohjelmistoon. 

JUnit 4:ssä on kaksi erilaista lisäosamekanismia, Runner API ja Rule API, joissa molemmissa on omat heikot puolensa.

Merkittävin ongelma Runner API:ssa on se, että kehittäjän tulee luoda koko elinkaari vaikka tarve olisi vain yhdelle elämänkaaren vaiheelle. Tämä on liian monimutkaista suurimmalle osasta tapauksista. Toinen merkittävä ongelma on tarve luoda jokaiselle tapaukselle oma Runner -luokkansa, sillä ne eivät ole yhteensopivia keskenään. Esimerkkinä tästä toimii Mockito ja Parametrisoidut Runnerit, sillä ne eivät voi olla samassa testiluokassa.

Rule -rajapinnan merkittävä ongelma on sen kyvyttömyys hallita koko testin elinkaarta, tehden siitä mahdottoman hyödyntää jokaisessa käyttötapauksessa. Sitä voidaan käyttää ainoastaa sellaisissa tapauksissa, missä jotain pitää tehdä ennen tai jälkeen testin suorittamista. Lisäksi, säännöt luokkatasolle ja metoditasolle tulee tehdä erikseen, vaikeuttaen testien kirjoittamista. 

JUnit 5:ssä lisäosarajapinta on sisäänrakennettu JUnit Jupiter -moottoriin, mahdollistaen kehittäjien yhtyä eri vaiheisiin testin elinkaaressa. Saavutettaessa tietty elinkaaren vaihe, Jupiter -moottori pystyy yhdistämään vaiheessa vaaditut lisäosat. Kehittäjän on mahdollista yhtyä viiteen keskeiseen vaiheeseen:
 Testin elinkaaren takaisinpyyntö - Mahdollistaa kehittäjän yhtyä tiettyyn elinkaaren vaiheeseen
 Testin instanssin jälkiprosessointi - Kehittäjä voi yhtyä testi-instanssin luonnin jälkeen tekemällä TestInstancePostProcessor -rajapinnan
 Ehdollinen testin suorittaminen - Kehittäjä pystyy suorittamaan testin kun tietyt ehdot täyttyvät
 Parametriresoluutio - Kehittäjä voi selvittää testimetodista tai rakentajasta saadun parametrin
 Virheenkäsittely - Mahdollistaa testiajon sopeuttamisen virheen heittämisen sijaan.

Aikaisemmat JUnit-versiot 
Martin Fowler, yksi JUnitin varhaisista käyttäjistä, kertoo:

"JUnit syntyi lennolla Zürichistä vuoden 1997 OOPSLAan Atlantassa. Kent (Beck) lensi Erich Gamman kanssa, ja mitä muuta kaksi nörttiä tekisi pitkällä lennolla kuin ohjelmoisi? JUnitin ensimmäinen versio rakennettiin siellä, pariohjelmoitiin ja testattiin ensi kertaa."

Laajan käytön sivuvaikutuksena JUnitin aiemmat versiot ovat edelleen suosittuja, sillä JUnit 4:llä on yli 100 000 käyttöä muilla Maven Central -tietovaraston ohjelmistokomponenteilla.

JUnit 4:ssä testin suorittamisen takaisinkutsujen merkinnät olivat @BeforeClass, @Before, @After ja @AfterClass, toisin kuin JUnit 5:n @BeforeAll, @BeforeEach, @AfterEach ja @AfterAll.

JUnit 3:ssa testien oli perittävä junit.framework.TestCase. Lisäksi testimenetelmien eteen piti liittää "test".

Lähteet 

 https://www.tutorialspoint.com/junit/junit_overview.htm
 https://junit.org/junit5/
 https://www.theseus.fi/bitstream/handle/10024/118620/Haltiapuu_Inka.pdf?sequence=1
 https://ohjelmointi2.github.io/kalvot/yksikkotestaus.pdf

Java