Introducere în testarea iOS cu automatizare UI

Imaginați-vă că puteți scrie scenarii care interacționează automat cu aplicația dvs. iOS și puteți verifica rezultatele. Cu UI Automation puteți. UI Automation este un instrument oferit de Apple pentru a efectua un nivel mai înalt de testare pe aplicația dvs. iOS dincolo de orice realizabil cu XCTest.

1. White Box versus Black Box Testing

S-ar putea să fi auzit compararea testării casetei albe față de testarea cutie neagră cu privire la modul în care s-ar putea testa o bucată de software. Dacă nu sunteți familiarizați cu aceste concepte, permiteți-mi să vă explic cum funcționează.

Testarea cutie albă

Imaginați-vă că există o bucată de software care rulează într-o cutie. Cu testarea casetei albe, puteți vedea în interiorul casetei și uitați-vă la toate piesele greu de felul în care software-ul funcționează și apoi luați decizii educate cu privire la modul de testare a software-ului. Puteți avea, de asemenea, cârlige de nivel mai profund în software-ul de la testele pe care le scrieți.

Testul unității este testul cutie albă. Când se testează unitățile de testare, testerul are acces fin la codul testat. Testerul poate scrie, de fapt, teste care folosesc software-ul testat la nivel de metodă sau unitate.

În dezvoltarea de software iOS folosim XCTest cadru pentru a efectua acest tip de testare. Aruncati o privire la un alt tutorial pe care l-am scris despre inceput cu XCTest.

Black Box Testing

În testul cutie neagră, caseta este opacă. Testerul nu se vede în cutie. Testerul nu poate accesa și nu știe despre implementarea bazei de cod pentru a scrie teste. În schimb, testerul este forțat să utilizeze aplicația ca utilizator final, interacționând cu aplicația și așteptând răspunsul său, verificând rezultatele.

Există cel puțin două modalități de a executa acest tip de testare.

  • Un tester care efectuează în mod repetat și manual o serie de pași predefiniți și verifică vizual rezultatele.
  • Utilizați instrumente specializate pentru a testa aplicația cu API-uri care se comportă similar cu modul în care interacționează un om.

În dezvoltarea aplicațiilor iOS, Apple furnizează un instrument numit UI Automation pentru a efectua testarea cutiei negre.

2. Ce este automatizarea UI?? 

UI Automation este un instrument pe care Apple îl furnizează și întreține pentru testarea automată a aplicațiilor iOS. Testele sunt scrise în JavaScript, aderând la un API definit de Apple.

Testele de scriere pot fi făcute mai ușor, bazându-vă pe etichetele de accesibilitate pentru elementele interfeței utilizator din aplicația dvs. Nu vă faceți griji însă, dacă nu aveți aceste definiții, există alternative disponibile.

API-ul de automatizare UI nu are formatul tipic xUnit pentru scrierea testelor. O diferență cu testarea unității este că testerul trebuie să înregistreze manual succesul și eșecurile. UI Testele de automatizare sunt executate de la instrumentul Automation în cadrul Instrumente care vine cu instrumentele de dezvoltare ale Apple. Testele pot fi executate în Simulatorul iOS sau pe un dispozitiv fizic.

3. Scrierea testelor de automatizare UI

Pasul 1: Deschideți Proiectul de probă

Am actualizat proiectul de eșantion folosit în tutorialul anterior pe testarea iOS cu câteva elemente de interfață utilizator suplimentare care oferă câteva cârlige utile pentru adăugarea testelor de automatizare UI. Descărcați proiectul de la GitHub. Deschideți proiectul și rulați aplicația pentru a vă asigura că totul funcționează conform așteptărilor. Ar trebui să vedeți o interfață de utilizator similară celei indicate mai jos.


Înainte de a scrie orice teste, nu ezitați să încercați aplicația de probă pentru a vă familiariza cu funcționalitatea acesteia. Ca utilizator, puteți introduce text în câmpul de text și atingeți butonul pentru a vedea o etichetă pe ecran care afișează șirul inversat, introdus.

Pasul 2: Creați un test de automatizare UI

Acum că sunteți familiarizat cu aplicația de probă, este timpul să adăugați un test de automatizare UI. UI Automation este un instrument care poate fi găsit în Instrumente. Pentru a executa aplicația de probă din Instrumente, selectați Produs> Profil din meniul Xcode. Selectați Automatizare din lista de instrumente.


