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.
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:
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.
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.
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
.
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.
Importer headerfilen til JumblifyViewController
klasse og legg til en eiendom av typen JumblifyViewController
til XCTestCase
underklasse.
@property (nonatomic) JumblifyViewController * vcToTest;
I Setup
metode, initialiser eiendommen som vist nedenfor.
- (void) setUp [super setUp]; self.vcToTest = [[JumblifyViewController alloc] init];
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.
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
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.
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.
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.
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.
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.
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.