Sådan testes ved hjælp af forfalskede data på iOS

For at levere software af høj kvalitet og undgå regression er implementering af enhedsprøvning et must for enhver iOS-applikation.
Spottende objekter er en teknik i enhedstestning, der skaber falske objekter ved at bruge de samme API'er som de rigtige.
Denne artikel er trådløs for at give dig den bedste praksis for, hvordan du bruger falske data og skriver enhedsprøver til de mest forekommende scenarier på iOS-apps.

Når vi skriver enhedstests, skal vi altid undgå at ændre reelle data for applikationsmålet og i stedet bruge falske data bare til testformål.

De følgende dele diskuterer, hvordan man skriver tests ved hjælp af falske data til almindeligt anvendte iOS API-er.

Brugerindstillinger

I softwareudvikling er det altid en god praksis at reducere objekternes afhængighed. Afhængigheder i bedste tilfælde bør indsprøjtes i de klasser, der bruger dem.

Men hvis vi kontrollerer de virkelige iOS-udviklingsscenarier, bruger næsten hvert projekt UserDefaults ved at kalde dets API direkte til lagring eller hentning af data.

Derfor vil vi forsøge at tilbyde en praktisk løsning til test af UserDefaultsrather end at abstrahere dens API med protokoller.

Vi kan oprette to nye funktioner på UserDefaults

Det er altid en god praksis at ikke ændre applikationsdata fra enhedstestmål, så vi bør derfor skabe et andet sted til at gemme brugerdata til vores testmål.

I dette tilfælde initialiserer vi et nyt objekt med UserDefaults med suiteName - testDefaults, at det er helt uafhængigt af standard UserDefaults.

Lad os prøve at skrive en simpel test, der bruger UserDefaults

Da disse data grundlæggende kun bruges til test, bør vi undgå at lade disse data hænge i vores applikationsfiler, derfor opretter vi en funktion, der er ansvarlig for at droppe denne lagring, når vi er færdig med testen.

Det bedste sted at rense disse data vil naturligvis være tearDown-funktionen i vores enhedstestklasse.

Singelton-objekter

Singletons-objekter bruges meget på iOS på mange API'er, vi kan finde dem på NSFileManager, NSApplication, UIApplication og mange andre steder.

At vide, hvordan man tester singletons, er en nyttig ting at vide for iOS-udviklere.

I vores eksempel vil vi bruge iAd-rammen for apple. Vi opretter en fil for at få et lokalt JSON-svar i stedet for reelle data om anmodning om annonces attribution.

En dejlig funktion i iOS er, at udvidelser i hurtig tillader os ikke kun at tilføje nye funktioner til et foruddefineret API, men også gøre dem i overensstemmelse med vores egne brugerdefinerede protokoller.

Lad os definere en AnnonceringClient-protokol

Derefter overholder vi denne protokol ved både standard ADClient og vores falske reklameklient som at følge

Vi ændrer derefter afhængighed til begge

privat var adClient: AdvertisingClient = ADClient.shared ()

eller

privat var adClient: AnnonceringClient = MockAdClient ()

og brug det som følger

På denne måde kan vi nemt beslutte, hvornår vi skal bruge rigtige data, og hvornår de testes, afhængigt af om vi tester enhed eller ringer API fra vores live applikationsmål.

Kernedata

Kernedata bruges stadig meget i iOS til cache-data. Test af kernedataenheder kan være vanskeligt. Nedenfor forklarer vi en god praksis med både organisering af Core Data Services og Faking Data.

Generelt er det i de fleste tilfælde altid en god ting at oprette en serviceklasse, der er ansvarlig for at hente og skrive specifikke data i databasen, snarere end at bruge kernedatakode overalt i projektet.

