Stel je voor dat je scripts kunt schrijven die automatisch communiceren met je iOS-applicatie en de resultaten kunnen verifiëren. Met UI Automation kan dat. UI Automation is een hulpmiddel van Apple om meer tests uit te voeren op uw iOS-applicatie dan alles wat haalbaar is met XCTest.
U hebt misschien de vergelijking van testen in de witte doos met testen in de zwarte doos gehoord met betrekking tot hoe u een stukje software kunt testen. Als je niet bekend bent met deze concepten, laat me uitleggen hoe ze werken.
Stel je voor dat er een stuk software in een doos loopt. Met het testen van witte kisten kunt u in de doos kijken naar alle korrelige stukken van de werking van de software en vervolgens gefundeerde beslissingen nemen over het testen van de software. Je kunt ook dieperliggende hooks gebruiken in de software van de tests die je schrijft.
Het testen van eenheden is testen met witte kisten. Bij het schrijven van eenheidscontroletests heeft de tester fijnmazige toegang tot de te testen code. De tester kan zelfs tests schrijven die gebruikmaken van de geteste software op de methode of eenheid, niveau.
Bij de ontwikkeling van iOS-software gebruiken we de XCTest kader om dit type testen uit te voeren. Bekijk eens een andere zelfstudie die ik heb geschreven om met XCTest aan de slag te gaan.
Bij testen in een zwarte doos is de doos dekkend. De tester kan de binnenkant van de doos niet zien. De tester heeft geen toegang tot en is niet op de hoogte van de implementatie van de codebasis om tests te schrijven. In plaats daarvan wordt de tester gedwongen om de applicatie als een eindgebruiker te gebruiken door interactie met de applicatie en in afwachting van de reactie, het verifiëren van de resultaten.
Er zijn ten minste twee manieren om dit type testen uit te voeren.
In iOS-applicatie-ontwikkeling, Apple biedt een tool genaamd UI-automatisering om testen in een zwarte doos uit te voeren.
UI Automation is een tool die Apple biedt en onderhoudt voor het op een hoger niveau, geautomatiseerd testen van iOS-applicaties. Tests zijn geschreven in JavaScript en houden zich aan een door Apple gedefinieerde API.
Schrijftests kunnen eenvoudiger worden door te vertrouwen op toegankelijkheidslabels voor elementen van de gebruikersinterface in uw toepassing. Maak je echter geen zorgen, als je deze niet hebt gedefinieerd, zijn er alternatieven beschikbaar.
De UI Automation API mist het typische op xUnit gebaseerde formaat voor schrijftests. Een verschil met unit-testen is dat de tester handmatig successen en storingen moet registreren. UI Automation-tests worden uitgevoerd vanuit het Automation-instrument binnen de instrumenten hulpmiddel dat bij de ontwikkeltools van Apple wordt geleverd. De tests kunnen worden uitgevoerd in de iOS Simulator of op een fysiek apparaat.
Ik heb het voorbeeldproject dat in de vorige zelfstudie voor iOS-tests werd gebruikt, geüpdatet met enkele extra elementen in de gebruikersinterface die een aantal nuttige haken bieden voor het toevoegen van UI Automation-tests. Download het project van GitHub. Open het project en voer de applicatie uit om te controleren of alles werkt zoals verwacht. U zou een gebruikersinterface moeten zien die lijkt op de hieronder getoonde gebruikersinterface.
Voordat we tests schrijven, kunt u de voorbeeldtoepassing proberen om vertrouwd te raken met de functionaliteit ervan. Als gebruiker kunt u tekst in het tekstveld invoeren en op de knop tikken om een label op het scherm te zien waarop de omgekeerde ingevoerde string wordt weergegeven.
Nu u bekend bent met de voorbeeldtoepassing, is het tijd om een UI Automation-test toe te voegen. UI Automation is een hulpmiddel dat u kunt vinden in instrumenten. Als u de voorbeeldtoepassing in Instrumenten wilt uitvoeren, selecteert u Product> Profiel uit het Xcode-menu. kiezen Automatisering uit de lijst met tools.
Het hoofdvenster Instrumenten wordt geopend met een enkel instrument dat gereed is om te worden uitgevoerd, het Automation-instrument (het Automation-instrument voert UI Automation-testcases uit). U ziet ook een gebied in de onderste helft van het venster dat eruitziet als een teksteditor. Dit is de scripteditor. Hier schrijf je je UI Automation-tests. Volg voor deze eerste test de onderstaande instructies en voeg elke regel toe aan het script in de scripteditor.
Begin met het opslaan van een verwijzing naar het tekstveld in een variabele.
var inputField = target.frontMostApp (). mainWindow (). textFields () ["Input Field"];
Stel de waarde van het tekstveld in.
inputField.setValue ( "hallo”);
Controleer of de waarde met succes is ingesteld en voer de test uit als deze was. Misluk de test als dat niet het geval was.
if (inputField.value ()! = "hi") UIALogger.logFail ("Het invoerveld kon NIET worden ingesteld met de tekenreeks!"); else UIALogger.logPass ("Het invoerveld kon worden ingesteld met de string!");
Hoewel deze test tamelijk triviaal is, heeft deze wel waarde. We hebben zojuist een test geschreven die de aanwezigheid van een tekstveld test wanneer de toepassing wordt gestart en die test of een willekeurige reeks kan worden ingesteld als de waarde van het tekstveld. Als je me niet gelooft, verwijder je het tekstveld van het storyboard en voer je de test uit. Je zult zien dat het mislukt.
Deze test toont drie belangrijke stukken UI Automation-tests. Ten eerste toont het u hoe u toegang krijgt tot een eenvoudig gebruikersinterface-element, het tekstveld. In het bijzonder hebben we toegang tot een woordenboek van alle tekstvelden in het basisoverzicht van de toepassing via target.frontMostApp (). MainWindow (). textfields ()
en we vinden dan het tekstveld waarin we geïnteresseerd zijn door te zoeken naar degene met sleutel Invoer veld
. Deze sleutel is eigenlijk het toegankelijkheidslabel van het tekstveld. In dit geval is het gedefinieerd in het storyboard. We kunnen ook het toegankelijkheidslabel in code instellen met behulp van de accessibilityLabel
eigendom op NSObject
.
Toegang tot het hoofdvenster van de toepassing, de meestvoorkomende toepassing en het doel zijn gebruikelijk bij het werken met UI Automation. Ik zal je laten zien hoe je dit eenvoudiger en minder uitgebreid kunt maken later in deze tutorial.
Ten tweede toont dit u dat u kunt communiceren met elementen van de gebruikersinterface op het scherm. In dit geval stellen we de waarde van het tekstveld in, waarbij de gebruiker die interactie heeft met de toepassing wordt nagebootst door tekst in het tekstveld in te voeren.
En ten derde toont het voorbeeld ook een techniek om te verifiëren wat er in de applicatie gebeurt. Als de waarde met succes is ingesteld, gaat de test voorbij. Als de waarde niet is ingesteld, mislukt de test.
Hoewel het schrijven van tests in de scripteditor handig is, wordt het snel omslachtig en moeilijk te onderhouden. Als u Instrumenten afsluit, worden niet-opgeslagen wijzigingen weggegooid. We moeten de tests opslaan die we schrijven. Kopieer en plak uw test in een nieuw document in uw favoriete teksteditor en sla het op. U kunt de tests die in deze zelfstudie zijn gemaakt, vinden in het voorbeeldproject hieronder Jumblify / JumblifyTests / AutomationTests.js.
Als u de test wilt uitvoeren, selecteert u het middelste tabblad in het rechterdeel naast de scripteditor en selecteert u Voeg toe> Importeren.
U wordt gevraagd om het script te selecteren om te importeren. Navigeer naar het opgeslagen script en importeer het. U kunt het script nog steeds wijzigen in de scripteditor. Alle wijzigingen worden automatisch opgeslagen in het externe bestand dat u hebt gemaakt.
Laten we onze test bijwerken om de interactie met de knop te testen. Onze test voegt al tekst toe aan het tekstveld, dus we hoeven alleen maar code toe te voegen om op de knop te tikken. Laten we eerst eens kijken hoe we de knop in de weergave kunnen vinden, zodat deze kan worden afgeluisterd. Er zijn minstens drie manieren om dit te bereiken en elke aanpak heeft zijn afwegingen.
We kunnen programmatisch op een (X, Y) -coördinaat op het scherm tikken. We doen dit met de volgende regel code:
target.tap (x: 8.00, y: 50.00);
Natuurlijk heb ik geen idee of dat zelfs de coördinaten van de knop op het scherm zijn en daar maak ik me geen zorgen over, omdat deze benadering niet de juiste tool is voor deze taak. Ik zeg het alleen maar, zodat je weet dat het bestaat. De ... gebruiken tik
methode op doelwit
om op een knop te tikken is foutgevoelig, omdat die knop niet altijd op die specifieke coördinaat staat.
Het is ook mogelijk om de knop te vinden door te zoeken in de reeks knoppen in het hoofdvenster, vergelijkbaar met hoe we het tekstveld in de eerste test hebben geopend. In plaats van de knop rechtstreeks met een toets te gebruiken, kunnen we een reeks knoppen in het hoofdvenster ophalen en een code hard maken om een verwijzing naar de knop te krijgen.
target.frontMostApp () MainWindow () () toetsen [0] .tap ()..;
Deze aanpak is een beetje beter. We coderen geen codering, maar we coderen een array-index hard om de knop te vinden. Als we toevallig nog een knop op de pagina toevoegen, kan deze per ongeluk deze test doorbreken.
Dit brengt me op de derde manier om de knop op de pagina te vinden, met toegankelijkheidslabels. Door een toegankelijkheidslabel te gebruiken, hebben we rechtstreeks toegang tot de knop die zojuist is gevonden dat we een object in een woordenboek zouden vinden met behulp van een sleutel.
target.frontMostApp (). mainWindow (). -knoppen () ["Jumblify-knop"]. Tik op ();
Als u echter de bovenstaande regel toevoegt aan het script en het uitvoert, krijgt u een foutmelding.
Dit komt omdat we het toegankelijkheidslabel voor de knop nog niet hebben gedefinieerd. Om dat te doen, ga je naar Xcode en open je het storyboard van het project. Zoek de knop in de weergave en open de Identiteitsinspecteur aan de rechterkant (Beeld> Hulpprogramma's> Identiteitscontrole). Verzekeren dat Toegankelijkheid is ingeschakeld en de Label voor de knop naar Jumblify-knop.
Als u de test opnieuw wilt uitvoeren, moet u de toepassing vanuit Xcode uitvoeren door te selecteren Artikel > Rennen en profileer de applicatie opnieuw door te selecteren Artikel > Profiel. Dit voert de tests uit en elke test zou nu moeten slagen.
Zoals ik eerder al zei, onze applicatie neemt een reeks tekst als invoer, en wanneer de gebruiker op de knop tikt, wordt de omgekeerde string weergegeven. We moeten nog een test toevoegen om te controleren of de invoerreeks juist is omgekeerd. Om te verifiëren dat de UILabel
is gevuld met de juiste string, we moeten uitzoeken hoe we moeten verwijzen naar de UILabel
en controleer de tekenreeks die wordt weergegeven. Dit is een veelvoorkomend probleem bij het schrijven van automatiseringstests, dat wil zeggen: uitzoeken hoe een element in de toepassing moet worden verwezen om er een bewering over te doen.
Er is een methode voor bijna elk object in de UI Automation API, logElementTree
. Deze methode registreert de geneste elementen van een bepaald element. Dit is erg handig om de hiërarchie van elementen in de toepassing te begrijpen en helpt om erachter te komen hoe een specifiek element moet worden bereikt.
Laten we kijken hoe dit werkt door de elementstructuur van het hoofdvenster te loggen. Bekijk de volgende regel code.
target.frontMostApp () MainWindow () logElementTree ()..;
Het toevoegen van deze regel aan het testscript resulteert in de volgende uitvoer:
Zoals je kunt zien, is er een UIAStaticText
subelement van de UIAWindow
en je kunt ook zien dat het een naam heeft ih
, wat ook de omgekeerde reeks is die we moeten verifiëren. Nu, om onze test te voltooien, hoeven we alleen maar code toe te voegen om toegang te krijgen tot dit element en te controleren of het aanwezig is.
Waarom hoeven we alleen maar te verifiëren of het UIAStaticText
element is aanwezig?Omdat de naam van het element de omgekeerde reeks van de invoerreeks is, bevestigt het verifiëren van de aanwezigheid dat de reeks correct is omgekeerd. Als het element niet bestaat wanneer naar de naam wordt verwezen, de omgekeerde reeks, betekent dit dat de tekenreeks niet correct is omgekeerd.
var stringResult = target.frontMostApp (). mainWindow (). staticTexts () ["ih"]; if (! stringResult.isValid ()) UIALogger.logFail ("De uitvoertekst was NIET ingesteld met de correct omgekeerde string!"); else UIALogger.logPass ("De uitvoertekst is ingesteld met de correct omgekeerde string!");
Er zijn zoveel andere manieren waarop een eindgebruiker kan communiceren met een iOS-apparaat tijdens het gebruik van uw app. Dit betekent dat er veel andere manieren zijn waarop u UI Automation kunt gebruiken om deze interacties te simuleren. In plaats van te proberen een uitgebreide lijst van deze interacties vast te leggen, zal ik u verwijzen naar de UI Automation-referentiedocumentatie.
Voor elk type object waarmee u kunt communiceren, kunt u de lijst met beschikbare methoden voor dat object bekijken. Sommige methoden zijn voor het ophalen van kenmerken over het object, terwijl andere methoden zijn voor het simuleren van aanraakinteractie, zoals flickInsideWithOptions
op UIAWindow
.
Terwijl je probeert meer en meer gecompliceerde apps te testen met UI Automation, zul je merken dat het soms vervelend is om herhaaldelijk te gebruiken logElementTree
om het element te vinden waarnaar u op zoek bent. Dit wordt ook vervelend en complex voor toepassingen met een complexe weergavehiërarchie of navigatie. In deze gevallen kunt u een andere functie van gebruiken instrumenten om een reeks gebruikersinteracties op te nemen. Wat nog cooler is, is dat Instruments de UI Automation JavaScript-code genereert die nodig is om de opgenomen interacties te reproduceren. Hier leest u hoe u het zelf kunt uitproberen.
Zoek in Instrumenten en met het geselecteerde automatiseringsinstrument naar de opnameknop onderaan het venster.
Als u op de opnameknop klikt, start Instruments een opnamesessie zoals in de onderstaande schermafbeelding wordt getoond.
Instrumenten zullen je applicatie starten in de iOS Simulator en je zult ermee kunnen communiceren. Instrumenten genereren een script op basis van uw interacties in realtime. Probeer het eens. Draai de iOS-simulator, tik op willekeurige locaties, voer een uithaalbeweging uit, enz. Het is echt een handige manier om de mogelijkheden van UI-automatisering te verkennen.
Zoals je waarschijnlijk kunt verwachten, zal het snel moeilijk worden om het testbestand dat we op dezelfde manier hebben gemaakt, te blijven toevoegen als we doorgaan met het toevoegen van meer tests. Wat kunnen we doen om te voorkomen dat dit gebeurt. In mijn tests, ik doe twee dingen om dit probleem op te lossen:
testEmptyInputField
.In het volgende codefragment importeren we een JavaScript-bestand en hierdoor zijn de functies in dat JavaScript-bestand voor ons beschikbaar.
#import "OtherTests.js"
In deze zelfstudie hebt u de waarde van tests op hoger niveau geleerd en hoe UI Automation kan helpen om die lacune op te vullen. Het is een ander hulpmiddel in uw toolbox om te zorgen dat u betrouwbare en robuuste applicaties verzendt.
UI Automation JavaScript-referentie