Introducere în testarea pe iOS

Nimeni nu vrea să vândă software-uri buggy. Asigurați-vă că lansați o aplicație mobilă de cea mai înaltă calitate necesită mult mai mult decât un proces de asigurare a calității manuale de calitate. Dispozitivele noi și sistemele de operare sunt difuzate publicului în fiecare an. Aceasta înseamnă că există o combinație tot mai mare de dimensiuni de ecran și versiuni ale sistemului de operare pe care trebuie să testați aplicația dvs. mobilă. Nu numai că ar fi extrem de consumatoare de timp, dar încercarea de a testa aplicația dvs. iOS prin testarea manuală neglijează o întreagă piesă a procesului de inginerie software modernă, testul automatizat de asigurare a calității.

În lumea de astăzi, există multe instrumente disponibile care pot fi utilizate pentru a testa automat software-ul pe care îl scrieți. Unele dintre aceste instrumente sunt menținute printr-un model open source, dar există și un set de bază furnizat de Apple. Cu fiecare lansare nouă a SDK-ului iOS, Apple a continuat să își arate angajamentul de a îmbunătăți instrumentele disponibile pentru dezvoltatori pentru a testa codul pe care îl scriu. Pentru dezvoltatorul de iOS, care este nou pentru testarea automată și interesat să înceapă, instrumentele Apple sunt un bun loc pentru a începe.

1. Apple furnizează instrumente utile

Acest tutorial va oferi instrucțiuni pentru utilizarea unui instrument pe care Apple îl oferă pentru testarea automată, XCTest. XCTest este cadrul de testare a unităților Apple. Testarea unității este tipul de testare automată care verifică codul la cel mai scăzut nivel. Scrieți codul Objective-C care apelează metode din codul "de producție" și verificați dacă codul testat face exact ceea ce intenționează să facă. Sunt setate corect variabilele? Valoarea returnată este corectă?

Testele scrise cu cadrul XCTest pot fi executate în repetate rânduri în raport cu codul aplicației dvs. pentru a vă ajuta să câștigați încrederea că creați un produs fără bug-uri, deoarece noile modificări ale codului nu întrerup funcționalitatea existentă.
În mod implicit, fiecare nou proiect Xcode este creat cu un bun punct de plecare pentru testarea unităților de testare. Acestea includ trei lucruri:

  • o țintă separată pentru testele dvs.
  • un grup pentru clasele dvs. de test
  • un exemplu de test


Să săpăm structura unui test de unitate iOS. Un test de unitate individuală este reprezentat ca o singură metodă în cadrul oricărei subclase a lui XCTestCase unde se întoarce metoda vid, nu ia parametri, iar numele metodei începe cu Test.

- (void) testSomething 

Din fericire, Xcode face ușor crearea cazurilor de testare. Cu noi proiecte Xcode, este creat un caz test inițial pentru tine într-un grup de fișiere separat al cărui nume este sufixat de cuvânt teste.

2. Crearea primului test pentru unitatea iOS

Am creat un exemplu de proiect care poate fi folosit ca referință pentru exemplele oferite în acest tutorial. Descărcați proiectul de la GitHub și deschideți-l în Xcode.

Pasul 1: Creați clasa cazurilor de testare

În proba de proiect, puteți găsi grupul de teste în folderul numit JumblifyTests.

Pentru a crea primul test, faceți clic dreapta pe grupul de fișiere, JumblifyTests, și selectați Fișier nou. Alege Clasa cazurilor de test de la iOS> Sursă și dați un nou subclasă un nume.

Conceptul tipic de numire este de a numi cazul de testare astfel încât acesta este numele clasei corespunzătoare testate, sufixată cu teste. Din moment ce vom testa JumblifyViewController clasa, numele XCTestCase subclasă JumblifyViewControllerTests.

Pasul 2: Scoateți codul de boilerplate

În brandul nou XCTestCase subclasa, veți vedea patru metode. Două dintre acestea sunt testări. Puteți să identificați care sunt acestea? Rețineți că numele metodelor de încercare încep cu cuvântul "test".

Dacă nu ați dat seama, metodele de testare create în mod implicit sunt testExample și testPerformanceExample.

Ștergeți ambele teste, pentru că ne vom scrie de la zero. Celelalte două metode, înființat și dărâma, sunt suprascrise de superclaj, XCTestCase. Ele sunt unice în acest sens înființat și dărâma sunt numite înainte și după fiecare metodă de testare invocată respectiv. Sunt locuri utile pentru a centraliza codul care ar trebui să fie executat înainte sau după fiecare metodă de testare. Sarcini precum inițializarea sau curățarea comună merg aici.

Pasul 3: Conectați-vă testul la testul dvs.

