Introduksjon til testing på iOS

Ingen ønsker å sende buggy programvare. Å sørge for at du slipper ut et mobilprogram av høyeste kvalitet, krever mye mer enn en menneskelig drevet manuell kvalitetssikringsprosess. Nye enheter og operativsystemer blir gitt ut til offentligheten hvert år. Dette betyr at det er en stadig voksende kombinasjon av skjermstørrelser og operativsystemversjoner som du må teste mobilapplikasjonen på. Ikke bare ville det være ekstremt tidkrevende, men forsøk på å teste ditt iOS-program ved manuell testing forsømmer et helt stykke av den moderne programvare engineering prosessen, automatisert kvalitetssikring testing.

I dagens verden finnes det mange verktøy som kan brukes til å teste automatisk programvaren du skriver. Noen av disse verktøyene opprettholdes gjennom en åpen kildekode-modell, men det er også et kjernesett levert av Apple. Med hver ny versjon av iOS SDK har Apple fortsatt å vise sitt engasjement for å forbedre verktøyene som er tilgjengelige for utviklere for å teste koden de skriver. For IOS-utvikleren som er ny for automatisert testing og interessert i å komme i gang, er Apples verktøy et godt sted å starte.

1. Apple gir nyttige verktøy

Denne opplæringen skal gi instruksjoner for bruk av et verktøy som Apple gir automatisert testing, XCTest. XCTest er Apples enhetstestingsramme. Enhetstesting er typen automatisert test som bekrefter kode på laveste nivå. Du skriver Objective-C-kode som kaller metoder fra "produksjon" -koden din og verifiserer at koden under test faktisk gjør hva den er ment å gjøre. Er variabler satt riktig? Er returverdien riktig?

Test som er skrevet med XCTest-rammen, kan gjentatte ganger utføres mot programmets kode for å hjelpe deg med å få tillit til at du oppretter et feilfritt produkt ved at nye kodeendringer ikke bryter eksisterende funksjonalitet.
Som standard er hvert nytt Xcode-prosjekt opprettet med et godt utgangspunkt for å skrive enhetstester. Dette inkluderer tre ting:

  • et eget mål for dine tester
  • en gruppe for testklassene dine
  • en eksempeltest


La oss grave inn i strukturen til en iOS-enhetstest. En individuell enhetstest er representert som en enkelt metode innenfor noen underklasse av XCTestCase hvor metoden kommer tilbake tomrom, tar ingen parametere, og metodenavnet begynner med test.

- (void) testSomething 

Heldigvis gjør Xcode å lage test tilfeller enkelt. Med nye Xcode-prosjekter, opprettes et første test-tilfelle for deg i en egen filgruppe hvis navn er suffiks av ordet tester.

2. Opprette din første iOS-enhetstest

Jeg har laget et prøveprosjekt som kan brukes som referanse for eksemplene i denne opplæringen. Last ned prosjektet fra GitHub og åpne det i Xcode.

Trinn 1: Opprett testcase klassen

I prøveprosjektet finner du gruppen av tester i mappen som heter JumblifyTests.

For å opprette ditt første testfall, høyreklikk filgruppen, JumblifyTests, og velg Ny fil. Velge Test Case Class fra iOS> Kilde seksjonen, og gi den nye underklasse et navn.

Den typiske navngivningskonvensjonen er å navngi prøvesaken slik at den er navnet på den tilsvarende klassen under test, suffiks med tester. Siden vi skal teste JumblifyViewController klasse, navn på XCTestCase underklasse JumblifyViewControllerTests.

Trinn 2: Ta ut Boilerplate-koden

I den splitter nye XCTestCase underklasse, vil du se fire metoder. To av disse er tester selv. Kan du identifisere hvilke de er? Husk at testmetodenavn begynner med ordet "test".

Hvis du ikke fant ut det, er testmetodene som er opprettet som standard, testExample og testPerformanceExample.

Slett begge tester, fordi vi skal skrive vår fra bunnen av. De to andre metodene, Setup og rive ned, er overstyrt fra superklassen, XCTestCase. De er unike i det Setup og rive ned blir kalt før og etter hver testmetode er påkalt henholdsvis. De er nyttige steder for sentralisering av kode som skal utføres før eller etter hver testmetode kalles. Oppgaver som vanlig oppstart eller opprydding går her.

Trinn 3: Koble testen din med din klasse under test

Importer headerfilen til JumblifyViewController klasse og legg til en eiendom av typen JumblifyViewController til XCTestCase underklasse.

