Introduktion til iOS-testning med UI Automation

apr 17, 2021
admin

Forestil dig, at du kan skrive scripts, der automatisk interagerer med din iOS-applikation, og at du kan verificere resultaterne. Med UI Automation kan du det. UI Automation er et værktøj leveret af Apple til at udføre et højere niveau af testning af din iOS-applikation end noget, der kan opnås med XCTest.

1. White Box versus Black Box-testning

Du har måske hørt sammenligningen af white box-testning versus black box-testning med hensyn til, hvordan man kan teste et stykke software. Hvis du ikke er bekendt med disse begreber, så lad mig forklare, hvordan de fungerer.

White Box Testing

Forestil dig, at der er et stykke software, der kører inde i en boks. Med white box-testning kan du se ind i boksen og se på alle de små detaljer i, hvordan softwaren fungerer, og derefter træffe kvalificerede beslutninger om, hvordan softwaren skal testes. Du kan også få dybere indblik i softwaren fra de tests, du skriver.

Unit testing er white box testing. Når man skriver enhedstests, har testeren finkornet adgang til den kode, der skal testes. Testeren kan faktisk skrive tests, der udnytter den testede software på metode- eller enhedsniveau.

I iOS-softwareudvikling bruger vi XCTest-rammen til at udføre denne type test. Tag et kig på en anden tutorial, som jeg har skrevet om at komme i gang med XCTest.

Black Box Testing

I black box testing er boksen uigennemsigtig. Testeren kan ikke se inde i boksen. Testeren kan ikke få adgang til og kender ikke til implementeringen af kodebasen for at skrive tests. I stedet er testeren tvunget til at bruge applikationen som en slutbruger ville gøre det ved at interagere med applikationen og vente på dens svar og verificere resultaterne.

Der er mindst to måder at udføre denne type test på.

  • En tester, der gentagne gange og manuelt udfører en række foruddefinerede trin og visuelt verificerer resultaterne.
  • Brug specialiserede værktøjer til at teste applikationen med API’er, der opfører sig på samme måde, som et menneske interagerer.

I iOS applikationsudvikling tilbyder Apple et værktøj kaldet UI Automation til at udføre black box-testning.

2. Hvad er UI Automation?

UI Automation er et værktøj, som Apple leverer og vedligeholder til automatiseret testning af iOS-applikationer på et højere niveau. Testene skrives i JavaScript og overholder et API, der er defineret af Apple.

Det kan gøres lettere at skrive test ved at stole på tilgængelighedsmærker for brugergrænsefladeelementer i din applikation. Men bare rolig, hvis du ikke har disse defineret, er der alternativer til rådighed.

UI Automation API mangler det typiske xUnit-baserede format til at skrive tests. En forskel i forhold til enhedstest er, at testeren manuelt skal logge succes og fiaskoer. UI Automation-tests køres fra Automation-instrumentet i Instruments-værktøjet, der følger med Apples udviklerværktøjer. Testene kan køres i iOS-simulatoren eller på en fysisk enhed.

3. Skrivning af UI Automation-tests

Stræk 1: Åbn eksempelprojektet

Jeg har opdateret det eksempelprojekt, der blev brugt i den tidligere vejledning om iOS-test, med nogle ekstra brugergrænsefladeelementer, der giver nogle nyttige kroge til tilføjelse af UI Automation-tests. Download projektet fra GitHub. Åbn projektet, og kør programmet for at sikre, at alt fungerer som forventet. Du bør se en brugergrænseflade, der ligner den nedenfor viste.

Hvor vi skriver nogen tests, er du velkommen til at prøve prøve prøveapplikationen for at blive fortrolig med dens funktionalitet. Som bruger kan du indtaste tekst i tekstfeltet og trykke på knappen for at se en etiket på skærmen, der viser den omvendte, indtastede streng.

Stræk 2: Opret en UI Automation Test