Importați fișierul antet al JumblifyViewController și adăugați o proprietate de tip JumblifyViewController la XCTestCase subclasă.

@property (nonatomic) JumblifyViewController * vcToTest;

În înființat , inițializați proprietatea după cum se arată mai jos.

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

Pasul 4: Scrieți un test

Acum vom scrie un test pentru a testa reverseString: metodă a JumblifyViewController clasă.

Creați o metodă de testare care utilizează instanța vcToTest obiecte pentru a testa reverseString: metodă. În această metodă de testare, creăm un NSString obiecte și transmiteți-le la controlerul de vizualizare reverseString: metodă. Este o convenție comună de a da testului dvs. un nume semnificativ pentru a clarifica ceea ce testul testează.

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

În acest moment, nu am făcut încă nimic util, pentru că nu am testat reverseString: metoda încă. Ceea ce trebuie să facem este să comparăm rezultatele producției reverseString: cu ceea ce ne așteptăm ca producția să fie.

 XCTAssertEqualObjects este parte a cadrului XCTest. Cadrul XCTest oferă multe alte metode pentru a face afirmații despre starea aplicației, cum ar fi egalitatea variabilă sau rezultatele expresiei booleene. În acest caz, am afirmat că două obiecte trebuie să fie egale. Dacă sunt, testul trece și, dacă nu, testul eșuează. Uitați-vă la documentația Apple pentru o listă cuprinzătoare de afirmații furnizate de cadrul XCTest.

- (void) testReverseString NSString * originalString = @ "himynameisandy"; NSString * reversedString = [auto.vcToTest reverseString: originalString]; NSString * așteptatăReversedString = @ "ydnasiemanymih"; XCTAssertEqualObjects (așteptatReversedString, reversedString, @ "Șirul inversat nu se potrivește cu inversarea așteptată");

Dacă încercați să compilați codul în acest moment, veți observa un avertisment atunci când încercați să apelați reverseString: din cazul testului. reverseString: metoda este o metodă privată a JumblifyViewController clasă. Aceasta înseamnă că alte obiecte nu pot invoca această metodă, deoarece nu este definită în fișierul antet al JumblifyViewController clasă.

În timp ce scriem codul testabil este o mantra pe care mulți dezvoltatori o urmează, nu vrem să modificăm în mod inutil codul nostru testat. Dar cum îl numim pe cel privat reverseString: metodă a JumblifyViewController clasa în testele noastre? Am putea adăuga o definiție publică a reverseString: la fișierul antet al fișierului JumblifyViewController clasa, dar care sparge modelul de încapsulare.

Pasul 5: Adăugarea unei categorii private

O soluție este să adăugați o categorie privată pe JumblifyViewController clasa pentru a expune reverseString: metodă. Adăugăm această categorie la XCTestCase subclasa, ceea ce înseamnă că este disponibil numai în acea clasă. Prin adăugarea acestei categorii, cazul de testare se va compila fără avertismente sau erori.

@interface JumblifyViewController (Test) - (NSString *) reverseString: (NSString *) stringToReverse; @Sfârșit

Pasul 6: Rulați testul

Să facem testele pentru a ne asigura că trec. Există mai multe modalități de a rula testele unității pentru o aplicație iOS. Sunt un băiat de scurtătură de la tastatură, astfel încât cea mai utilizată tehnică pentru rularea testelor de unitate pentru aplicația mea este prin apăsare Command-U. Această comandă rapidă de la tastatură va executa toate testele pentru aplicația dvs. De asemenea, puteți efectua aceeași acțiune selectând Test de la Produs meniul.

Pe măsura creșterii suitei dvs. de testare sau dacă vă recomandăm să implementați dezvoltarea testată, veți descoperi că rularea suitei de testare poate deveni prea consumatoare de timp. Sau ar putea fi în calea fluxului de lucru. O comandă foarte utilă, îngropată în meniul lui Xcode, că m-am îndrăgostit e Command-Option-control-U. Această comandă rapidă declanșează o comandă care execută testul în care se află cursorul dvs. Odată ce ați testat și finalizat suita de testare, trebuie să rulați întotdeauna întreaga suită de testare. Rularea unui test individual este utilă pe măsură ce scrieți un nou test de testare sau când depanați un test care nu reușește.

Comanda pentru a rula un test este completată de Command-Option-Control-G, care reia ultima încercare. Aceasta poate fi întreaga suită de testare sau doar cel mai recent test la care lucrați. Este, de asemenea, util în cazul în care ați navigat departe de orice test pe care lucrați și sunteți încă în proces de depanare.

Pasul 7: Revizuirea rezultatelor

