Vodič kroz JUnit 4 pravila

1. Pregled

U ovom uputstvu ćemo pogledati značajku Pravila koju pruža knjižnica JUnit 4.

Počet ćemo s uvođenjem modela JUnit pravila prije prolaska kroz najvažnija osnovna pravila koja pruža distribucija. Pored toga, vidjet ćemo i kako pisati i koristiti vlastito prilagođeno pravilo JUnit.

Da biste saznali više o testiranju s JUnit-om, pogledajte našu sveobuhvatnu seriju JUnit.

Imajte na umu da ako koristite JUnit 5, pravila su zamijenjena modelom Extension.

2. Uvod u JUnit 4 pravila

Pravila JUnit 4 pružaju fleksibilan mehanizam za poboljšanje testova pokretanjem nekog koda oko izvršavanja test slučaja. U nekom je smislu to slično imati @Prije i @Nakon bilješke u našem ispitnom razredu.

Zamislimo da smo se tijekom postavljanja testa htjeli povezati s vanjskim resursom, poput baze podataka, a zatim zatvoriti vezu nakon završetka testa. Ako želimo koristiti tu bazu podataka u više testova, na kraju bismo duplicirali taj kod u svakom testu.

Korištenjem pravila možemo izolirati sve na jednom mjestu i lako ponovno koristiti kôd iz više klasa testa.

3. Korištenje pravila JUnit 4

Pa kako možemo koristiti pravila? JUnit 4 pravila možemo koristiti slijedeći ove jednostavne korake:

  • Dodati javnost polje u našu ispitnu klasu i osigurajte da je vrsta ovog polja podvrsta org.junit.rules.TestRule sučelje
  • Označite polje znakom @Pravilo bilješka

U sljedećem ćemo odjeljku vidjeti koje ovisnosti o projektu trebaju za početak.

4. Ovisnosti Mavena

Prvo, dodajmo ovisnosti o projektu koje će nam trebati za naše primjere. Trebat će nam samo glavna knjižnica JUnit 4:

 junit junit 4.12 

Kao i uvijek, najnoviju verziju možemo dobiti od Maven Central.

5. Pravila navedena u distribuciji

Naravno, JUnit nudi niz korisnih, unaprijed definiranih pravila kao dio knjižnice. Sva ta pravila možemo pronaći u org.junit.rules paket.

U ovom ćemo odjeljku vidjeti nekoliko primjera kako ih koristiti.

5.1. The Privremena mapa Pravilo

Tijekom testiranja često nam je potreban pristup privremenoj datoteci ili mapi. Međutim, upravljanje stvaranjem i brisanjem tih datoteka može biti nezgodno. Koristiti Privremena mapa U pravilu možemo upravljati stvaranjem datoteka i mapa koje bi trebale biti izbrisane kad se metoda ispitivanja završi:

@Rule public TemporaryFolder tmpFolder = new TemporaryFolder (); @Test public void givenTempFolderRule_whenNewFile_thenFileIsCreated () baca IOException {File testFile = tmpFolder.newFile ("test-file.txt"); assertTrue ("Datoteka je trebala biti kreirana:", testFile.isFile ()); assertEquals ("Privremena mapa i testna datoteka trebaju se podudarati:", tmpFolder.getRoot (), testFile.getParentFile ()); }

Kao što vidimo, prvo definiramo Privremena mapa Pravilo tmpFolder. Dalje, naša metoda ispitivanja stvara datoteku pod nazivom test-file.txt u privremenoj mapi. Zatim provjeravamo je li datoteka stvorena i postoji li tamo gdje bi trebala. Stvarno lijepo i jednostavno!

Kad test završi, privremenu mapu i datoteku treba izbrisati. Međutim, ovo pravilo ne provjerava je li brisanje uspješno ili nije.

Postoji i nekoliko drugih zanimljivih metoda koje vrijedi spomenuti u ovoj klasi:

  • newFile ()

    Ako ne navedemo nijedno ime datoteke, tada ova metoda stvara slučajno imenovanu novu datoteku.

  • newFolder (String ... folderNames)

    Da bismo stvorili rekurzivno duboke privremene mape, možemo se poslužiti ovom metodom.

  • nova mapa()

    Isto tako, nova mapa() metoda stvara slučajno imenovanu novu mapu.

Lijep dodatak koji vrijedi spomenuti je da, počevši od verzije 4.13, Privremena mapa pravilo omogućuje provjeru izbrisanih resursa:

@Rule public TemporaryFolder folder = TemporaryFolder.builder (). AssureDeletion (). Build ();

Ako se resurs ne može izbrisati, test s neuspjehom s AssertionError.

Konačno, u JUnit 5 možemo postići istu funkciju pomoću proširenja Privremeni direktorij.

5.2. The OčekivanoIznimka Pravilo

Kao što i samo ime govori, možemo koristiti OčekivanoIznimka pravilo za provjeru da neki kôd baca očekivanu iznimku:

