Introduksjon til IOS-testing med UI-automatisering

Tenk deg å kunne skrive skript som automatisk samhandler med ditt iOS-program og kunne bekrefte resultatene. Med UI Automation kan du. UI Automation er et verktøy levert av Apple for å utføre et høyere nivå av testing på din iOS-applikasjon utover alt som kan oppnås med XCTest.

1. White Box versus Black Box Testing

Du har kanskje hørt sammenligningen av white box testing mot svart boks testing med tanke på hvordan man kan teste et program. Hvis du ikke er kjent med disse konseptene, la meg forklare hvordan de fungerer.

White Box Testing

Tenk deg at det er et stykke programvare som kjører inne i en boks. Med hvit boks testing kan du se inne i esken og se på alle de grusomme delene av hvordan programvaren fungerer, og deretter ta utførte beslutninger om hvordan man skal teste programvaren. Du kan også ha dypere kroker i programvaren fra testene du skriver.

Enhetstesting er test av hvit boks. Når du skriver enhetstester, har testeren finkornet tilgang til koden under test. Testeren kan faktisk skrive tester som utnytter programvaren under test på metoden, eller enhet, nivå.

I IOS programvareutvikling bruker vi XCTest rammeverk for å utføre denne typen testing. Ta en titt på en annen opplæring jeg skrev om å komme i gang med XCTest.

Black Box Testing

I svart boks testing er boksen ugjennomsiktig. Testeren kan ikke se inne i esken. Testeren kan ikke få tilgang til og vet ikke om implementeringen av kodebase for å skrive tester. I stedet er testeren tvunget til å bruke programmet som en sluttbruker ville ved å samhandle med programmet og vente på svaret sitt, verifisere resultatene.

Det er minst to måter å utføre denne typen testing på.

  • En tester som gjentatte ganger og manuelt utfører en rekke forhåndsdefinerte trinn og visuelt verifiserer resultatene.
  • Bruk spesialiserte verktøy for å teste applikasjonen med APIer som oppfører seg som hvordan et menneske samhandler.

I IOS applikasjonsutvikling gir Apple et verktøy som heter UI Automation å utføre svart boks testing.

2. Hva er UI Automation? 

UI Automation er et verktøy som Apple tilbyr og vedlikeholder for høyere nivå, automatisert, testing av iOS-applikasjoner. Testene er skrevet i JavaScript, og overholder en API definert av Apple.

Skrivingstester kan gjøres lettere ved å stole på tilgjengelighetsetiketter for brukergrensesnittelementer i søknaden din. Ikke bekymre deg, men hvis du ikke har disse definert, finnes det alternativer.

UI Automation API mangler det typiske xUnit-baserte formatet for å skrive tester. En forskjell med enhetstesting er at testeren må manuelt logge suksess og feil. UI Automasjonstester kjøres fra Automation-instrumentet i instrumenter verktøy som følger med Apples utviklerverktøy. Tester kan kjøres i iOS-simulatoren eller på en fysisk enhet.

3. Skrive UI Automation Tests

Trinn 1: Åpne prøveprosjektet

Jeg har oppdatert prøveprosjektet som ble brukt i den tidligere opplæringen om iOS-testing med noen andre brukergrensesnittelementer som gir noen nyttige kroker for å legge til UI Automation-tester. Last ned prosjektet fra GitHub. Åpne prosjektet og kjør programmet for å sikre at alt fungerer som forventet. Du bør se et brukergrensesnitt som ligner på det som vises nedenfor.


Før vi skriver noen tester, er du velkommen til å prøve ut prøveapplikasjonen for å bli kjent med funksjonaliteten. Som bruker kan du skrive inn tekst i tekstfeltet og trykke på knappen for å se en etikett på skjermen som viser den omvendte, innmatede strengen.

Trinn 2: Opprett en UI-automasjonstest

Nå som du er kjent med prøveapplikasjonen, er det på tide å legge til en UI Automation test. UI Automation er et verktøy som finnes i instrumenter. For å kjøre prøveapplikasjonen i Instrumenter, velg Produkt> Profil fra Xcode-menyen. Å velge Automasjon fra listen over verktøy.


