A specifikációk írása a Kotlin és a Spek cégekkel

1. Bemutatkozás

A specifikáció tesztelési keretrendszerek kiegészítik az egység tesztelési keretrendszereket alkalmazásaink teszteléséhez.

Ebben az oktatóanyagban bemutatjuk a Spek keretrendszert - a Java és Kotlin specifikáció tesztelési keretrendszerét.

2. Mi a specifikáció tesztelése?

Egyszerűen fogalmazva, a Specifikáció tesztelésben a specifikációval kezdjük és leírjuk a szoftver szándékát, annak mechanikája helyett.

Ezt gyakran a viselkedésvezérelt fejlesztésben használják fel, mivel a rendszert az alkalmazásunk előre meghatározott specifikációival szemben akarják érvényesíteni.

A közismert specifikációs tesztelési keretrendszerek közé tartoznak a Spock, az uborka, a jázmin és az RSpec.

2.1. Mi az a Spek?

A Spek egy Kotlin-alapú specifikációs tesztelési keretrendszer a JVM számára. Úgy tervezték, hogy JUnit 5 tesztmotorként működjön. Ez azt jelenti, hogy könnyen csatlakoztathatjuk minden olyan projekthez, amely már használja a JUnit 5-et, hogy futtasson bármilyen esetleges más tesztet.

A teszteket a régebbi JUnit 4 keretrendszerrel is futtathatja, szükség esetén a JUnit Platform Runner függőség használatával.

2.2. Maven-függőségek

A Spek használatához hozzá kell adnunk a szükséges függőségeket a Maven-összeállításunkhoz:

 org.jetbrains.spek spek-api 1.1.5 teszt org.jetbrains.spek spek-junit-platform-motor 1.1.5 teszt 

A spek-api függőség a tesztelési keretrendszerhez használt tényleges API. Mindent meghatároz, amellyel tesztjeink működni fognak. A spek-junit-platform-motor a függőség a JUnit 5 tesztmotor, amely a tesztjeink végrehajtásához szükséges.

Vegye figyelembe, hogy az összes Spek-függőségnek ugyanazzal a verzióval kell rendelkeznie. A legújabb verzió itt található.

2.3. Első teszt

A Spek felállítása után a tesztek megírása egyszerű eset, amikor a megfelelő osztályt a megfelelő szerkezetben írják. Ez kissé szokatlan, hogy jobban olvasható legyen.

A Spek megköveteli, hogy tesztjeink valamennyien egy megfelelő szuperosztályból származzanak - általában Spek - és hogy tesztjeinket úgy hajtjuk végre, hogy blokkot adunk át az osztály konstruktorának:

class FirstSpec: Spek ({// itt hajtsa végre a tesztet})

3. Tesztstílusok

A Specifikációs tesztelés a lehető legolvasottabb módon írja le a teszteket. Az uborka például az egész tesztet ember által olvasható nyelven írja, majd a lépésekhez köti, hogy a kód külön maradjon.

A Spek speciális módszerek alkalmazásával működik, amelyek olvasható húrként működnek, amelyek mindegyikének adott esetben blokkot kap a végrehajtáshoz. Van néhány variáció arról, hogy milyen funkciókat használunk, attól függően, hogy milyen módon akarjuk a teszteket olvasni.

3.1. adott/tovább/azt

Az egyik módja annak, hogy tesztjeinket megírhassuk, a „megadott / be / be” stílusú.

Ez az úgynevezett módszereket használja adott, tovább és azt, amely beágyazódik ebbe a struktúrába, tesztjeink megírásához:

  • adott - meghatározza a teszt kezdeti feltételeit
  • tovább - hajtsa végre a teszt műveletet
  • azt - állítsa, hogy a vizsgálati műveletet helyesen hajtották végre

Minden blokkból annyi lehet, amennyi szükséges, de ebben a sorrendben kell beágyaznunk őket:

class CalculatorTest: Spek ({megadott ("A számológép") {val számológép = Számológép () be van kapcsolva ("3 és 5 hozzáadása") {val result = calculator.add (3, 5) it ("8-at produkál") {assertEquals (8, eredmény)}}}})

Ez a teszt nagyon könnyen olvasható. A teszt lépéseire összpontosítva ezt olvashatjuk úgy: „Adott egy számológép, 3 és 5 hozzáadásakor 8-at eredményez”.

3.2. írja le/azt

A tesztek másik leírási módja a „leír / meg” stílus. Ehelyett ez a módszert használja írja le az összes fészkeléshez, és folyamatosan használja azt állításainkhoz.

Ebben az esetben fészkelhetjük a írja le módszereket, amennyire csak meg kell írnunk a tesztjeinket:

class CalculatorTest: Spek ({írja le ("A számológép") {val számológép = Számológép () írja le ("Összeadás") {val eredmény = számológép.add (3, 5) azt ("Helyes választ ad") {assertEquals ( 8. eredmény:}}}})

Kevesebb a struktúra érvényesítése a teszteken, amelyek ezt a stílust használják, ami azt jelenti, hogy sokkal nagyobb rugalmasságot biztosítunk a tesztek írásában.

Sajnos ennek hátránya, hogy a tesztek nem olyan természetes módon olvashatók, mint amikor a „megadott / be / be” szót használjuk.

3.3. További stílusok

A Spek nem érvényesíti ezeket a stílusokat, és lehetővé teszi a kulcsszavak cseréjét, amennyire csak kívánja. Az egyetlen követelmény az, hogy minden állítás létezzen egy azt és hogy ezen a szinten nincsenek más blokkok.

A rendelkezésre álló fészkelő kulcsszavak teljes listája:

  • adott
  • tovább
  • írja le
  • kontextus

Ezeket felhasználhatjuk arra, hogy tesztjeinknek a lehető legjobb struktúrát biztosítsuk annak megírásához.

3.4. Adatvezérelt tesztek

A tesztek meghatározásához használt mechanizmus nem más, mint egyszerű függvényhívások. Ez azt jelenti, hogy más dolgokat is megtehetünk velük, mint bármely normális kódot. Különösen adatvezérelt módon hívhatjuk őket, ha úgy kívánjuk.

Ennek legegyszerűbb módja az, hogy körbevezetjük a használni kívánt adatokat, és a hurok belsejéből felhívjuk a megfelelő blokkot:

class DataDrivenTest: Spek ({írja le ("Egy adatvezérelt teszt") {mapOf ("hello" - "HELLO", "world" - "WORLD"). Mindegyik {input, várható -> leírja ("A $ input nagybetűsítése") {it ("Helyesen adja vissza a $ várható" értéket) {assertEquals (várható, input.toUpperCase ())}}}}})

Mindenféle ilyen dolgot megtehetünk, ha szükséges, de ez valószínűleg a leghasznosabb.

4. Állítások

A Spek nem ír elő semmilyen különleges módszert az állítások felhasználására. Helyette, lehetővé teszi számunkra azt az állítási keretet, amellyel a legkényelmesebbek vagyunk.

A nyilvánvaló választás az lesz org.junit.jupiter.api.Allertations osztály, mivel tesztfutóként már a JUnit 5 keretrendszert használjuk.

Használhatunk azonban bármilyen más állítási könyvtárat is, amelyre szükségünk van, ha ez jobbá teszi a tesztjeinket - pl. Kluent, Expekt vagy HamKrest.

Az előnye, hogy ezeket a könyvtárakat használja a szokásos JUnit 5 helyett Állítások osztály a tesztek olvashatóságán múlik.

Például a fenti teszt a Kluent segítségével újraírva így hangzik:

class CalculatorTest: Spek ({írja le ("A számológép") {val számológép = Számológép () írja le ("Összeadás") {val eredmény = számológép.add (3, 5) azt ("Helyes választ ad") {result shouldEqual 8}}}})

5. Kezelők előtt / után

Mint a legtöbb tesztkeretnél, A Spek logikát is végrehajthat tesztek előtt / után.

Ezek pontosan a nevükből fakadóan blokkok, amelyeket a teszt előtt vagy után hajtanak végre.

Az itt található lehetőségek a következők:

  • beforeGroup
  • afterGroup
  • beforeEachTest
  • afterEachTest

Ezek elhelyezhetők a fészkelő kulcsszavak bármelyikében, és a csoporton belül mindenre vonatkoznak.

A Spek működésének módja, hogy a fészkelő kulcsszavak belsejében lévő összes kód azonnal végrehajtásra kerül a teszt kezdetén, de a vezérlő blokkok egy adott sorrendben kerülnek végrehajtásra azt blokkok.

Kívülről befelé dolgozva Spek mindegyiket végrehajtja beforeEachTest blokkolja közvetlenül minden előtt azt blokk beágyazva ugyanazon a csoporton belül, és mindegyik afterEachTest azonnal blokkolja minden után azt Blokk. Ugyanígy a Spek mindegyiket kivégzi beforeGroup blokkolja közvetlenül minden csoport és mindegyik előtt afterGroup azonnal blokkolja az összes fészkelés minden csoportját.

Ez bonyolult, és a legjobban egy példával magyarázható:

class GroupTest5: Spek ({írja le ("Külső csoport") {beforeEachTest {System.out.println ("BeforeEachTest 0")} beforeGroup {System.out.println ("BeforeGroup 0")} afterEachTest {System.out.println ( "AfterEachTest 0")} afterGroup {System.out.println ("AfterGroup 0")} írja le ("1. belső csoport") {beforeEachTest {System.out.println ("BeforeEachTest 1")} beforeGroup {System.out.println ("BeforeGroup 1")} afterEachTest {System.out.println ("AfterEachTest 1")} afterGroup {System.out.println ("AfterGroup 1")} it ("1. teszt") {System.out.println (" 1. teszt ")}}}})

A fentiek futtatásának eredménye:

BeforeGroup 0 BeforeGroup 1 BeforeEachTest 0 BeforeEachTest 1 Test 1 AfterEachTest 1 AfterEachTest 0 AfterGroup 1 AfterGroup 0

Rögtön láthatjuk, hogy a külső beforeGroup / afterGroup blokkok körül a teljes tesztkészlet, míg a belső beforeGroup / afterGroup blokkok csak a tesztek körül vannak ugyanabban a kontextusban.

Azt is láthatjuk, hogy az összes beforeGroup a blokkokat bármelyik előtt végrehajtják beforeEachTest blokkok és az ellenkezője a afterGroup / afterEachTest.

Ennek egy nagyobb példája, amely több csoportban végzett tesztek kölcsönhatását mutatja be, a GitHubon látható.

6. Tesztalanyok

Sokszor egyetlen Spec-t írunk egyetlen tesztalany számára. A Spek egy kényelmes módot kínál ennek megírására, így automatikusan kezeli számunkra a teszt alatt álló tárgyat. Használjuk a SubjectSpek alaposztály a Spek osztály erre.

Amikor ezt használjuk, be kell jelentenünk egy hívást a tantárgy blokk a legkülső szinten. Ez határozza meg a tesztalanyot. Ezt követően bármelyik tesztkódunkból erre hivatkozhatunk tantárgy.

Ezt használhatjuk korábbi kalkulátor tesztünk újraszerkesztésére az alábbiak szerint:

class CalculatorTest: SubjectSpek ({subject {Calculator ()} description ("A calculator") {description ("Addition") {val result = subject.add (3, 5) it ("Helyes választ ad") {assertEquals ( 8. eredmény:}}}})

Lehet, hogy nem tűnik soknak, de ez elősegítheti a tesztek sokkal olvashatóbbá tételét, különösen akkor, ha nagyszámú tesztesetet kell figyelembe venni.

6.1. Maven-függőségek

A Subject kiterjesztés használatához hozzá kell adnunk egy függőséget a Maven összeállításunkhoz:

 org.jetbrains.spek spek-subject-extension 1.1.5 teszt 

7. Összegzés

A Spek egy erőteljes keretrendszer, amely néhány nagyon olvasható tesztet tesz lehetővé, ami viszont azt jelenti, hogy a szervezet minden része el tudja olvasni őket.

Ez azért fontos, hogy minden kolléga hozzájárulhasson a teljes alkalmazás teszteléséhez.

Végül a kódrészletek, mint mindig, megtalálhatók a GitHubon.