@Rule public final ExposedException bačen = ExpectedException.none (); @Test javna praznina givenIllegalArgument_whenExceptionThrown_MessageAndCauseMatches () {thrown.expect (IllegalArgumentException.class); thrown.expectCause (isA (NullPointerException.class)); thrown.expectMessage ("Ovo je protuzakonito"); baciti novi IllegalArgumentException ("Ovo je protuzakonito", novo NullPointerException ()); }

Kao što možemo vidjeti u gornjem primjeru, prvo proglašavamo OčekivanoIznimka Pravilo. Zatim, u našem testu, tvrdimo da je an IlegalArgumentException baca se.

Korištenjem ovog pravila možemo provjeriti i neka druga svojstva iznimke, poput poruke i uzroka.

Detaljni vodič za testiranje iznimaka pomoću JUnit-a potražite u našem izvrsnom vodiču kako utvrditi iznimku.

5.3. The TestName Pravilo

Jednostavno rečeno, TestName pravilo pruža trenutno ime testa unutar zadane metode ispitivanja:

@Rule public TestName name = new TestName (); @Test javna praznina givenAddition_whenPrintingTestName_thenTestNameIsDisplayed () {LOG.info ("Izvršavanje: {}", name.getMethodName ()); assertEquals ("givenAddition_whenPrintingTestName_thenTestNameIsDisplayed", name.getMethodName ()); }

U ovom trivijalnom primjeru, kada pokrenemo jedinični test, u izlazu bismo trebali vidjeti naziv testa:

INFO c.baeldung.rules.JUnitRulesUnitTest - Izvršenje: givenAddition_whenPrintingTestName_thenTestNameIsDisplayed

5.4. The Pauza Pravilo

U sljedećem ćemo primjeru pogledati Pauza Pravilo. Ovo pravilo nudi korisnu alternativu upotrebi parametra vremenskog ograničenja na pojedinačnoj probnoj bilješci.

Sada, pogledajmo kako koristiti ovo pravilo za postavljanje globalnog vremenskog ograničenja za sve metode ispitivanja u našoj testnoj klasi:

@Rule public Timeout globalTimeout = Timeout.seconds (10); @Test javna praznina givenLongRunningTest_whenTimout_thenTestFails () baca InterruptedException {TimeUnit.SECONDS.sleep (20); }

U gornjem trivijalnom primjeru, prvo definiramo globalno vremensko ograničenje za sve metode ispitivanja od 10 sekundi. Tada namjerno definiramo test koji će trajati duže od 10 sekundi.

Kada pokrenemo ovaj test, trebali bismo vidjeti neuspjeh testa:

org.junit.runners.model.TestTimedOutException: test je istekao nakon 10 sekundi ...

5.5. The ErrorCollector Pravilo

Dalje ćemo pogledati ErrorCollector Pravilo. Ovo pravilo omogućuje nastavak izvođenja testa nakon pronalaska prvog problema.

Pogledajmo kako ovo pravilo možemo koristiti za prikupljanje svih pogrešaka i prijavljivanje svih odjednom kad test završi:

@Rule public final ErrorCollector errorCollector = novi ErrorCollector (); @Test javna praznina givenMultipleErrors_whenTestRuns_thenCollectorReportsErrors () {errorCollector.addError (novo bacanje ("Prva stvar je pošla po zlu!")); errorCollector.addError (novo Bacanje ("Još je nešto pošlo po zlu!")); errorCollector.checkThat ("Pozdrav svijetu", ne (sadržiString ("POGREŠKA!")); }

U gornjem primjeru sakupljaču dodajemo dvije pogreške. Kada pokrenemo test, izvršenje se nastavlja, ali test na kraju neće uspjeti.

U izlazu ćemo vidjeti obje prijavljene pogreške:

java.lang.Throwable: Prva stvar je pošla po zlu! ... java.lang.Throwable: Još je nešto pošlo po zlu!

5.6. The Provjerivač Pravilo

The Provjerivač pravilo je apstraktna osnovna klasa koju možemo koristiti kada želimo provjeriti neko dodatno ponašanje iz naših testova. Zapravo, ErrorCollector pravilo koje smo vidjeli u prošlom odjeljku proširuje ovu klasu.

Pogledajmo sada trivijalni primjer definiranja vlastitog verifikatora:

privatni popis messageLog = novi ArrayList (); @Rule public Verifier verifier = new Verifier () {@Override public void verify () {assertFalse ("Zapisnik poruka nije prazan!", MessageLog.isEmpty ()); }}; 

Ovdje definiramo novo Provjerivač i poništiti provjeri () metoda za dodavanje dodatne logike provjere. U ovom izravnom primjeru jednostavno provjeravamo da zapis poruka u našem primjeru nije prazan.

Sada, kada pokrenemo jedinični test i dodamo poruku, trebali bismo vidjeti da je primijenjen naš verifikator:

@Test javna praznina givenNewMessage_whenVerified_thenMessageLogNotEmpty () {// ... messageLog.add ("Nova je poruka!"); }

5.7. The DisableOnDebug Pravilo

Ponekad bismo možda htjeli onemogućiti pravilo prilikom otklanjanja pogrešaka. Na primjer, često je poželjno onemogućiti a Pauza pravilo prilikom otklanjanja pogrešaka kako bi se izbjeglo vremensko ograničenje i neuspjeh testa prije nego što smo stigli ispravno otkloniti pogreške.

The DisableOnDebug Pravilo čini upravo to i omogućuje nam označavanje određenih pravila koja će biti onemogućena prilikom uklanjanja pogrešaka:

@Rule public DisableOnDebug disableTimeout = novo DisableOnDebug (Timeout.seconds (30));

U gornjem primjeru možemo vidjeti da da bismo koristili ovo pravilo, mi jednostavno prenosimo pravilo koje želimo onemogućiti konstruktoru.

Glavna prednost ovog pravila je ta što možemo onemogućiti pravila bez ikakvih izmjena na našim testnim klasama tijekom uklanjanja pogrešaka.

5.8. The Vanjski resurs Pravilo

Tipično, prilikom pisanja integracijskih testova možda ćemo htjeti postaviti vanjski resurs prije testa i nakon toga ga srušiti. Srećom, JUnit za to nudi još jednu korisnu osnovnu klasu.

Sažetak možemo produžiti Vanjski resurs za postavljanje vanjskog resursa prije testa, poput datoteke ili veze s bazom podataka. Zapravo, Privremena mapa pravilo koje smo vidjeli ranije proteže se Vanjski resurs.

Kratko ćemo pogledati kako bismo mogli proširiti ovu klasu:

@Rule public final ExternalResource externalResource = new ExternalResource () {@Override protected void before () baca Throwable {// code to set a specific external resource. }; @Preuzmi zaštićenu prazninu nakon () {// koda za rušenje vanjskog resursa}; };

U ovom primjeru, kada definiramo vanjski resurs, jednostavno moramo nadjačati prije() metoda i nakon() metodu kako bismo postavili i srušili naš vanjski resurs.

6. Primjena pravila klase

Do sada su se svi primjeri koje smo gledali primjenjivali na metode pojedinačnog test slučaja. Međutim, ponekad bismo možda htjeli primijeniti pravilo na razini testne klase. To možemo postići pomoću @ClassRule bilješka.

Ova napomena djeluje slično kao @Pravilo ali obavija pravilo oko cijelog testa - glavna razlika je u tome što polje koje koristimo za naše pravilo klase mora biti statično:

@ClassRule javna statička Privremena mapa globalFolder = nova Privremena mapa ();

7. Definiranje prilagođenog pravila JUnit

Kao što smo vidjeli, JUnit 4 nudi mnoštvo korisnih pravila već izravno. Naravno, možemo definirati vlastita prilagođena pravila. Da bismo napisali prilagođeno pravilo, moramo implementirati TestRule sučelje.

Pogledajmo primjer definiranja pravila zapisivanja naziva prilagođene metode ispitivanja:

javna klasa TestMethodNameLogger implementira TestRule {private static final Logger LOG = LoggerFactory.getLogger (TestMethodNameLogger.class); Primjenjuje se javna izjava nadjačavanja (baza izjave, opis opisa) {logInfo ("Prije testa", opis); isprobajte {return new Statement () {@Override public void evaluacija () baca bacanje {base.evaluate (); }}; } napokon {logInfo ("Nakon testa", opis); }} private void logInfo (niska poruke, opis opisa) {LOG.info (msg + description.getMethodName ()); }}

Kao što vidimo, TestRule sučelje sadrži jednu metodu koja se naziva primijeniti (Izjava, Opis) da moramo nadjačati vraćanje instance Izjava. Izjava predstavlja naše testove u okviru izvršavanja JUnit. Kad nazovemo procijeniti () metodom, ovo izvršava naš test.

U ovom primjeru bilježimo poruku prije i poslije i uključujemo iz Opis prigovoriti nazivu metode pojedinačnog testa.

8. Korištenje lanaca pravila

U ovom posljednjem odjeljku pogledat ćemo kako možemo naručiti nekoliko pravila ispitivanja pomoću RuleChain Pravilo:

@Rule javni RuleChain lanac = RuleChain.outerRule (novo MessageLogger ("Prvo pravilo")) .around (novo MessageLogger ("Drugo pravilo")) .around (novo MessageLogger ("Treće pravilo"));

U gornjem primjeru kreiramo lanac od tri pravila koja jednostavno ispisuju poruku proslijeđenu svakom MessageLogger konstruktor.

Kada pokrenemo test, vidjet ćemo kako se lanac primjenjuje redom:

Početak: Prvo pravilo Početak: Drugo pravilo Početak: Treće pravilo je završeno: Treće pravilo je završeno: Drugo pravilo je završeno: Prvo pravilo

9. Zaključak

Da rezimiramo, u ovom uputstvu detaljno smo istražili pravila JUnit 4.

Prvo smo započeli objašnjavajući što su pravila i kako ih možemo koristiti. Zatim smo detaljno pogledali pravila koja dolaze kao dio distribucije JUnit.

Na kraju smo pogledali kako možemo definirati vlastito prilagođeno pravilo i kako povezati pravila.

Kao i uvijek, puni izvorni kôd članka dostupan je na GitHub-u.