Introduktion till iOS-testning med UI Automation

apr 17, 2021
admin

Föreställ dig att du kan skriva skript som automatiskt interagerar med din iOS-applikation och kontrollera resultaten. Med UI Automation kan du. UI Automation är ett verktyg som tillhandahålls av Apple för att utföra en högre nivå av testning av din iOS-applikation än vad som går att uppnå med XCTest.

1. White Box kontra Black Box-testning

Du kanske har hört jämförelsen mellan white box-testning och black box-testning när det gäller hur man kan testa en programvara. Om du inte är bekant med dessa begrepp, låt mig förklara hur de fungerar.

White Box Testing

Föreställ dig att det finns en programvara som körs inuti en låda. Med white box-testning kan du se in i lådan och titta på alla detaljer om hur programvaran fungerar och sedan fatta välgrundade beslut om hur programvaran ska testas. Du kan också ha djupare ingångar till programvaran från de tester som du skriver.

Enhetstestning är white box-testning. När man skriver enhetstester har testaren finkornig tillgång till den kod som testas. Testaren kan faktiskt skriva tester som utnyttjar den testade programvaran på metod- eller enhetsnivå.

I mjukvaruutveckling för iOS använder vi ramverket XCTest för att utföra den här typen av testning. Ta en titt på en annan handledning som jag skrev om hur man kommer igång med XCTest.

Black Box Testing

I black box testing är lådan ogenomskinlig. Testaren kan inte se inuti lådan. Testaren kan inte få tillgång till och känner inte till implementationen av kodbasen för att skriva tester. Istället tvingas testaren använda applikationen som en slutanvändare skulle göra genom att interagera med applikationen och vänta på dess svar och verifiera resultaten.

Det finns minst två sätt att utföra denna typ av testning.

  • En testare som upprepade gånger och manuellt utför ett antal fördefinierade steg och visuellt verifierar resultaten.
  • Använda specialiserade verktyg för att testa applikationen med API:er som beter sig på ett sätt som liknar hur en människa interagerar.

I iOS-applikationsutveckling tillhandahåller Apple ett verktyg som kallas UI Automation för att utföra black box-testning.

2. Vad är UI Automation?

UI Automation är ett verktyg som Apple tillhandahåller och underhåller för automatiserad testning på högre nivå av iOS-applikationer. Testerna skrivs i JavaScript och följer ett API som definieras av Apple.

Det kan bli lättare att skriva tester genom att förlita sig på tillgänglighetsetiketter för användargränssnittselement i din applikation. Men oroa dig inte, om du inte har dessa definierade finns det alternativ.

UI Automation API saknar det typiska xUnit-baserade formatet för att skriva tester. En skillnad mot enhetstester är att testaren måste logga framgång och misslyckanden manuellt. UI Automation-tester körs från Automation-instrumentet i Instruments-verktyget som följer med Apples utvecklarverktyg. Testerna kan köras i iOS-simulatorn eller på en fysisk enhet.

3. Att skriva UI Automation-tester

Steg 1: Öppna exempelprojektet

Jag har uppdaterat exempelprojektet som användes i den tidigare handledningen om iOS-testning med några ytterligare användargränssnittselement som ger några användbara krokar för att lägga till UI Automation-tester. Ladda ner projektet från GitHub. Öppna projektet och kör programmet för att se till att allt fungerar som förväntat. Du bör se ett användargränssnitt som liknar det som visas nedan.

Innan vi skriver några tester kan du gärna prova exempelprogrammet för att bekanta dig med dess funktionalitet. Som användare kan du skriva in text i textfältet och trycka på knappen för att se en etikett på skärmen som visar den omvända, inmatade strängen.

Steg 2: Skapa ett UI Automation-test

Nu när du är bekant med exempelprogrammet är det dags att lägga till ett UI Automation-test. UI Automation är ett verktyg som finns i Instruments. Om du vill köra exempelprogrammet i Instruments väljer du Product > Profile i Xcodes meny. Välj Automation i listan över verktyg.

Huvudfönstret Instruments öppnas med ett enda instrument redo att köras, Automation-instrumentet (Automation-instrumentet utför UI Automation-testfall). Du kommer också att se ett område i den nedre halvan av fönstret som ser ut som en textredigerare. Detta är skriptredigeraren. Det är här du kommer att skriva dina UI Automation-tester. För det här första testet följer du nedanstående instruktioner och lägger till varje rad till skriptet i skripteditorn.

Startar med att lagra en referens till textfältet i en variabel.

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

Sätt textfältets värde.

inputField.setValue("hi");

Kontrollera att värdet har satts in framgångsrikt och, om så är fallet, godkänn testet. Misslyckas testet om det inte gjorde det.