Nu, hvor du er fortrolig med prøveprogrammet, er det tid til at tilføje en UI Automation-test. UI Automation er et værktøj, der kan findes i Instruments. Hvis du vil køre prøveprogrammet i Instruments, skal du vælge Produkt > Profil i Xcode-menuen. Vælg Automation på listen over værktøjer.

Det vigtigste Instruments-vindue åbnes med et enkelt instrument klar til at køre, nemlig Automation-instrumentet (Automation-instrumentet udfører UI Automation-testsager). Du vil også se et område i den nederste halvdel af vinduet, der ligner en teksteditor. Dette er scripteditoren. Det er her, du skal skrive dine UI Automation-tests. For denne første test skal du følge nedenstående instruktioner og tilføje hver linje til scriptet i scripteditoren.

Start med at gemme en reference til tekstfeltet i en variabel.

var inputField = target.frontMostApp().mainWindow().textFields();

Sæt tekstfeltets værdi.

inputField.setValue("hi");

Kontroller, at værdien blev sat med succes, og hvis det var tilfældet, skal du bestå testen. Fail testen, hvis den ikke blev det.

Selv om denne test er ret triviel, har den dog en værdi. Vi har netop skrevet en test, der tester tilstedeværelsen af et tekstfelt, når programmet startes, og som tester, om en tilfældig streng kan indstilles som tekstfeltets værdi. Hvis du ikke tror mig, så fjern tekstfeltet fra storyboardet, og kør testen. Du vil se, at den fejler.

Denne test demonstrerer tre vigtige dele af at skrive UI Automation-tests. For det første viser den, hvordan du får adgang til et simpelt brugergrænsefladeelement, nemlig tekstfeltet. Helt konkret får vi adgang til en ordbog over alle tekstfelter på grundvisningen i programmet via target.frontMostApp().mainWindow().textFields(), og vi finder derefter det tekstfelt, vi er interesseret i, ved at lede efter det med nøglen Input Field. Denne nøgle er faktisk tekstfeltets tilgængelighedsetiket. I dette tilfælde er den defineret i storyboardet. Vi kan også angive tilgængelighedsetiketten i kode ved hjælp af accessibilityLabel-egenskaben på NSObject.

Accessing the application’s main window, the front most application, and the target are common when working with UI Automation. Jeg viser dig, hvordan du kan gøre dette nemmere og mindre omstændeligt senere i denne vejledning.

For det andet viser dette dig, at du kan interagere med brugergrænsefladeelementer på skærmen. I dette tilfælde indstiller vi tekstfeltets værdi og efterligner dermed brugeren, der interagerer med programmet ved at indtaste tekst i tekstfeltet.

For det tredje viser eksemplet også en teknik til at verificere, hvad der sker i programmet. Hvis det lykkes at indstille værdien, er testen bestået. Hvis værdien ikke er indstillet, mislykkes testen.

Stræk 3: Lagring af test

Selv om det er praktisk at skrive test i scripteditoren, bliver det hurtigt besværligt og svært at vedligeholde. Hvis du afslutter Instruments, kasseres alle ikke gemte ændringer. Vi er nødt til at gemme de tests, vi skriver. Du skal blot kopiere og indsætte din test i et nyt dokument i din foretrukne teksteditor og gemme den. Du kan finde de tests, der er oprettet i denne vejledning, i eksempelprojektet under Jumblify/JumblifyTests/AutomationTests.js.

For at køre testen skal du vælge den midterste fane i ruden til højre ved siden af scripteditoren og vælge Tilføj > Import.

Du bliver bedt om at vælge det script, der skal importeres. Naviger til det gemte script, og importer det. Du kan stadig ændre scriptet i scripteditoren. Eventuelle ændringer gemmes automatisk i den eksterne fil, du har oprettet.

Stræk 4: Tryk på en knap