Fereastra principală Instruments se va deschide cu un singur instrument gata de funcționare, instrumentul Automation (instrumentul Automation execută casetele de testare UI Automation). De asemenea, veți vedea o zonă din jumătatea inferioară a ferestrei care arată ca un editor de text. Acesta este editorul de script-uri. Aici veți scrie testele de automatizare UI. Pentru acest prim test, urmați instrucțiunile de mai jos, adăugând fiecare rând la scriptul din editorul de script-uri.

Începeți prin a stoca o referință la câmpul de text într-o variabilă.

var inputField = target.frontMostApp (). mainWindow () textFields () ["Câmp de intrare"];

Setați valoarea câmpului de text.

inputField.setValue ( "hi“);

Verificați dacă valoarea a fost stabilită cu succes și, dacă a fost, treceți testul. Nu ați reușit testul dacă nu a fost așa.

dacă (inputField.value ()! = "hi") UIALogger.logFail ("Câmpul de intrare nu a putut fi setat cu șir!"); altceva UIALogger.logPass ("Câmpul de introducere a putut fi setat cu șir!");

În timp ce acest test este destul de banal, acesta are valoare. Tocmai am scris un test care testează prezența unui câmp text atunci când aplicația este lansată și care testează dacă un șir aleator poate fi setat ca valoarea câmpului de text. Dacă nu mă credeți, îndepărtați câmpul de text din panoul de prezentare și executați testul. Veți vedea că nu reușește.

Acest test demonstrează trei piese importante de teste de automatizare UI. În primul rând, vă arată cum să accesați un element simplu al interfeței de utilizator, câmpul de text. În mod specific, accesăm un dicționar al tuturor câmpurilor de text din vizualizarea de bază a aplicației prin target.frontMostApp (). MainWindow (). Câmpuri de text () și apoi găsim câmpul de text care ne interesează căutând unul cu cheie Câmp de introducere. Această cheie este de fapt eticheta de accesibilitate a câmpului de text. În acest caz, este definită în tabloul de bord. De asemenea, putem seta eticheta de accesibilitate în cod utilizând accessibilityLabel proprietate pe NSObject.

Accesul la fereastra principală a aplicației, aplicația frontală cea mai mare și ținta sunt frecvente la lucrul cu UI Automation. Vă voi arăta cum să faceți acest lucru mai ușor și mai puțin verbose mai târziu în acest tutorial.

În al doilea rând, acest lucru vă arată că puteți interacționa cu elementele interfeței utilizator pe ecran. În acest caz, setăm valoarea câmpului de text, imită utilizatorul care interacționează cu aplicația introducând text în câmpul de text.

În al treilea rând, exemplul arată, de asemenea, o tehnică pentru a verifica ce se întâmplă în aplicație. Dacă valoarea este setată cu succes, testul trece. Dacă valoarea nu este setată, testul nu reușește.

Pasul 3: Salvarea testelor

În timp ce scrierea testelor în editorul script este convenabilă, devine repede greoaie și dificil de întreținut. Dacă renunțați la Instrumente, toate modificările nesalvate sunt eliminate. Trebuie să salvăm testele pe care le scriem. Pur și simplu copiați și inserați testul într-un nou document în editorul dvs. de text preferat și salvați-l. Puteți găsi testele create în acest tutorial în exemplul de proiect de sub Jumblify / JumblifyTests / AutomationTests.js.

Pentru a executa testul, selectați fila din mijloc din panoul din partea dreaptă, alături de editorul de script și selectați Adăugați> Importați.


Veți fi invitat să selectați scriptul de importat. Navigați la scriptul salvat și importați-l. Puteți schimba în continuare scriptul în editorul de script-uri. Orice modificări vor fi salvate automat în fișierul extern pe care l-ați creat.

Pasul 4: Atingerea unui buton

Să actualizăm testul pentru a testa interacțiunea cu butonul. Testul nostru adaugă deja text în câmpul de text, astfel că trebuie doar să adăugăm codul pentru atingerea butonului. Să analizăm mai întâi modul de găsire a butonului în vizualizare, astfel încât să fie posibilă accesarea acestuia. Există cel puțin trei modalități de a realiza acest lucru și fiecare abordare are compromisuri.

Abordarea 1

Putem atinge programatic o coordonată (X, Y) pe ecran. Facem acest lucru cu următorul rând de cod:

target.tap (x: 8.00, y: 50.00);

Desigur, nu am nici o idee dacă acestea sunt chiar coordonatele butonului de pe ecran și nu mă voi preocupa de asta, deoarece această abordare nu este instrumentul potrivit pentru această slujbă. Numai o menționez, așa că știi că există. Utilizarea Atingeți metoda pe ţintă pentru a atinge un buton este predispusă la erori, deoarece acest buton nu este întotdeauna la acea coordonată specifică.

Abordarea 2

De asemenea, este posibil să găsiți butonul căutând o serie de butoane din fereastra principală, similar cu modul în care am accesat câmpul de text din primul test. În loc să accesăm butonul direct cu ajutorul unei chei, putem extrage o serie de butoane din fereastra principală și codul hard, un indice matrice pentru a obține o referință la buton.

target.frontMostApp () MainWindow () butoane () [0] .tap ()..;

Această abordare este puțin mai bună. Nu codificăm greu o coordonată, dar codificăm greu un indice matrice pentru a găsi butonul. Dacă se întâmplă să adăugați un alt buton pe pagină, acest lucru poate duce la ruperea accidentală a acestui test.

Abordarea 3

Acest lucru mă aduce la cel de-al treilea mod de a găsi butonul din pagină utilizând etichetele de accesibilitate. Utilizând o etichetă de accesibilitate, putem accesa direct butonul care ne-a plăcut că vom găsi un obiect într-un dicționar utilizând o cheie.

Butoanele principale () Butoane () [Butonul "Jumblify"] atingeți ();

Cu toate acestea, dacă adăugați linia de mai sus în script și executați-o, veți primi o eroare.


Acest lucru se datorează faptului că nu am definit încă eticheta de accesibilitate pentru buton. Pentru a face acest lucru, flip peste Xcode și deschideți storyboard-ul proiectului. Găsiți butonul din vizualizare și deschideți Inspectorul de identitate pe dreapta (Vizualizați> Utilitare> Inspector de identitate). Asigura-te ca Accesibilitate este activată și setată Eticheta pentru butonul Faceți clic pe Button.


Pentru a executa din nou testul, va trebui să rulați aplicația din Xcode selectând Produs > Alerga după care selectați din nou aplicația Produs > Profil. Aceasta conduce testele și fiecare test trebuie să treacă acum.

Pasul 5: Verificați șirul Jumbled 

Așa cum am menționat mai devreme, aplicația noastră are un șir de text ca intrare și, atunci când utilizatorul pune butonul, afișează șirul inversat. Trebuie să adăugăm încă un test pentru a verifica dacă șirul de intrare este corect inversat. Pentru a verifica dacă UILabel este populat cu șirul corect, trebuie să ne dăm seama cum să facem referire la UILabel și verificați șirul pe care îl afișează. Aceasta este o problemă obișnuită atunci când se scriu teste de automatizare, și anume, cum se face referire la un element din aplicație pentru a face o afirmație despre el.

Există o metodă pentru aproape fiecare obiect din API de automatizare UI, logElementTree. Această metodă înregistrează elementele imbricate ale unui element dat. Acest lucru este foarte util pentru a înțelege ierarhia elementelor din aplicație și vă ajută să aflați cum să vizați un anumit element.

Să vedem cum funcționează acest lucru prin logarea arborelui element al ferestrei principale. Uitați-vă la următoarea linie de cod.

target.frontMostApp () MainWindow () logElementTree ()..;

Adăugarea acestei linii în scriptul de test are ca rezultat următoarea ieșire:


După cum puteți vedea, există a UIAStaticText subelement al UIAWindow și puteți vedea, de asemenea, că are un nume de ih, care, de asemenea, se întâmplă să fie șirul inversat pe care trebuie să îl verificăm. Acum, pentru a finaliza testul nostru, trebuie doar să adăugăm codul pentru a accesa acest element și a verifica dacă acesta este prezent.

De ce trebuie doar să verificăm dacă UIAStaticText element este prezent?Deoarece numele elementului este șirul invers al șirului de intrare, verificarea prezenței acestuia confirmă faptul că șirul a fost inversat corect. Dacă elementul nu există atunci când se face referire pe nume - șirul inversat - atunci înseamnă că șirul nu a fost corect inversat.

var stringResult = target.frontMostApp (). mainWindow () staticTexts () ["ih"]; if (! stringResult.isValid ()) UIALogger.logFail ("Textul de ieșire nu a fost setat cu șirul invers inversat!"); altul UIALogger.logPass ("Textul de ieșire a fost setat cu șirul invers inversat!");

4. Zgârierea suprafeței

Există atât de multe alte modalități prin care un utilizator final poate interacționa cu un dispozitiv iOS în timp ce utilizează aplicația. Aceasta înseamnă că există multe alte modalități prin care puteți utiliza UI Automation pentru a simula aceste interacțiuni. Mai degrabă decât să încercați să capturați o listă cuprinzătoare a acestor interacțiuni, vă îndrumăm către documentația de referință pentru automatizarea UI.

Pentru fiecare tip de obiect cu care puteți interacționa, puteți vedea lista metodelor disponibile pentru obiectul respectiv. Unele metode sunt pentru recuperarea atributelor despre obiect, în timp ce altele sunt pentru simularea interacțiunii touch, cum ar fi flickInsideWithOptions pe UIAWindow.

Înregistrarea unei sesiuni

Pe măsură ce încercați să testați aplicații din ce în ce mai complicate cu UI Automation, veți observa uneori că este destul de obositor să utilizați în mod repetat logElementTree pentru a găsi elementul pe care îl căutați. Acest lucru devine, de asemenea, obositor și complex pentru aplicații cu o ierarhizare sau navigare complexă. În aceste cazuri, puteți utiliza o altă caracteristică a Instrumente pentru a înregistra un set de interacțiuni cu utilizatorul. Ceea ce este mai răcoros este faptul că Instrumentele generează codul JavaScript UI Automation necesar pentru a reproduce interacțiunile înregistrate. Iată cum puteți să-l încercați singur.

În Instrumente și cu instrumentul Automatizare selectat, căutați butonul de înregistrare din partea inferioară a ferestrei.


Dacă faceți clic pe butonul de înregistrare, Instruments va începe o sesiune de înregistrare după cum se arată în imaginea de mai jos.


Instrumentele vor lansa aplicația dvs. în Simulatorul iOS și vei putea să interacționezi cu acesta. Instrumentele vor genera un script bazat pe interacțiunile dvs. în timp real. Incearca. Rotiți simulatorul iOS, atingeți locații aleatorii, efectuați un gest de glisare etc. Este o modalitate foarte utilă de a ajuta la explorarea posibilităților de automatizare UI.

Evitarea unei baze de cod monolitic

Așa cum probabil veți prevedea, dacă vom continua să adăugăm mai multe teste la fișierul test pe care l-am creat în aceeași metodă, va deveni rapid greu de întreținut. Ce putem face pentru a împiedica acest lucru. În testele mele, fac două lucruri pentru a rezolva această problemă:

  • Un test pentru o funcție: Aceasta implică faptul că testele pe care le scriem trebuie să se concentreze asupra unei anumite funcționalități. Îi dau chiar și un nume adecvat, cum ar fi testEmptyInputField.
  • Teste legate de grup într-un singur dosar: De asemenea, grup de teste conexe în același fișier. Aceasta menține codul într-un singur fișier ușor de gestionat. Acest lucru facilitează, de asemenea, testarea pieselor separate de funcționalitate prin executarea testelor într-un anumit fișier. În plus, puteți crea un script master în care să apelați funcțiile sau testele pe care le-ați grupat în alte fișiere de testare.

În următorul fragment de cod, importem un fișier JavaScript și acest lucru face ca funcțiile din acel fișier JavaScript să fie disponibile pentru noi.

#import "OtherTests.js"

Concluzie

În acest tutorial, ați învățat valoarea testelor la nivel superior și cum poate automatizarea UI să ajute la umplerea acestui decalaj. Este un alt instrument din caseta de instrumente pentru a vă asigura că livrați aplicații fiabile și robuste.

Referințe

UI Automation JavaScript referință

Cod