Dette har hovedsageligt to fordele:

  • Det frigører dig fra den underliggende database, der bruges, hvis du i fremtiden vil erstatte kernedata med en anden database, bliver du kun nødt til at foretage ændringer i en klasse.
  • Ved at gøre dette kan vi nemt beslutte, hvilken CoreDataStack vil blive brugt eller enhver anden opsætning, som vi muligvis har brug for inden for andre rammer.

Vi opretter en CoreDataStack-protokol, og derefter overholder to CoreDataStacksthat denne protokol, en MainCoreDataStack og en MockCoreDataStack.

Vores DatabaseService kan derefter initialiseres af en af ​​dem, afhængigt af om vi bruger den på vores applikationsmål eller på vores Unit Testing-mål.

Vores vigtigste kernedatastakke har en standardopsætning som følger

Når enhedstesting altid skal vi undgå at ændre status for nuværende 'rigtige' objekter, når vi tester dem.

Så når vi ønsker at oprette falske kernedataenheder, skal vi have en separat vedvarende butik og bruge konfiguration i lagerhukommelsestypen, så de foretagne ændringer ikke gemmes på disken, og de vil blive adskilt fuldstændigt fra aktuelt vedvarende data.

Vi vil nu være i stand til at oprette vores databasetjeneste, der som standard initialiseres med MainCoreDataStack.

Og i vores testklasse kan vi initialisere det med den falske datastakke

Vi kan nu skrive et par enkle test som følger:

Ved at bruge denne tilgang kan vi nemt teste vores DatabaseService uden at påvirke nogen af ​​de data, der er gemt af applikationsmålet.

Netværksanmodninger

Når vi tester netværkslag, kan vi bruge den protokolorienterede tilgang til at oprette en protokol og konformere den med både reel NetworkService og MockNetworkService og derefter injicere afhængigheder ved enten at bruge reel eller hånet service.

I denne artikel bruger vi dog et rigtig flot open source-bibliotek kaldet OHHTTPStubs, der vil håndtere hån og stubbing endnu bedre.

Den gode ting ved dette bibliotek er, at det fungerer godt med det berømte iOS-netværksbibliotek Alamofire.

Stubbing Network-anmodning er virkelig let med OHHTTPStubs, du kan erstatte ethvert svar for en bestemt sti eller vært ved at give et tilpasset svar med en ordbog.

Efter dette vil hver anmodning, der går fra appen til følgende URL, returnere vores tilpassede svar i stedet.

lad opgaverURL = URL (streng: “https://jsonplaceholder.typicode.com/todos”)!

Det, der også er virkelig cool ved brugerdefinerede svar, er, at du nemt kan teste, om fejl- og kantsager håndteres korrekt ved blot at returnere en fejl i svaret.

At manuelt opbygge ordbogen til svar er en fantastisk funktion, men når vi vil returnere store JSON-data med masser af egenskaber, kan det blive rodet og næppe vedligeholdeligt i vores testklasser.

I disse tilfælde kan vi bruge en JSON-fil til at stoppe svaret som følgende.

Hver gang vores app sender anmodningen, får vi svaret fra filen myResponse.json, som vi gemte i vores filer.

Vi skal dog huske at undgå at gemme følsomme oplysninger i disse JSON-filer, fordi hvis vi sender disse filer sammen med applikationen, kan de let vises.

Du kan tjekke min artikel om sikkerhedsemnet for mere.

Afslutningsvis

Enhedstest af vores applikation er et must, hvis vi ønsker at undgå regression så meget som muligt og også forsøge at levere en fejlfri applikation.

I denne artikel har vi drøftet, hvordan man leverer test for almindelige sager, der opstår under iOS-udvikling.

Vi diskuterede, hvordan man tester UserDefaults, Singeltons, Core Data og Network Request.

Hvis du kunne lide denne artikel, skal du sørge for at klappe for at vise din støtte.

Følg mig for at se mange flere artikler, der kan tage dine iOS-udviklerværdigheder til et næste niveau.

Hvis du har spørgsmål eller kommentarer, er du velkommen til at lægge en note her eller maile mig til [email protected]