Även om det här testet är ganska trivialt har det ett värde. Vi har just skrivit ett test som testar närvaron av ett textfält när programmet startas och som testar om en slumpmässig sträng kan ställas in som textfältets värde. Om du inte tror mig kan du ta bort textfältet från storyboarden och köra testet. Du kommer att se att det misslyckas.

Det här testet demonstrerar tre viktiga delar av att skriva UI Automation-tester. För det första visar det hur du får tillgång till ett enkelt användargränssnittselement, textfältet. Närmare bestämt får vi tillgång till ett lexikon med alla textfält i basvyn i programmet via target.frontMostApp().mainWindow().textFields() och vi hittar sedan det textfält vi är intresserade av genom att leta efter det som har nyckeln Input Field. Denna nyckel är faktiskt textfältets tillgänglighetsetikett. I det här fallet är den definierad i storyboardet. Vi kan också ställa in tillgänglighetsetiketten i kod med hjälp av egenskapen accessibilityLabelNSObject.

Accessing the application’s main window, the front most application, and the target are common when working with UI Automation. Jag kommer att visa dig hur du kan göra detta enklare och mindre verbalt senare i den här handledningen.

För det andra visar det här att du kan interagera med användargränssnittselement på skärmen. I det här fallet ställer vi in textfältets värde, vilket efterliknar användaren som interagerar med programmet genom att skriva in text i textfältet.

För det tredje visar exemplet också en teknik för att verifiera vad som händer i programmet. Om värdet sätts framgångsrikt klaras testet. Om värdet inte sätts misslyckas testet.

Steg 3: Spara test

Som det är bekvämt att skriva test i skripteditorn blir det snabbt krångligt och svårt att underhålla. Om du avslutar Instruments slängs alla osparade ändringar. Vi måste spara de tester vi skriver. Det är bara att kopiera och klistra in ditt test i ett nytt dokument i din favorittextredigerare och spara det. Du hittar testerna som skapats i den här handledningen i exempelprojektet under Jumblify/JumblifyTests/AutomationTests.js.

För att köra testet väljer du den mellersta fliken i rutan till höger, bredvid skriptredigeraren, och väljer Lägg till > Importera.

Du kommer att bli ombedd att välja det skript som ska importeras. Navigera till det sparade skriptet och importera det. Du kan fortfarande ändra skriptet i skriptredigeraren. Alla ändringar sparas automatiskt i den externa fil som du skapade.

Steg 4: Tryck på en knapp

Vi uppdaterar vårt test för att testa interaktionen med knappen. Vårt test lägger redan till text i textfältet så vi behöver bara lägga till kod för att trycka på knappen. Låt oss först fundera på hur vi hittar knappen i vyn så att den kan knackas. Det finns minst tre sätt att åstadkomma detta och varje tillvägagångssätt har sina kompromisser.

Metod 1

Vi kan programmatiskt trycka på en (X, Y)-koordinat på skärmen. Vi gör detta med följande kodrad:

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

Självklart har jag ingen aning om det ens är knappens koordinater på skärmen och jag tänker inte oroa mig för det, eftersom det här tillvägagångssättet inte är rätt verktyg för det här jobbet. Jag nämner det bara för att du ska veta att det finns. Att använda tap-metoden på target för att trycka på en knapp är felbenägen, eftersom knappen kanske inte alltid finns på den specifika koordinaten.

Ansats 2

Det är också möjligt att hitta knappen genom att söka i arrayen av knappar i huvudfönstret, på samma sätt som vi fick tillgång till textfältet i det första testet. Istället för att komma åt knappen direkt med hjälp av en nyckel kan vi hämta en array av knappar i huvudfönstret och hårdkoda ett arrayindex för att få en referens till knappen.

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

Detta tillvägagångssätt är lite bättre. Vi hårdkodar inte en koordinat, men vi hårdkodar ett arrayindex för att hitta knappen. Om vi råkar lägga till en annan knapp på sidan kan det råka bryta det här testet.

Angreppssätt 3

Detta för mig till det tredje sättet att hitta knappen på sidan, med hjälp av tillgänglighetsetiketter. Genom att använda en tillgänglighetsetikett kan vi få direkt tillgång till knappen precis som vi skulle hitta ett objekt i en ordbok med hjälp av en nyckel.

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

Men om du lägger till ovanstående rad i skriptet och kör det får du ett fel.

Detta beror på att vi inte har definierat tillgänglighetsetiketten för knappen ännu. För att göra det, vänder du dig till Xcode och öppnar projektets storyboard. Hitta knappen i vyn och öppna identitetsinspektören till höger (View > Utilities > Identity Inspector). Se till att Tillgänglighet är aktiverat och ange Etikett för knappen till Jumblify Button.

För att köra testet igen måste du köra programmet från Xcode genom att välja Produkt > Kör och sedan profilera programmet igen genom att välja Produkt > Profil. På så sätt körs testerna och varje test bör nu godkännas.

Steg 5: Verifiera den omvända strängen