Hovedinstrumentvinduet åpnes med et enkelt instrument klar til å kjøre, automatiseringsinstrumentet (automatiseringsinstrumentet utfører UI Automation test tilfeller). Du ser også et område i nederste halvdel av vinduet som ser ut som en tekstredigerer. Dette er skriptredigeringsprogrammet. Det er her du vil skrive UI Automation tester. For denne første testen følger du instruksjonene nedenfor, og legger til hver linje i skriptet i skripteditoren.

Begynn med å lagre en referanse til tekstfeltet i en variabel.

var inputField = target.frontMostApp (). mainWindow (). textFields () ["Input Field"];

Angi tekstfeltets verdi.

inputField.setValue ( "hi”);

Kontroller at verdien ble satt til vellykket og, hvis det var, bestått testen. Feil testen hvis den ikke var det.

hvis (inputField.value ()! = "hei") UIALogger.logFail ("Inngangsfeltet kunne IKKE settes med strengen!"); ellers UIALogger.logPass ("Input Field var i stand til å bli satt med strengen!");

Mens denne testen er ganske triviell, har den verdi. Vi har nettopp skrevet en test som tester tilstedeværelsen av et tekstfelt når programmet startes, og det tester om en tilfeldig streng kan settes som tekstfeltets verdi. Hvis du ikke tror på meg, fjerner du tekstfeltet fra storyboardet og kjører testen. Du ser at den mislykkes.

Denne testen demonstrerer tre viktige stykker skrive UI-automatiseringstester. Først viser det deg hvordan du får tilgang til et enkelt brukergrensesnittelement, tekstfeltet. Spesielt får vi tilgang til en ordbok for alle tekstfeltene i grunnvisningen til programmet via target.frontMostApp (). mainWindow (). Tekstfelt () og vi finner deretter tekstfeltet vi er interessert i ved å lete etter en med nøkkel Input Field. Denne nøkkelen er faktisk tilgjengelighetsetiketten til tekstfeltet. I dette tilfellet er det definert i storyboardet. Vi kan også sette tilgjengelighetsetiketten i kode ved hjelp av accessibilityLabel eiendom på NSObject.

Å få tilgang til programmets hovedvindu, det fremste programmet og målet er vanlige når du arbeider med UI Automation. Jeg vil vise deg hvordan du gjør dette enklere og mindre ordentlig senere i denne opplæringen.

For det andre viser dette deg at du kan samhandle med brukergrensesnittelementer på skjermen. I dette tilfellet setter vi inn tekstfeltets verdi, etterligner brukeren som samhandler med programmet ved å skrive inn tekst i tekstfeltet.

Og for det tredje viser eksemplet også en teknikk for å verifisere hva som skjer i applikasjonen. Hvis verdien er vellykket, går testen. Hvis verdien ikke er satt, mislykkes testen.

Trinn 3: Lagre tester

Mens skrive tester i skripteditoren er praktisk, blir det raskt tungvint og vanskelig å vedlikeholde. Hvis du avslutter Instrumenter, blir eventuelle ubehandlede endringer kassert. Vi må lagre testene vi skriver. Kopier og lim inn testen din til et nytt dokument i din favoritt tekstredigerer, og lagre det. Du finner tester opprettet i denne opplæringen i prøveprosjektet under Jumblify / JumblifyTests / AutomationTests.js.

For å kjøre testen, velg mellomfliken i ruten til høyre ved siden av skripteditoren, og velg Legg til> Importer.


Du blir bedt om å velge skriptet som skal importeres. Naviger til det lagrede skriptet og importer det. Du kan fortsatt endre skriptet i skripteditoren. Eventuelle endringer lagres automatisk i den eksterne filen du opprettet.

Trinn 4: Trykk på en knapp

La oss oppdatere vår test for å teste samhandling med knappen. Vår test legger allerede til tekst i tekstfeltet, så vi trenger bare å legge til kode for å trykke på knappen. La oss først vurdere hvordan du finner knappen i visningen slik at den kan tappes. Det er minst tre måter å oppnå dette, og hver tilnærming har sine kompromisser.

Tilnærming 1

Vi kan programmatisk trykke på en (X, Y) koordinat på skjermen. Vi gjør dette med følgende linje av kode:

target.tap (x: 8,00, y: 50,00);

Selvfølgelig har jeg ingen anelse om de er til og med koordinatene til knappen på skjermen, og jeg kommer ikke til å bekymre meg for det, fordi denne tilnærmingen ikke er det riktige verktøyet for denne jobben. Jeg nevner bare det slik at du vet at det eksisterer. Bruker springen metode på mål å trykke på en knapp er feilaktig, fordi den knappen kanskje ikke alltid er i den spesifikke koordinaten.

Tilnærming 2

Det er også mulig å finne knappen ved å søke i rekkefølge av knapper i hovedvinduet, likt hvordan vi åpnet tekstfeltet i den første testen. I stedet for å få tilgang til knappen direkte ved hjelp av en nøkkel, kan vi hente en rekke knapper i hovedvinduet og hardkode en matriseindeks for å få en referanse til knappen.

target.frontMostApp () mainWindow () knapper () [0] .tap ()..;

Denne tilnærmingen er litt bedre. Vi er ikke hardkodende en koordinat, men vi er hardkodende en arrayindeks for å finne knappen. Hvis vi tilfeldigvis legger til en annen knapp på siden, kan det ved et uhell ødelegges denne testen.

Tilnærming 3

Dette bringer meg til den tredje måten å finne knappen på siden, ved hjelp av tilgjengelighetsetiketter. Ved å bruke en tilgjengelighetsetikett, kan vi direkte få tilgang til knappen som bare likte at vi skulle finne et objekt i en ordbok ved hjelp av en nøkkel.

target.frontMostApp (). mainWindow (). knapper () ["Jumblify Button"]. Trykk på ();

Men hvis du legger til linjen over til skriptet og kjører den, får du en feil.


Dette skyldes at vi ikke har definert tilgjengelighetsetiketten for knappen ennå. For å gjøre det, bla til Xcode og åpne prosjektets storyboard. Finn knappen i visningen og åpne Identitetsinspektør til høyre (Se> Verktøy> Identitetsinspektør). Sørge for at tilgjengelighet er aktivert og angi Merkelapp for knappen til Jumblify Button.


For å kjøre testen igjen, må du kjøre programmet fra Xcode ved å velge Produkt > Løpe og profiler deretter programmet på nytt ved å velge Produkt > Profil. Dette løper tester og hver test skal passere nå.

Trinn 5: Verifiser Jumbled String 

Som nevnt tidligere tar vår søknad en streng tekst som input, og når brukeren tapper på knappen, viser den omvendte strengen. Vi må legge til en ny test for å bekrefte at inntastingsstrengen er riktig reversert. For å verifisere at UILabel er befolket med riktig streng, må vi finne ut hvordan du refererer til UILabel og bekreft strengen som vises. Dette er et vanlig problem når du skriver automatiseringstester, det vil si å finne ut hvordan du refererer til et element i applikasjonen for å gjøre et påstand om det.

Det er en metode på nesten alle objekter i UI Automation API, logElementTree. Denne metoden logger inn de nestede elementene i et gitt element. Dette er veldig nyttig for å forstå elementarhierarkiet i applikasjonen og bidrar til å finne ut hvordan du målretter mot et bestemt element.

La oss se hvordan dette fungerer ved å logge elementetreet i hovedvinduet. Ta en titt på følgende linje av kode.

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

Å legge denne linjen til testskriptet resulterer i følgende utgang:


Som du kan se, er det en UIAStaticText delelement av UIAWindow og du kan også se at den har et navn på ih, som også skjer med den omvendte strengen vi må verifisere. Nå, for å fullføre testen, trenger vi bare å legge til kode for å få tilgang til dette elementet og bekrefte at det er til stede.

Hvorfor trenger vi bare å verifisere om UIAStaticText element er tilstede?Fordi elementets navn er den omvendte strengen av inngangsstrengen, bekrefter det at tilstedeværelsen er bekreftet at strengen var riktig reversert. Hvis elementet ikke eksisterer når det refereres til etter navn - den omvendte strengen - da betyr det at strengen ikke var riktig reversert.

var stringResult = target.frontMostApp (). mainWindow (). staticTexts () ["ih"]; hvis (! stringResult.isValid ()) UIALogger.logFail ("Utgangsteksten ble IKKE satt med den riktige reverserte strengen!"); ellers UIALogger.logPass ("Utgangsteksten ble satt med den riktige reverserte strengen!");

4. Skrape overflaten

Det er så mange andre måter som en sluttbruker kan samhandle med en iOS-enhet mens du bruker appen din. Dette betyr at det er mange andre måter du kan bruke UI Automation til å simulere disse interaksjonene. I stedet for å prøve å fange en omfattende liste over disse interaksjonene, leder jeg deg til referansedokumentasjonen til UI Automation.

For hver type objekt som du kan samhandle med, kan du se listen over metoder som er tilgjengelige på objektet. Noen metoder er for å hente attributter om objektet, mens andre er for å simulere berøringsinteraksjon, for eksempel flickInsideWithOptionsUIAWindow.

Opptak av en økt

Når du prøver å teste mer og mer kompliserte applikasjoner med UI Automation, finner du at det er ganske kjedelig å gjentatte ganger bruke logElementTree for å finne elementet du leter etter. Dette blir også kjedelig og komplisert for applikasjoner med et komplekst visningshierarki eller navigasjon. I disse tilfellene kan du bruke en annen funksjon av instrumenter å registrere et sett med brukerinteraksjoner. Hva er enda kulere er at Instrumenter genererer UI Automation JavaScript-koden som trengs for å reprodusere de registrerte interaksjonene. Slik kan du prøve det selv.

I Instrumenter og med det valgte automatiseringsinstrumentet, se etter opptaksknappen nederst i vinduet.


Hvis du klikker på opptaksknappen, starter Instrumentene en opptakssesjon som vist på skjermbildet nedenfor.


Instrumenter vil starte applikasjonen din i iOS-simulatoren, og du vil kunne samhandle med den. Instrumenter vil generere et skript basert på samspillet ditt i sanntid. Gi det et forsøk. Roter iOS-simulatoren, trykk på tilfeldige steder, utfør en swipe gest, etc. Det er en veldig nyttig måte å hjelpe deg med å utforske mulighetene for UI Automation.

Unngå en monolitisk kodebase

Som du sannsynligvis kan forutse, hvis vi fortsetter å legge til mer test i testfilen som vi har opprettet i samme metode, blir det raskt vanskelig å vedlikeholde. Hva kan vi gjøre for å forhindre at det skjer. I mine tester gjør jeg to ting for å løse dette problemet:

  • Én test for en funksjon: Dette innebærer at testene vi skriver må være fokusert på en bestemt funksjonalitet. Jeg vil til og med gi det et passende navn, for eksempel testEmptyInputField.
  • Grupperelaterte tester i en fil: Jeg grupperer også relaterte tester i samme fil. Dette holder koden i en fil håndterlig. Dette gjør det også lettere å teste separate deler av funksjonaliteten ved å utføre testene i en bestemt fil. I tillegg kan du opprette et masterskript der du ringer funksjonene eller tester du har gruppert i andre testfiler.

I den følgende kodestykket importerer vi en JavaScript-fil, og dette gjør funksjonene i den JavaScript-filen tilgjengelig for oss.

#import "OtherTests.js"

Konklusjon

I denne opplæringen har du lært verdien av høyere nivå testing og hvordan UI Automation kan bidra til å fylle det gapet. Det er et annet verktøy i verktøykassen for å sikre at du leverer pålitelige og robuste applikasjoner.

referanser

UI Automation JavaScript Reference