@property (nonatomic) JumblifyViewController * vcToTest;

Setup metode, initialiser eiendommen som vist nedenfor.

- (void) setUp [super setUp]; self.vcToTest = [[JumblifyViewController alloc] init]; 

Trinn 4: Skriv en test

Vi skal nå skrive en test for å teste reverseString: metode av JumblifyViewController klasse.

Opprett en testmetode som bruker instantiated vcToTest protestere mot å teste reverseString: metode. I denne testmetoden lager vi en NSString objekt og send det til visningskontrolleren reverseString: metode. Det er vanlig å gi testen et meningsfylt navn for å gjøre det klart hva testen tester.

- (void) testReverseString NSString * originalString = @ "himynameisandy"; NSString * reversedString = [self.vcToTest reverseString: originalString]; 

På dette tidspunktet har vi ikke gjort noe nytt ennå, fordi vi ikke har testet reverseString: metode ennå. Det vi trenger å gjøre er å sammenligne produksjonen av reverseString: Metode med hva vi forventer at produksjonen skal være.

De XCTAssertEqualObjects funksjon er en del av XCTest-rammen. XCTest-rammen gir mange andre metoder for å gjøre påstander om applikasjonsstatus, for eksempel variabel likestilling eller booleske uttrykksresultater. I dette tilfellet har vi oppgitt at to gjenstander må være like. Hvis de er, går testen, og hvis de ikke er, svikter testen. Ta en titt på Apples dokumentasjon for en omfattende liste over påstander fra XCTest-rammen.

- (void) testReverseString NSString * originalString = @ "himynameisandy"; NSString * reversedString = [self.vcToTest reverseString: originalString]; NSString * expectedReversedString = @ "ydnasiemanymih"; XCTAssertEqualObjects (expectedReversedString, reversedString, @ "Den omvendte strengen stemmer ikke overens med forventet revers");

Hvis du prøver å kompilere koden på dette tidspunktet, vil du legge merke til en advarsel når du forsøker å ringe reverseString: fra test saken. De reverseString: Metoden er en privat metode for JumblifyViewController klasse. Dette betyr at andre objekter ikke kan påberope denne metoden, siden den ikke er definert i headerfilen til JumblifyViewController klasse.

Mens du skriver testbar kode er et mantra som mange utviklere følger, ønsker vi ikke å unødig endre koden vår under testen. Men hvordan kalles vi privat reverseString: metode av JumblifyViewController klasse i våre tester? Vi kan legge til en offentlig definisjon av reverseString: metode til header filen av JumblifyViewController klassen, men det bryter innkapslingsmønsteret.

Trinn 5: Legge til en privat kategori

En løsning er å legge til en privat kategori på JumblifyViewController klasse for å avsløre reverseString: metode. Vi legger til denne kategorien i XCTestCase underklasse, som betyr at den bare er tilgjengelig i den aktuelle klassen. Ved å legge til denne kategorien vil testsaken kompilere uten advarsler eller feil.

@interface JumblifyViewController (Test) - (NSString *) reverseString: (NSString *) stringToReverse; @slutt

Trinn 6: Kjør testen

La oss kjøre testene våre for å sikre at de passerer. Det er flere måter å kjøre enhetstester på for et iOS-program. Jeg er en tastatur snarvei junkie, så min mest brukte teknikk for å kjøre enhetstester for søknaden min er ved å trykke Kommando-U. Denne snarveien vil kjøre alle tester for søknaden din. Du kan også utføre samme handling ved å velge Test fra Produkt Meny.

Som testpakken vokser, eller hvis du liker å implementere testdrevet utvikling, vil du oppdage at å kjøre testpakken din kan bli for tidkrevende. Eller det kan komme i veien for arbeidsflyten din. En veldig nyttig kommando, begravet i Xcodes meny, som jeg har forelsket meg i, er Command-Option-Control-U. Denne snarveien utløser en kommando som kjører testen som markøren din er i. Når du har testserien fleshed ut og ferdigstilt, bør du alltid kjøre hele testpakken. Å kjøre en individuell test er nyttig når du skriver en ny testtest eller når du feilsøker en feiltest.

Kommandoen til å kjøre en test kompletteres med Command-Option-Control-G, som gjenoppretter siste testkjøring. Dette kan være hele testpakken eller bare den siste testen du jobber med. Det er også nyttig hvis du har navigert vekk fra hvilken test du jobber med, og du er fortsatt i ferd med å feilsøke den.