Som jag nämnde tidigare tar vår applikation en textsträng som inmatning och när användaren trycker på knappen visas den omvända strängen. Vi måste lägga till ytterligare ett test för att verifiera att inmatningssträngen är korrekt omvänd. För att verifiera att UILabel fylls med rätt sträng måste vi ta reda på hur vi kan referera till UILabel och verifiera den sträng som visas. Detta är ett vanligt problem när man skriver automationstester, det vill säga att ta reda på hur man refererar till ett element i programmet för att göra ett påstående om det.

Det finns en metod på nästan varje objekt i UI Automation API, logElementTree. Denna metod loggar de inbäddade elementen i ett givet element. Detta är mycket användbart för att förstå hierarkin av element i programmet och hjälper till att räkna ut hur man ska rikta in sig på ett specifikt element.

Låt oss se hur detta fungerar genom att logga elementträdet i huvudfönstret. Ta en titt på följande kodrad:

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

Om du lägger till den här raden i testskriptet får du följande utdata:

Som du kan se finns det ett UIAStaticText underelement till UIAWindow och du kan också se att det har namnet ih, vilket också råkar vara den omvända strängen som vi behöver verifiera. För att slutföra vårt test behöver vi nu bara lägga till kod för att komma åt detta element och verifiera att det finns.

Varför behöver vi bara verifiera om UIAStaticText-elementet finns? Eftersom elementets namn är den omvända strängen av inmatningssträngen bekräftar verifieringen av dess närvaro att strängen har omvänts på rätt sätt. Om elementet inte finns när det refereras med namnet – den omvända strängen – betyder det att strängen inte har omvänts korrekt.

4. Skrapa på ytan

Det finns så många andra sätt som en slutanvändare kan interagera med en iOS-enhet när han eller hon använder din app. Det betyder att det finns många andra sätt som du kan använda UI Automation för att simulera dessa interaktioner. Istället för att försöka fånga en omfattande lista över dessa interaktioner hänvisar jag dig till referensdokumentationen för UI Automation.

För varje typ av objekt som du kan interagera med kan du visa en lista över metoder som är tillgängliga för det objektet. Vissa metoder är till för att hämta attribut om objektet medan andra är till för att simulera beröringsinteraktion, till exempel flickInsideWithOptionsUIAWindow.

Inspelning av en session

I takt med att du försöker testa mer och mer komplicerade appar med UI Automation kommer du att märka att det ibland är ganska tråkigt att upprepade gånger använda logElementTree för att hitta det element som du letar efter. Detta blir också tråkigt och komplext för program med en komplex visningshierarki eller navigering. I dessa fall kan du använda en annan funktion i Instruments för att registrera en uppsättning användarinteraktioner. Vad som är ännu häftigare är att Instruments genererar den JavaScript-kod för UI Automation som behövs för att reproducera de inspelade interaktionerna. Så här kan du prova det själv:

I Instruments och med Automation-instrumentet valt letar du efter inspelningsknappen längst ner i fönstret.

Om du klickar på inspelningsknappen startar Instruments en inspelningssession som visas i skärmdumpen nedan.

Instruments startar din applikation i iOS-simulatorn och du kan interagera med den. Instruments kommer att generera ett skript baserat på dina interaktioner i realtid. Prova det. Rotera iOS-simulatorn, tryck på slumpmässiga platser, utför en svepande gest osv. Det är ett riktigt användbart sätt att hjälpa till att utforska möjligheterna med UI Automation.

Undervika en monolitisk kodbas

Som du säkert kan förutse, om vi fortsätter att lägga till fler test till testfilen som vi har skapat med samma metod, kommer den snabbt att bli svår att underhålla. Vad kan vi göra för att förhindra att det händer. I mina tester gör jag två saker för att lösa detta problem:

  • Ett test för en funktion: Detta innebär att de tester vi skriver måste fokusera på en specifik funktionalitet. Jag ger den till och med ett lämpligt namn, till exempel testEmptyInputField.
  • Gruppera relaterade tester i en fil: Jag grupperar också relaterade tester i samma fil. Detta håller koden i en fil hanterbar. Det gör det också lättare att testa separata delar av funktionaliteten genom att utföra testerna i en specifik fil. Dessutom kan du skapa ett huvudskript där du anropar de funktioner eller tester som du har grupperat i andra testfiler.

I följande kodutdrag importerar vi en JavaScript-fil och detta gör funktionerna i den JavaScript-filen tillgängliga för oss.

#import "OtherTests.js"

Slutsats

I den här handledningen har du lärt dig värdet av testning på högre nivå och hur UI Automation kan hjälpa till att fylla detta gap. Det är ytterligare ett verktyg i din verktygslåda för att se till att du levererar tillförlitliga och robusta applikationer.

Lämna ett svar

Din e-postadress kommer inte publiceras.