Lad os opdatere vores test for at teste interaktion med knappen. Vores test tilføjer allerede tekst til tekstfeltet, så vi behøver kun at tilføje kode til at trykke på knappen. Lad os først overveje, hvordan vi finder knappen i visningen, så der kan trykkes på den. Der er mindst tre måder at opnå dette på, og hver tilgang har sine kompromiser.

Ansats 1

Vi kan programmæssigt trykke på et (X, Y)-koordinat på skærmen. Det gør vi med følgende kodelinje:

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

Selvfølgelig aner jeg ikke, om det overhovedet er koordinaterne for knappen på skærmen, og det vil jeg ikke bekymre mig om, for denne fremgangsmåde er ikke det rigtige værktøj til denne opgave. Jeg nævner det kun, så du ved, at det findes. Det er fejlbehæftet at bruge tap-metoden på target til at trykke på en knap, fordi knappen måske ikke altid befinder sig på den specifikke koordinat.

Angangsvinkel 2

Det er også muligt at finde knappen ved at søge i arrayet af knapper i hovedvinduet, på samme måde som vi fik adgang til tekstfeltet i den første test. I stedet for at få direkte adgang til knappen ved hjælp af en nøgle kan vi hente et array af knapper i hovedvinduet og hardcode et array-indeks for at få en reference til knappen.

target.frontMostApp().mainWindow().buttons().tap();

Denne fremgangsmåde er lidt bedre. Vi hardkoder ikke en koordinat, men vi hardkoder et arrayindeks for at finde knappen. Hvis vi tilfældigvis tilføjer en anden knap på siden, kan det ved et uheld ødelægge denne test.

Ansats 3

Dette bringer mig til den tredje måde at finde knappen på siden på, ved hjælp af tilgængelighedsetiketter. Ved at bruge en tilgængelighedsetiket kan vi få direkte adgang til knappen, ligesom vi ville finde et objekt i en ordbog ved hjælp af en nøgle.

target.frontMostApp().mainWindow().buttons().tap();

Hvis du tilføjer ovenstående linje til scriptet og kører det, får du imidlertid en fejl.

Dette skyldes, at vi endnu ikke har defineret tilgængelighedsetiketten for knappen. Hvis du vil gøre det, skal du vende over til Xcode og åbne projektets storyboard. Find knappen i visningen, og åbn Identitetsinspektøren til højre (Visning > Hjælpeprogrammer > Identitetsinspektør). Sørg for, at Tilgængelighed er aktiveret, og indstil Label for knappen til Jumblify Button.

For at køre testen igen skal du køre programmet fra Xcode ved at vælge Produkt > Kør og derefter profilere programmet igen ved at vælge Produkt > Profil. Dette kører testene, og hver test skulle nu bestå.

Stræk 5: Verificer den sammenblandede streng

Som jeg nævnte tidligere, tager vores applikation en tekststreng som input, og når brugeren trykker på knappen, vises den omvendte streng. Vi skal tilføje endnu en test for at verificere, at inputstrengen er korrekt omvendt. For at verificere, at UILabel er udfyldt med den korrekte streng, skal vi finde ud af, hvordan vi kan henvise til UILabel og verificere den streng, den viser. Dette er et almindeligt problem, når man skriver automatiseringstest, nemlig at finde ud af, hvordan man refererer til et element i programmet for at foretage en påstand om det.

Der er en metode på næsten alle objekter i UI Automation API’et, logElementTree. Denne metode logger de indlejrede elementer i et givet element. Dette er meget nyttigt for at forstå hierarkiet af elementer i programmet og hjælper med at finde ud af, hvordan man kan målrette et bestemt element.

Lad os se, hvordan dette fungerer ved at logge elementtræet i hovedvinduet. Tag et kig på følgende kodelinje:

target.frontMostApp().mainWindow().logElementTree();

Indførelse af denne linje i testskriptet resulterer i følgende output:

