JUnit er en tredjeparts open source-enhedstestramme. Projektet blev startet af Kent Beck og Erich Gamma i slutningen af 1995. Det vakte hurtigt interesse i fællesskabet af udviklere, som især beskæftiger sig med testdrevet udvikling. JUnit blev oprindeligt introduceret til Smalltalk, men blev senere overført til Java, som hurtigt opfangede dette som en de-facto standard for enhedstestning. Populariteten af JUnit voksede i en sådan grad, at der for at imødekomme behovene i mange andre nutidige sprog såsom C#, Perl, Python, PHP, Ruby, Visual Basic, C++ og så videre blev der udviklet en generisk xUnit-ramme, hvor bogstavet 'x' erstattes af det første bogstav i sproget, såsom JUnit for Java, RUnit for Ruby, og så videre. Denne artikel giver et overblik over denne ramme, som den bruges af de-facto-standarden for Java-enhedstestning.
Testoversigt
Test er en vigtig fase i en applikationsudviklings livscyklus. Hovedformålet med test er at evaluere et program ud fra de krævede specifikationer. Målet er at skabe visse testcases, der så vidt muligt viser fejl, huller, eventuelle uoverensstemmelser eller uventede resultater. Dette enkle koncept har nogle omfattende processer forbundet med det. Men for at sige det kort, det foregår på tre niveauer. Når testen udføres på det meget granulære eller individuelle komponentniveau, kaldes det Enhedstest; når de kombineres for at kontrollere grænseflader mellem komponenter i forhold til et softwaredesign, kaldes det Integrationstest; og endelig, når det komplette system er integreret, og test udføres for at verificere, at systemet som helhed opfylder det specificerede krav, kaldes det Systemtest .
Enhedstest
I en nøddeskal er udførelse af en enhedstest en måde at undersøge adfærden for en særskilt kodeenhed. I Java, en kodeenhed kan betyde en metode eller en klasse eller endda et modul, alt efter konteksten. Hvis det for eksempel er en metode, er fokus for testen på at evaluere den rigtige objektreference, der har lov til at påkalde metoden, typen af parametre og acceptable værdier, primitive værdiintervaller, returtype og -værdi, og så videre. Ideen er at grille metoden, så den kan gøres robust nok til på en yndefuld måde at håndtere sit problem og smide dem, der ligger uden for dens rækkevidde, bortset fra at opfylde dens kontrakt.
Derfor udgør enhedstest den grundlæggende byggesten i enhver programevaluering. Faktisk udfører hver programmør en form for enhedstest, mens man skriver kode for at kontrollere resultatet af koden med nogle dummy-data/sager. Enhedstest er således en formel status givet til den isolerede samling af tests. Det er ekstremt vigtigt, at en kode gennemgår strengheden af forskellige testfaser. Ud over dens betydning er enhedstesten også meget almindelig. Folk som Kent Beck og Erich Gamma tænkte på at skabe en ramme for det, så programmører får et struktureret miljø og kan automatisere mange af disse opgaver. Det er jo det, en ramme er til for. Typisk giver det en sammenhængende programstruktur, der kan genbruges og deles på tværs af applikationer. En programmør kan inkorporere dem i en eksisterende applikation og udvide dem efter dets specifikke behov.
Et hurtigt eksempel
En simpel enhedstestkode til at undersøge den enkelte metode i Temperature klasse uden at bruge JUnit framework er som følger:
package org.mano.unittest.examples; public class Circle { double area(double radius) { returnMath.PI* radius * radius; } }
Lad os nu skrive koden for at enhedsteste området metode.
package org.mano.unittest.examples; public class CircleTest { public int errCounter= 0; public void testCircleArea() { Circle circle = new Circle(); double area = circle.area(12); if (area < 452 && area > 453) { throw new IllegalStateException("Wrong calculation!: " + area); } } public static void main(String[] args) { TestCircle test = new TestCircle(); try { test.testCircleArea(); } catch (Throwable e) { test.errCounter++; e.printStackTrace(); } if (test.errCounter> 0) { throw new IllegalStateException("There were " + test.errCounter+ " error(s)"); } } }
Dette er et rudimentært eksempel, men giver dig en idé om, hvordan enhedstestning kan udføres uden at bruge nogen ramme.
JUnit Testing Framework
Brug af JUnit-ramme til enhedstest har flere fordele. Det giver adskillige annoteringer, der gør det nemt at skrive og køre testkoder i Java:
- Primært adskiller det bekymringen om enhedstestning fra den faktiske projektkode ved at gøre det muligt for en at oprette en testklasseinstans og klasseindlæsere for hver enhedstest. Disse "immuner" den eksisterende kode mod unødvendige bivirkninger af test.
- Annoteringerne leveret af JUnit – såsom @Before, @After, @BeforeClass, @AfterClass —har metoder til både ressourceinitialisering og ressourcegenvinding.
- Der er en lang række forskellige påstandsmetoder til at verificere resultatet af en test.
- I årenes løb blev JUnit så populær, at adskillige Java-værktøjer, såsom Ant og Maven; og populære IDE'er, såsom Eclipse , NetBeans , IntelliJ IDEE , og lignende, kommer med indbygget integration af JUnit.
For at bruge JUnit Test Framework i et Java-projekt, skal man tilføje en JUnit JAR-fil til projektklassens sti. Dette er eksplicit påkrævet, hvis IDE'en ikke er integreret med JUnit-biblioteket. Processen er enkel. Download JAR-filen og føj den til projektklassens sti.
Her er nogle vigtige links til JUnit framework.
- JUnit's officielle websted
- JUnit Java API
- JUnit brugervejledning
- JUnit-kildekode i GitHub
I modsætning til JUnit 4 og dens forgængere medførte JUnit 5 nogle væsentlige ændringer. Bortset fra mange nye funktioner tilføjet&mdahs;såsom lambda-understøttelse, nye annoteringer og testmetodeparameterindsprøjtning - har kernearkitekturen fået nogle væsentlige ændringer. JUnit 5 er nu en sammensat arkitektur af tre forskellige moduler:JUnit Jupiter, JUnit Vintage og JUnit Platform. Testcase-udviklerne behøver dog ikke at bekymre sig om de indviklede ændringer. Ændringerne betyder primært bedre værktøjsunderstøttelse, konsistens og renere API'er. Frem for alt er den direkte bagudkompatibel med JUnit 4. Så ingen bekymringer der heller. Se brugervejledningen til JUnit 5 for flere detaljer.
Et hurtigt eksempel
Her er et meget simpelt eksempel for at få et indblik i, hvordan enhedstestning kan udføres med JUnit-rammen. Vi bruger medarbejderen klasse til enhedstesten og opret en testklasse for at give en idé om dens funktion. Eksemplet er rudimentært i det omfang at skrive et 'Hello World'-program. Testcases i den virkelige verden, eller endda et anstændigt eksempel på enhedstest, kræver en god mængde kode. Måske prøver vi det i en anden artikel.
package org.mano.unittest.examples; public class Employee { private final String name; private final double basicPay; public Employee(String name, double basicPay) { this.name=name; this.basicPay=basicPay; } public String getName() { return name; } public double getBasicPay() { return basicPay; } } package org.mano.unittest.examples; import org.junit.Test; import static org.junit.Assert.*; public class EmployeeTest { @Test public void constructorInitTest(){ Employee emp=new Employee("Odin", 2300); assertEquals("Odin", emp.getName()); assertEquals(2300, emp.getBasicPay(), 0.001); } } package org.mano.unittest.examples; public class EmployeeTestMain { public static void main(String[] args){ EmployeeTest et=new EmployeeTest(); et.constructorInitTest(); } }
Bemærk, at Employee-klassen er uforanderlig med kun to felter indstillet af konstruktøren. Fordi kun konstruktørmetoden er værd at teste, tester vi kun den.
Testklassen hedder EmployeeTest efter konventionen. Annotationen @Test gør det muligt for JUnit at udpege en metode som en testmetode. Der er en række forskellige påstandsmetoder i Bekræftelse klasse. Her har vi kun brugt assertEquals .
Der er mange måder at køre en test skrevet i JUnit. Typisk udskriver den et resumé efter at testcaserne er kørt. Det kan dog variere afhængigt af, hvordan testen køres. Det kan køre gennem IDE'er som Eclipse eller IntelliJ, eller værktøjer som Maven, Gradle og så videre. Nogle gange er den eneste information, der modtages efter testen, at den enten er mislykket eller bestået.
Konklusion
Der er flere andre rammer for enhedstestning. JUnit er en populær enhedstestramme blandt Java-fællesskabet. Test som en systemingeniørfase har meget mere proces involveret. Enhedstest er bare en del af det, og interessant nok kan en masse legetest, der udføres af udvikleren, betegnes som enhedstest. JUnit, som en testramme, tilføjer værdi til det. Annoteringerne og API'erne leveret af JUnit automatiserer mange opgaver og gør livet meget lettere for enhedstestudviklerne.