writing unit tests with spock framework
Skriveenhetstester med Spock Framework: Test inventar, påstander og rapportering
I dette Komplett nybegynnerguide på Spock , en kort Introduksjon om Spock Framework og Groovy programmering ble gitt i vår forrige opplæring.
I denne opplæringen vil vi gå gjennom alle detaljene / trinnene som kreves for å komme i gang med Enhetstesting i Spock.
For enkelhets skyld skal vi teste en enkel kalkulatorapplikasjon som har forskjellige metoder som tillegg, subtraksjon, multiplikasjon, divisjon, etc., som alle aksepterer heltallsparametere og returnerer et heltallutgang.
Hva du vil lære:
- Enhetstesting med Spock Video Tutorial
- Starter
- 'Def' nøkkelord
- Livssyklusen til en Spock-spesifikasjon
- Spock påstander
- Rapportering
- Konklusjon
- Anbefalt lesing
Enhetstesting med Spock Video Tutorial
Starter
I likhet med alle andre enhetstestingsrammer, kan Spock også brukes til å skrive scenarier / testtilfeller for et program som testes. Vi vil prøve å sammenligne og kontrastere de forskjellige funksjonene i Spock-rammeverket med eksisterende / kjente rammer som JUnit .
virtual reality spillbriller xbox 360
'Def' nøkkelord
La oss først prøve å forstå Groovys “def” nøkkelord i korte trekk. Def-nøkkelordet brukes til å definere type-def og kan brukes til å erklære en funksjon så vel som et felt / variabel.
'Def' brukes vanligvis når vi ikke vil begrense typen felt eller returtype for en metode. La oss se noen eksempler på def søkeord i en groovy klasse og alle dens gyldige bruksområder.
// def as variable types def inputNum = 100 def inputStr = 'hello world!!' def app = new CalculatorApp() // def as return type of function def 'test function'() { // function body here }
Livssyklusen til en Spock-spesifikasjon
Spock-spesifikasjon når den utføres, ser etter alle testene som er definert og utfører dem en etter en. Imidlertid er det få andre funksjoner / funksjoner som leveres av Spock for å gjøre tester mindre overflødige og mer lesbare.
La oss diskutere noen funksjoner nedenfor:
Definere innganger / variabler som en del av spes
Vurder å ha flere tester som alle bruker de samme inngangsverdiene. En måte ville være å initialisere inngangsverdiene i hver test individuelt, ellers kan vi direkte definere feltene på spesifikasjonsnivå og sikre at feltene før hver test vil bli initialisert og tilgjengelig for testen som utføres.
La oss se et eksempel på applikasjonsklassen vår .
Vi vil definere inngangsdataene på spesifikasjonsnivå slik at de vil være tilgjengelig med de opprinnelige verdiene for alle testene som er tilstede i spesifikasjonen.
class CalculatorAppSpec extends Specification { def input1 = 50 def input2 = 10 def result = 0 def app = new CalculatorApp() def 'addition with valid inputs return expected result'() { when: result = app.add(input1, input2) then: result == 60 } def 'multiplication with valid inputs return expected result'() { when: result = app.multiply(input1, input2) then: result == 500 } def 'division with valid inputs return expected result'() { when: result = app.divide(input1, input2) then: result == 5 } def 'subsctraction with valid inputs return expected result'() { when: result = app.substract(input1, input2) then: result == 40 } }
I dette kodeeksemplet kan du se at vi har definert input1, input2, applikasjonen under test og resultat på spesifikasjonsnivå. Det dette sikrer er at hver gang en test kjøres fra spesifikasjonsfilene, og de initialiserte feltene sendes til den testen. Dette eliminerer faktisk behovet for å sette opp tester hver gang med inngangsverdier.
Test inventar
I likhet med de fleste av enhetstestingsrammer, tilbyr Spock også oppsett- og oppryddingsmetoder for å utføre spesielle logikker / oppgaver ved spesifikke livssyklushendelser for testutførelse.
setupSpec & cleanupSpec
Disse metodene kalles en gang for hver Spec-utførelse og kalles henholdsvis før og etter testutførelsen. Disse er sammenlignbare med @ BeforeClass og @ Etter timen merknader om JUnit.
oppsett og opprydding
Disse metodene kalles før og etter gjennomføring av hver test i spesifikasjonen.
Disse krokene er det rette stedet for enhver logikk / kode som du vil utføre før og etter testutførelse. For eksempel , Ved opprydding kan du skrive en kode for å lukke databaseforbindelsen (hvis noen) som ble brukt under testen.
Disse kan sammenlignes med @ BeforeTest og @ AfterTest merknader i JUnit.
La oss se et eksempel på disse inventar i vår kalkulatorapplikasjonstest.
def setupSpec() { println('###in setup spec!') } def cleanupSpec() { println('###in cleanup spec!') } def setup() { println('>>>in test setup!') } def cleanup() { println('>>>in test cleanup!') }
Hvis den ovennevnte testinnretningskoden legges til i en spesifikasjon som inneholder 4 tester, vil utgangen være som nedenfor:
hvordan du returnerer matriser i java
###in setup spec! >>>in test setup! >>>in test cleanup! >>>in test setup! >>>in test cleanup! >>>in test setup! >>>in test cleanup! >>>in test setup! >>>in test cleanup! ###in cleanup spec!
Spock påstander
Påstandene i Spock kalles power assert (og det ble vedtatt av groovy senere etter at de ble introdusert av Spock). Spock-påstandene gir mange diagnostiske unntak i tilfelle feilmeldinger.
Man kan enkelt finne ut hva som gikk galt ved å bare se på feildiagnostikken i motsetning til ordet Påstand Feil i JUnit og andre rammer.
La oss prøve å forstå dette med et eksempel og kontrastere det med JUnit
Vi vil jobbe med en enkel test som sjekker om det er likeverdighet i strenger og se hvilken diagnostikk som genereres i tilfelle en påstandssvikt.
Spock Test
def 'check case-insensitive equality of 2 strings'() { given: 'two input strings' String str1 = 'hello' String str2 = 'HELLO world' when: 'strings are lowercased' str1 = str1.toLowerCase() str2 = str2.toLowerCase() then: 'equal strings should return success' str1 == str2 }
JUnit Test
@Test public void compareStrings_withValidInput_shouldReturnSuccess() { // Arrange String str1 = 'hello'; String str2 = 'HELLO world'; // Act str1 = str1.toLowerCase(); str2 = str2.toLowerCase(); // Assert Assert.assertEquals(str1,str2); }
Spock-utgang
Condition not satisfied: str1 == str2 | | | hello| hello world false 6 differences (45% similarity) hello(------) hello( world) Expected :hello world Actual :hello
JUnit-utgang
org.junit.ComparisonFailure: Expected :hello Actual :hello world
Som du kan utlede ovenfra, har diagnostisk informasjon gitt av Spock bedre detaljer og er mer brukervennlig sammenlignet med de andre rammene som JUnit.
Påstandstips og triks
Å hevde flere elementer på en gang - Spock gir forskjellige forkortelser for påstander, og en slik er '*' notasjon som gjør det mulig å hevde elementene på listen.
La oss forstå dette med et eksempel:
Vurder en CityInfo-klasse som har bynavn og befolkning som feltene. Vi vil skrive en Spock-test for å hevde navnene på byene som er der i listen.
public class CityInfo { public CityInfo(String cityName, int population) { this.cityName = cityName; this.population = population; } public String cityName; public int population; }
La oss se testen nå:
def 'Assert multiple elements of list' () { given: def cityList = new LinkedList() cityList.add(new CityInfo('Mumbai', 120)) cityList.add(new CityInfo('Delhi', 80)) cityList.add(new CityInfo('Chennai', 100)) expect: cityList*.cityName == ('Mumbai', 'Delhi', 'Chennai') }
Som vist i påstanden stenografi ovenfor kan du validere hele listen ved hjelp av '*' nøkkelordet.
La oss også se hvordan en feil ville ha sett ut. Jeg fjerner navnet på en by fra påstanden ovenfor.
Condition not satisfied: cityList*.cityName == ('Delhi', 'Chennai') | | | | | false | (Mumbai, Delhi, Chennai) (app.CityInfo@31368b99, app.CityInfo@1725dc0f, app.CityInfo@3911c2a7)
Du kan se at diagnostisk informasjon om påstandssvikt er rik og lett å forstå.
Utnytte lukningsparameter - hver ().
La oss se hvordan vi kan utnytte lukkingsparameteren som heter every () for å legge til en påstand for hvert element i en liste eller samling. I det samme eksemplet, la oss prøve å legge til en påstand som validerer befolkningen i hver by hvis den gitte innspill er> 50.
def 'Assert multiple elements of list' () { given: def cityList = new LinkedList() cityList.add(new CityInfo('Mumbai', 120)) cityList.add(new CityInfo('Delhi', 80)) cityList.add(new CityInfo('Chennai', 100)) expect: cityList*.cityName == ('Mumbai', 'Delhi', 'Chennai') and: cityList.population.every() { it > 50 } }
Å hevde kastede unntak
Unntak kan hevdes å kastes i 'da' -blokken (som betyr a når blokken også er nødvendig). Unntaksdetaljene kan diagnostiseres ved å tilordne det kastede unntaket til et felt og hevde de nødvendige egenskapene til unntaket som kastes.
La oss bruke den samme CityInfo-klassen og definere en metode som kaster et unntak og skrive en test for den.
public class CityInfo { public CityInfo(String cityName, int population) { this.cityName = cityName; this.population = population; } public String cityName; public int population; public CityInfo() { } public int getCleanlinessScore() { throw new RuntimeException('method not implemented'); } }
La oss se på testen nå:
def 'cleanliness score throws runtime exception with message - method not implemented'() { given: CityInfo app = new CityInfo(); when: app.cleanlinessScore() then: def e = thrown(RuntimeException) e.message == 'method not implemented' }
Rapportering
For å generere vakre og detaljerte HTML-baserte rapporter, er det tilgjengelige biblioteker som kan legges til i build-filen, og nå når testene blir utført under byggingen (eller ved direkte kjøring), blir en detaljert html-basert rapport generert i utdatamappe.
For å få testrapportene generert, legg til følgende biblioteker i build.gradle-filen (og tilsvarende for Maven pom.xml-filen også).
testCompile 'com.athaydes:spock-reports:1.6.1' testCompile 'org.slf4j:slf4j-api:1.7.13' testCompile 'org.slf4j:slf4j-simple:1.7.13'
Nå kan du bygge prosjektet og utføre testene ved å kjøre alle testene i 'test' -mappen eller ved å utføre ' gradere ren test ”.
Du kan åpne index.html fil for å få en oppsummert rapport for alle Spock-spesifikasjonene som var tilgjengelige for utføring.
beslutningstreetalgoritme i data mining
Hvis du vil se den detaljerte rapporten for en bestemt spesifikasjon, klikker du på spesifikasjonen fra listen ovenfor, og du kan se en detaljert rapport om feil og suksesser.
Konklusjon
I denne veiledningen dekket vi det grunnleggende om enhetstesting med Spock Framework. Vi så de forskjellige måtene og stenografiene for å skrive påstander og hva slags rik diagnostikkinfo som genereres av Spock-rammeverket for påstandssvikt.
Vi så også på hvordan vi kunne generere stille, ganske HTML-baserte rapporter for Spock-testene, som inkluderer den samme detaljerte diagnosen for testene som ble utført.
Vår kommende veiledning vil informere deg om å skrive parametriserte tester med Spock i detalj!
PREV Opplæring | NESTE veiledning
Anbefalt lesing
- Datadrevet eller parametrisert testing med Spock Framework
- Spock Intervjuespørsmål med svar (mest populære)
- Spock for integrasjon og funksjonstesting med selen
- Spock Mocking and Stubbing (Eksempler med videoveiledninger)
- Spock Tutorial: Testing With Spock And Groovy
- Mockito Tutorial: Mockito Framework for Mocking in Unit Testing
- Forskjellene mellom enhetstesting, integrasjonstesting og funksjonstesting
- Nøkkelen til vellykket enhetstesting - Hvordan utviklere tester sin egen kode?