Trinn 7: Gjennomgang av resultatene

Du kan se testresultatene dine på noen få steder. En av disse stedene er Test Navigator til høyre.

Et annet alternativ er å se på gutten til Kilderedigerer.

I begge disse stedene klikker du på den grønne diamanten med det hvite tasten. I tilfelle en mislykket test ser du en rød diamant med et hvitt kryss i midten. Hvis du klikker på det, blir det også den samme testen.

3. Ny i Xcode 6

Xcode 6 introduserte to nye spennende tillegg til enhetstesting på IOS og OS X, testing av asynkron funksjonalitet og måling av ytelse av et bestemt kodeks.

Asynkron Testing

Forut for Xcode 6 var det ingen god måte å styre asynkron kode på enheten. Hvis enhetstesten din kalte en metode som inneholdt asynkron logikk, kunne du ikke verifisere den asynkrone logikken. Testen ville fullføre før den asynkrone logikken i testmetoden ble utført.

For å teste asynkron kode har Apple introdusert en API som lar utviklere definere en forventning som må oppfylles for at testen skal fullføres. Strømmen er som følger, definere en forventning, vent på forventningen skal oppfylles, og oppfyll forventningen når den asynkrone koden er ferdig. Ta en titt på eksemplet nedenfor for avklaring.

- (void) testDoSomethingThatTakesSomeTime XCTestExpectation * completionExpectation = [selvforventningWithDescription: @ "Long method"]; [self.vcToTest doSomethingThatTakesSomeTimesWithCompletionBlock: ^ (NSString * resultat) XCTAssertEqualObjects (@ "result", result, @ "Resultatet var ikke riktig!"); [ferdigstillelse oppfylle] ]; [self waitForExpectationsWithTimeout: 5.0 handler: null]; 

I dette eksempelet tester vi doSomethingThatTakesSomeTimesWithCompletionBlock metode. Vi ønsker å hengslere suksess eller fiasko av testen vår på verdien som returneres i ferdigstillingsblokken kalt av metoden under test.

For å gjøre dette definerer vi en forventning ved starten av testmetoden. På slutten av testmetoden venter vi på at forventningen blir oppfylt. Som du kan se, kan vi også passere i en timeout-parameter.

Den faktiske påstanden om testen er gjort inne i ferdigstillingsblokken av metoden under test, hvor vi også oppfyller forventningen vi definerte tidligere. Som et resultat, når testen kjøres, venter testen til forventningen er oppfylt eller det mislykkes hvis tidsavbrudd utløper og forventningen ikke oppfylles.

Ytelsestesting

Et annet tillegg til enhetstesting i Xcode 6 er evnen til å måle ytelsen til et stykke kode. Dette gjør det mulig for utviklere å få innblikk i den bestemte tidsinformasjonen til koden som blir testet.

Med ytelsestesting kan du svare på spørsmålet "Hva er gjennomsnittlig utførelsestid for dette koden?" Hvis det er en seksjon som er spesielt følsom for endringer når det gjelder tiden det tar å utføre, kan du bruke ytelsestesting til å måle hvor lang tid det tar å utføre.

Du kan også definere en baseline kjøretid. Dette betyr at hvis koden som blir testet, avviker vesentlig fra den grunnlinjen, svikter testen. Xcode vil gjentatte ganger utføre koden som blir testet og måle utførelsestiden. For å måle ytelsen til et stykke kode, bruk measureBlock: API som vist nedenfor.

- (void) testPerformanceReverseString NSString * originalString = @ "himynameisandy"; [self measureBlock: ^ [self.vcToTest reverseString: originalString]; ]; 

Klikk på informasjonsmeldingen som vises.

Angi eller rediger baseline-tiden for utførelse for ytelsestesten.

Konklusjon

I denne opplæringen har du lært hvordan du bruker Xcode til å lage enhetstester for å verifisere et iOS-program på en programmatisk og automatisert måte. Prøv det, enten på en eksisterende kodebase eller noe helt nytt. Enten du gjør en fullstendig forpliktelse til enhetstesting eller legger til noen tester her og der, legger du bare til verdi for prosjektet ditt ved å skrive mer sterkt verifisert programvare som er mindre tilbøyelig til å bryte med fremtidige endringer. Enhetstesting er bare begynnelsen på automatisert programtesting. Det er flere flere lag med testing du kan legge til i et iOS-program.