Som du kan se, er der et UIAStaticText underelement til UIAWindow, og du kan også se, at det har navnet ih, som også er den omvendte streng, vi skal verificere. For at færdiggøre vores test skal vi nu blot tilføje kode for at få adgang til dette element og kontrollere, at det er til stede.

Hvorfor skal vi kun kontrollere, om UIAStaticText-elementet er til stede? Fordi elementets navn er den omvendte streng af inputstrengen, bekræfter verifikationen af dets tilstedeværelse, at strengen blev omvendt korrekt. Hvis elementet ikke findes, når der henvises til det ved navn – den omvendte streng – betyder det, at strengen ikke blev omvendt korrekt.

4. Kradser i overfladen

Der er så mange andre måder, hvorpå en slutbruger kan interagere med en iOS-enhed, mens han bruger din app. Det betyder, at der er mange andre måder, hvorpå du kan bruge UI Automation til at simulere disse interaktioner. I stedet for at forsøge at indfange en omfattende liste over disse interaktioner vil jeg henvise dig til referencedokumentationen til UI Automation.

For hver type objekt, som du kan interagere med, kan du få vist listen over metoder, der er tilgængelige for det pågældende objekt. Nogle metoder er til at hente attributter om objektet, mens andre er til at simulere berøringsinteraktion, f.eks. flickInsideWithOptionsUIAWindow.

Optagelse af en session

Når du forsøger at teste flere og mere komplicerede apps med UI Automation, vil du opdage, at det nogle gange er ret kedeligt at bruge logElementTree gentagne gange for at finde det element, du leder efter. Dette bliver også trættende og komplekst for programmer med et komplekst visningshierarki eller en kompleks navigation. I disse tilfælde kan du bruge en anden funktion i Instruments til at registrere et sæt brugerinteraktioner. Hvad der er endnu federe er, at Instruments genererer den UI Automation JavaScript-kode, der er nødvendig for at reproducere de registrerede interaktioner. Sådan kan du selv afprøve det:

I Instruments og med Automation-instrumentet valgt skal du kigge efter optageknappen nederst i vinduet.

Hvis du klikker på optageknappen, starter Instruments en optagelsessession, som vist i skærmbilledet nedenfor.

Instruments starter din applikation i iOS-simulatoren, og du kan interagere med den. Instruments vil generere et script baseret på dine interaktioner i realtid. Prøv det. Drej iOS-simulatoren, tryk på tilfældige steder, udfør en swipe-bevægelse osv. Det er en virkelig nyttig måde at hjælpe med at udforske mulighederne for UI-automatisering.

Undergå en monolitisk kodebase

Som du sikkert kan forudse, vil det hurtigt blive svært at vedligeholde, hvis vi fortsætter med at tilføje flere test til den testfil, vi har oprettet efter den samme metode, hvis vi fortsætter med at tilføje flere test til den testfil, vi har oprettet efter samme metode. Hvad kan vi gøre for at forhindre det i at ske. I mine tests gør jeg to ting for at løse dette problem:

  • Én test for én funktion: Dette indebærer, at de tests, vi skriver, skal være fokuseret på et bestemt stykke funktionalitet. Jeg giver den endda et passende navn, f.eks. testEmptyInputField.
  • Gruppér relaterede tests i én fil: Jeg grupperer også relaterede tests i den samme fil. Dette holder koden i én fil overskuelig. Det gør det også lettere at teste separate dele af funktionaliteten ved at udføre testene i en bestemt fil. Derudover kan du oprette et master-script, hvori du kalder de funktioner eller tests, du har grupperet i andre testfiler.

I det følgende kodestykke importerer vi en JavaScript-fil, og det gør funktionerne i denne JavaScript-fil tilgængelige for os.

#import "OtherTests.js"

Konklusion

I denne vejledning har du lært værdien af test på højere niveau, og hvordan UI Automation kan hjælpe med at udfylde dette hul. Det er endnu et værktøj i din værktøjskasse, der kan hjælpe dig med at sikre, at du leverer pålidelige og robuste applikationer.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.