writing unit tests with spock framework
Skriveenhedstest med Spock Framework: Testarmaturer, påstande og rapportering
I denne Komplet begyndervejledning om Spock , en kort Introduktion til Spock Framework og Groovy programmering blev givet i vores tidligere tutorial.
I denne vejledning gennemgår vi alle de detaljer / trin, der kræves for at komme i gang med Enhedstest i Spock.
Af hensyn til enkelheden skal vi teste en simpel lommeregnerapplikation, der har forskellige metoder som addition, subtraktion, multiplikation, division osv., Som alle accepterer heltalsparametre og returnerer et heltal output.
Hvad du lærer:
- Enhedstest med Spock-videovejledning
- Kom godt i gang
- 'Def' nøgleord
- Livscyklussen for en Spock-specifikation
- Spock påstande
- Rapportering
- Konklusion
- Anbefalet læsning
Enhedstest med Spock-videovejledning
hvordan man implementerer graf i java
Kom godt i gang
I lighed med andre enhedstestrammer kan Spock også bruges til at skrive scenarier / testcases for en applikation, der testes. Vi vil prøve at sammenligne og kontrastere de forskellige funktioner i Spock-rammen med de eksisterende / kendte rammer som JUnit .
'Def' nøgleord
Lad os først prøve at forstå Groovys 'def' nøgleord i korte træk. Def-nøgleordet bruges til at definere type-def og kan bruges til at erklære en funktion såvel som et felt / variabel.
'Def' bruges generelt, når vi ikke ønsker at begrænse typen af et felt eller returnere typen af en metode. Lad os se nogle eksempler på def-nøgleord i en groovy-klasse og alle dens gyldige anvendelser.
// 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 }
Livscyklussen for en Spock-specifikation
Spock spec, når den udføres, ser efter alle de definerede tests og udfører dem en efter en. Der er dog få andre funktioner / funktioner, der leveres af Spock for at gøre tests mindre overflødige og mere læsbare.
Lad os diskutere nogle af nedenstående funktioner:
Definition af input / variabler som en del af Spec
Overvej at have flere tests, der alle bruger de samme inputværdier. En måde ville være at initialisere inputværdierne i hver test individuelt, ellers kan vi direkte definere felterne på spec-niveau og sikre, at felterne inden hver test initialiseres og er tilgængelige for den test, der udføres.
Lad os se et eksempel på vores regnemaskineapplikationsklasse .
Vi definerer inputdataene på spec-niveauet, så de vil være tilgængelige med de indledende værdier til alle testene, der er til stede i specifikationen.
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 denne kodeeksempel kan du se, at vi har defineret input1, input2, applikationen under test og resultat på spec-niveau. Hvad dette sikrer er, at hver gang en test køres fra spec-filerne, og de initialiserede felter sendes til den test. Dette eliminerer faktisk behovet for at oprette tests hver gang med inputværdier.
Test inventar
I lighed med de fleste af enhedstestningsrammerne leverer Spock også opsætnings- og oprydningsmetoder til udførelse af speciel logik / opgaver ved specifikke livscyklushændelser for testudførelse.
setupSpec & oprydningSpec
Disse metoder kaldes en gang for hver Spec-udførelse og kaldes henholdsvis før og efter testudførelsen. Disse kan sammenlignes med @ BeforeClass og @ Efter skole annoteringer af JUnit.
opsætning og oprydning
Disse metoder kaldes før og efter udførelsen af hver test i specifikationen.
Disse kroge er det rigtige sted for enhver logik / stykke kode, som du gerne vil udføre før og efter testudførelse. For eksempel , I oprydning kan du skrive en kode for at lukke den databaseforbindelse (hvis nogen), der blev brugt under testen.
Disse kan sammenlignes med @ Før test og @ AfterTest annoteringer i JUnit.
Lad os se et eksempel på disse inventar i vores lommeregnertest.
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 ovenstående testarmaturkode føjes til en spec, der indeholder 4 tests, vil output være som nedenfor:
prøve testplan til softwaretest
###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åstande
Påstandene i Spock kaldes power assert (og det blev vedtaget af groovy senere efter at være blevet introduceret af Spock). Spock-påstandene giver mange diagnostiske undtagelser i tilfælde af påståede fejl.
Man kan let finde ud af, hvad der gik galt, ved blot at se på diagnosticering af fejl i modsætning til detaljeret Påstand Fejl i JUnit og andre rammer.
Lad os prøve at forstå dette med et eksempel og kontrastere det med JUnit
Vi arbejder med en simpel test, der kontrollerer, om der er streng lighed og se, hvilken diagnostik der genereres i tilfælde af en påstandssvigt.
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 output
Condition not satisfied: str1 == str2 | | | hello| hello world false 6 differences (45% similarity) hello(------) hello( world) Expected :hello world Actual :hello
JUnit-output
org.junit.ComparisonFailure: Expected :hello Actual :hello world
Som du kan udlede ovenfra, har diagnostiske oplysninger leveret af Spock bedre detaljer og er mere brugervenlige sammenlignet med de andre rammer som JUnit.
Påstand Tips og tricks
At hævde flere elementer på én gang - Spock giver forskellige stenografier for påstande, og en sådan er '*' notation, der gør det muligt at hævde elementerne på listen.
Lad os forstå dette med et eksempel:
Overvej en CityInfo-klasse, der har cityName og population som felter. Vi skriver en Spock-test for at hævde navnene på byer, der er der i den givne liste.
public class CityInfo { public CityInfo(String cityName, int population) { this.cityName = cityName; this.population = population; } public String cityName; public int population; }
Lad os se testen nu:
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 hjælp af '*' nøgleordet.
Lad os også se, hvordan en fiasko ville have set ud. 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 de diagnostiske oplysninger om påstandssvigt er rige og lette at forstå.
Brug af lukningsparameter - hver ().
Lad os se, hvordan vi kan udnytte lukningsparameter navngivet hver () for at tilføje en påstand for hvert element i en liste eller samling. I det samme eksempel, lad os prøve at tilføje en påstand, der validerer befolkningen i hver by, hvis den givne input 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 } }
Påstået kastede undtagelser
Undtagelser kan hævdes at blive kastet i ”da” -blokken (hvilket betyder a når blokken også er påkrævet). Undtagelsesdetaljerne kan diagnosticeres ved at tildele den kastede undtagelse til et felt og hævde de krævede egenskaber for den undtagelse, der kastes.
Lad os bruge den samme CityInfo-klasse og definere en metode, der kaster en undtagelse 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'); } }
Lad os se på testen nu:
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 at generere smukke og detaljerede HTML-baserede rapporter er der biblioteker til rådighed, som kan tilføjes i buildfilen, og nu, når testene udføres under build (eller ved direkte udførelse), genereres en detaljeret html-baseret rapport i outputmappe.
For at få testrapporterne genereret skal du tilføje følgende biblioteker til build.gradle-filen (og tilsvarende også for Maven pom.xml-filen).
testCompile 'com.athaydes:spock-reports:1.6.1' testCompile 'org.slf4j:slf4j-api:1.7.13' testCompile 'org.slf4j:slf4j-simple:1.7.13'
Opbyg nu projektet, og udfør testene ved at køre alle testene i mappen 'test' eller ved at udføre ' gradle ren test ”.
Du kan åbne index.html fil for at få en opsummeret rapport for alle Spock-specifikationer, der var tilgængelige til at blive udført.
hvilken e-mail-tjeneste skal jeg bruge
Hvis du vil se den detaljerede rapport for en bestemt spec, skal du klikke på spec fra ovenstående liste, og du kan se en detaljeret rapport om fejl såvel som succeser.
Konklusion
I denne vejledning dækkede vi det grundlæggende i Unit-test med Spock Framework. Vi så de forskellige måder og stenografier til at skrive påstande og den slags rige diagnostiske oplysninger genereret af Spock-rammen for påstandssvigt.
Vi så også på, hvordan vi kunne generere stille, smukke HTML-baserede rapporter til Spock-testene, som inkluderer den samme detaljerede diagnostik til de udførte tests.
Vores kommende vejledning orienterer dig om at skrive parametriserede tests med Spock i detaljer !!
PREV-vejledning | NÆSTE vejledning
Anbefalet læsning
- Datadrevet eller parametreret test med Spock Framework
- Spock Interview-spørgsmål med svar (mest populære)
- Spock til integration og funktionstest med selen
- Spock Mocking og Stubbing (Eksempler med videotutorials)
- Spock Tutorial: Test med Spock og Groovy
- Mockito Tutorial: Mockito Framework for Mocking in Unit Testing
- Forskellene mellem enhedstest, integrationstest og funktionstest
- Nøglen til vellykket enhedstest - Hvordan udviklere tester deres egen kode?