Puteți vedea rezultatele testelor în câteva locuri. Unul dintre acele locuri este Test Navigator pe dreapta.

O altă opțiune este de a privi jgheabul Editorul sursei.

În oricare dintre aceste două locuri, făcând clic pe diamantul verde cu marcajul alb va relua acel test. În cazul unui test eșuat, veți vedea un diamant roșu cu o cruce albă în centru. Dacă faceți clic pe acesta, veți relua și acel test special.

3. Noi în Xcode 6

Xcode 6 a introdus două noi adăugări interesante pentru testarea unităților pe iOS și OS X, testarea funcționalității asincrone și măsurarea performanței unei anumite bucăți de cod.

Testarea asincronă

Înainte de Xcode 6, nu a existat o modalitate bună de a codifica codul asincron al unității. Dacă testul dvs. de unitate a numit o metodă care conține logica asincronă, nu ați putut verifica logica asincronă. Testul s-ar termina înainte ca logica asincronă din metoda testată să fie executată.

Pentru a testa codul asincron, Apple a introdus un API care permite dezvoltatorilor să definească o așteptare care trebuie îndeplinită pentru ca testul să se finalizeze cu succes. Fluxul este după cum urmează: definirea unei așteptări, așteptarea așteptării care trebuie îndeplinită și îndeplinirea așteptărilor când codul asincron a terminat executarea. Uitați-vă la exemplul de mai jos pentru clarificare.

- (void) testDoSomethingThatTakesSomeTime XCTestExpectation * completionExpectation = [așteptarea de sine cu descrierea: @ "Metoda lungă"]; [auto.vcToTest doSomethingThatTakesSomeTimesWithCompletionBlock: ^ (rezultat NSString *) XCTAssertEqualObjects (@ "rezultat", rezultat, @ "Rezultatul nu a fost corect!"); [îndeplinireaExpectării îndeplinesc]; ]; [așteptați de sine pentruExpectăriWithTimeout: manipulator 5.0: nil]; 

În acest exemplu, încercăm doSomethingThatTakesSomeTimesWithCompletionBlock metodă. Vrem să cuprindem succesul sau eșecul testului nostru asupra valorii returnate în blocul de completare numit de metoda testată.

Pentru a face acest lucru, definim o așteptare la începutul metodei de testare. La sfârșitul metodei de testare, așteptăm ca așteptările să fie îndeplinite. După cum puteți vedea, putem trece și un parametru timeout.

Afirmația reală a testului se face în interiorul blocului de completare a metodei testate, în care îndeplinim și așteptările pe care le-am definit mai devreme. Ca urmare, atunci când testul este rulat, testul așteaptă până când așteptarea este îndeplinită sau nu reușește dacă expirarea timpului de expirare și așteptările nu sunt îndeplinite.

Test de performanta

O altă adăugire la testarea unităților în Xcode 6 este capacitatea de a măsura performanța unei bucăți de cod. Acest lucru permite dezvoltatorilor să obțină o perspectivă asupra informațiilor specifice de sincronizare a codului care este testat.

Cu testarea performanțelor, puteți răspunde la întrebarea "Care este timpul mediu de execuție pentru această bucată de cod?" Dacă există o secțiune care este deosebit de sensibilă la schimbări în ceea ce privește timpul necesar pentru a fi executat, atunci puteți utiliza testarea performanței pentru a măsura timpul necesar pentru a executa.

De asemenea, puteți defini un timp de execuție de bază. Aceasta înseamnă că, dacă codul testat se abate semnificativ de la linia de bază, testul eșuează. Xcode va executa în mod repetat codul care este testat și va măsura timpul de execuție. Pentru a măsura performanța unei bucăți de cod, utilizați measureBlock: API după cum se arată mai jos.

- (void) testPerformanceReverseString NSString * originalString = @ "himynameisandy"; [auto măsuraBlock: ^ [auto.vcToTest reverseString: originalString]; ]; 

Faceți clic pe mesajul informativ care apare.

Setați sau editați timpul de execuție al liniei de bază pentru testul de performanță.

Concluzie

În acest tutorial, ați învățat cum să utilizați Xcode pentru a crea teste unitare pentru a verifica o aplicație iOS într-un mod programatic și automatizat. Faceți o încercare, fie pe o bază de cod existent, fie pe ceva nou. Indiferent dacă vă angajați pe deplin la testarea unităților sau adăugați câteva teste aici și acolo, adăugați valoare proiectului dvs. doar prin scrierea de software mai puternic verificat, care este mai puțin predispus la ruperea schimbărilor viitoare. Testarea unităților este doar începutul testelor software automatizate. Există câteva straturi suplimentare de testare pe care le puteți adăuga la o aplicație iOS.

Cod