Niemand wil buggy-software verzenden. Om ervoor te zorgen dat u een mobiele applicatie van de hoogste kwaliteit vrijgeeft, is veel meer nodig dan een door de mens gestuurd handboek voor kwaliteitsborging. Nieuwe apparaten en besturingssystemen worden elk jaar vrijgegeven aan het publiek. Dit betekent dat er een steeds groter wordende combinatie is van schermformaten en besturingssysteemversies waarop u uw mobiele applicatie moet testen. Niet alleen zou het extreem tijdrovend zijn, maar een poging om uw iOS-applicatie te testen met handmatige tests, verwaarloost een heel stuk van het moderne software engineeringproces, geautomatiseerde kwaliteitsborgingstests.
In de wereld van vandaag zijn er veel tools beschikbaar die kunnen worden gebruikt om de software die u schrijft automatisch te testen. Sommige van deze tools worden onderhouden via een open source-model, maar er is ook een kernset die door Apple wordt geleverd. Met elke nieuwe release van de iOS SDK heeft Apple zijn engagement om de beschikbare tools voor ontwikkelaars te verbeteren om de code die ze schrijven te testen. Voor de iOS-ontwikkelaar die nog geen ervaring heeft met geautomatiseerd testen en die geïnteresseerd is om aan de slag te gaan, zijn de tools van Apple een goede plek om te beginnen.
Deze tutorial zal instructies geven voor het gebruik van een tool die Apple biedt voor geautomatiseerd testen, XCTest. XCTest is het unit testing framework van Apple. Unit-testen is het type van geautomatiseerd testen dat code op het laagste niveau controleert. U schrijft Objective-C-code die methoden van uw "productie" -code oproept en controleert of de te testen code daadwerkelijk doet wat hij moet doen. Zijn variabelen correct ingesteld? Is de retourwaarde correct??
Tests geschreven met het XCTest-framework kunnen herhaaldelijk worden uitgevoerd tegen de code van uw applicatie, zodat u er zeker van kunt zijn dat u een bugvrij product maakt, omdat nieuwe wijzigingen in de code de bestaande functionaliteit niet doorbreken.
Standaard wordt elk nieuw Xcode-project gemaakt met een goed startpunt voor het schrijven van eenheidscontroles. Dit omvat drie dingen:
Laten we ingaan op de structuur van een iOS unit-test. Een individuele eenheidstest wordt weergegeven als een enkele methode binnen elke subklasse van XCTestCase
waar de methode terugkeert leegte
, neemt geen parameters op en de naam van de methode begint met test
.
- (void) testSomething
Gelukkig maakt Xcode het maken van testcases eenvoudig. Bij nieuwe Xcode-projecten wordt een eerste testcase voor u gemaakt in een afzonderlijke bestandsgroep waarvan de naam wordt gevolgd door het woord Tests.
Ik heb een voorbeeldproject gemaakt dat kan worden gebruikt als referentie voor de voorbeelden in deze zelfstudie. Download het project vanuit GitHub en open het in Xcode.
In het voorbeeldproject vindt u de testgroep in de genoemde map JumblifyTests.
Klik met de rechtermuisknop op de bestandsgroep om uw eerste testcase te maken, JumblifyTests, en selecteer Nieuw bestand. Kiezen Testcase Klasse van de iOS> Bron sectie en geef de nieuwe subklasse een naam.
De gebruikelijke naamgevingsconventie is om de testcase zo te noemen dat het de naam is van de corresponderende klasse die wordt getest, gevolgd door Tests. Omdat we de. Zullen testen JumblifyViewController
class, noem de XCTestCase
subklasse JumblifyViewControllerTests
.
In de gloednieuwe XCTestCase
subklasse, ziet u vier methoden. Twee hiervan zijn zelf testen. Kun je identificeren wie ze zijn? Vergeet niet dat namen van testmethoden beginnen met het woord "test".
Als u er niet achter bent gekomen, zijn de standaard uitgevoerde testmethoden testExample
en testPerformanceExample
.
Verwijder beide tests, want we gaan de onze helemaal opnieuw schrijven. De andere twee methoden, opstelling
en scheuren
, worden overschreven door de superklasse, XCTestCase
. Ze zijn daarin uniek opstelling
en scheuren
worden aangeroepen voor en na elke testmethode wordt respectievelijk aangeroepen. Het zijn handige plaatsen om de code te centraliseren die moet worden uitgevoerd voordat of nadat elke testmethode wordt aangeroepen. Taken zoals algemene initialisatie of opschonen gaan hier.
Importeer het header-bestand van de JumblifyViewController
klasse en voeg een eigenschap van het type toe JumblifyViewController
naar de XCTestCase
subklasse.
@property (nonatomic) JumblifyViewController * vcToTest;
In de opstelling
methode, initialiseer de eigenschap zoals hieronder getoond.
- (ongeldig) setUp [super setUp]; self.vcToTest = [[JumblifyViewController alloc] init];
We gaan nu een test schrijven om het te testen reverseString:
methode van de JumblifyViewController
klasse.
Maak een testmethode die gebruikmaakt van de geïnstantieerde vcToTest
object om de te testen reverseString:
methode. In deze testmethode maken we een NSString
object en geef het door aan de view controller's reverseString:
methode. Het is gebruikelijk om uw test een zinvolle naam te geven om duidelijk te maken wat de test aan het testen is.
- (void) testReverseString NSString * originalString = @ "himynameisandy"; NSString * reversedString = [self.vcToTest reverseString: originalString];
Op dit moment hebben we nog niets nuttigs gedaan, omdat we het niet hebben getest reverseString:
methode nog niet. Wat we moeten doen is de output van de vergelijken reverseString:
methode met wat we verwachten dat de uitvoer zal zijn.
De XCTAssertEqualObjects
functie maakt deel uit van het XCTest-raamwerk. Het XCTest-framework biedt vele andere methoden om beweringen te doen over de applicatietoestand, zoals variabelengelijkheid of booleaanse expressieresultaten. In dit geval hebben we gesteld dat twee objecten gelijk moeten zijn. Als dat het geval is, gaat de test voorbij en als dat niet het geval is, mislukt de test. Bekijk de documentatie van Apple voor een uitgebreide lijst met beweringen die worden aangeboden door het XCTest-framework.
- (void) testReverseString NSString * originalString = @ "himynameisandy"; NSString * reversedString = [self.vcToTest reverseString: originalString]; NSString * expectedReversedString = @ "ydnasiemanymih"; XCTAssertEqualObjects (expectedReversedString, reversedString, @ "De omgekeerde tekenreeks kwam niet overeen met het verwachte omgekeerde");
Als u op dit moment probeert de code te compileren, ziet u een waarschuwing wanneer u probeert te bellen reverseString:
uit de testcase. De reverseString:
methode is een privémethode van de JumblifyViewController
klasse. Dit betekent dat andere objecten deze methode niet kunnen gebruiken omdat deze niet is gedefinieerd in het headerbestand van de JumblifyViewController
klasse.
Terwijl het schrijven van testbare code een mantra is die veel ontwikkelaars volgen, willen we onze code die wordt getest niet onnodig wijzigen. Maar hoe noemen we het privé reverseString:
methode van de JumblifyViewController
klasse in onze tests? We zouden een openbare definitie van de kunnen toevoegen reverseString:
methode om het header-bestand van de JumblifyViewController
klasse, maar dat breekt het inkapselingspatroon.
Een oplossing is om een privécategorie toe te voegen aan de JumblifyViewController
klasse om de reverseString:
methode. We voegen deze categorie toe aan de XCTestCase
subklasse, wat betekent dat het alleen beschikbaar is in die klasse. Door deze categorie toe te voegen, compileert de testcase zonder waarschuwingen of fouten.
@interface JumblifyViewController (Test) - (NSString *) reverseString: (NSString *) stringToReverse; @einde
Laten we onze tests uitvoeren om ervoor te zorgen dat ze slagen. Er zijn verschillende manieren om unit tests uit te voeren voor een iOS-applicatie. Ik ben een sneltoetsjunkie, dus mijn meest gebruikte techniek voor het uitvoeren van mijn unittests voor mijn toepassing is door op te drukken Command-U. Met deze sneltoets worden alle tests voor uw toepassing uitgevoerd. U kunt dezelfde actie ook uitvoeren door te selecteren Test van de Artikel menu.
Naarmate uw testsuite groter wordt of als u de ontwikkeling van een implementatietest wilt uitvoeren, zult u merken dat het uitvoeren van uw testsuite te tijdrovend kan worden. Of het kan uw workflow in de weg zitten. Een erg handig commando, begraven in Xcode's menu, waar ik verliefd op ben geworden Command + Option-Control-U. Met deze snelkoppeling wordt een opdracht gestart waarmee de test wordt uitgevoerd waarin uw cursor zich momenteel bevindt. Nadat u uw testsuite hebt ingevuld en gefinaliseerd, moet u altijd de volledige testsuite uitvoeren. Het uitvoeren van een individuele test is handig als u een nieuwe test test schrijft of als u een fout test uitvoert.
De opdracht om één test uit te voeren wordt aangevuld door Command + Option-Control-G, waarmee de laatste test opnieuw wordt uitgevoerd. Dit kan de volledige testsuite zijn of alleen de meest recente test waaraan u werkt. Het is ook handig in het geval dat u weg bent gegaan van welke test u ook aan het werken bent en u bent nog steeds bezig met het debuggen ervan.
U kunt uw testresultaten op een aantal plaatsen bekijken. Een van die plaatsen is de Test Navigator aan de rechterkant.
Een andere optie is door te kijken naar de goot van de Bron-editor.
Op een van deze twee plaatsen zal het klikken op de groene ruit met het witte vinkje die specifieke test opnieuw uitvoeren. In het geval van een mislukte test, zie je een rode ruit met een wit kruis in het midden. Als u hierop klikt, wordt die specifieke test ook opnieuw uitgevoerd.
Xcode 6 introduceerde twee nieuwe opwindende toevoegingen aan unit testing op iOS en OS X, testen asynchrone functionaliteit en het meten van de prestaties van een specifiek stuk code.
Voorafgaand aan Xcode 6 was er geen goede manier om asynchrone code te testen. Als de test van uw eenheid een methode met asynchrone logica bevat, kunt u de asynchrone logica niet verifiëren. De test zou voltooid zijn voordat de asynchrone logica in de te testen methode werd uitgevoerd.
Om asynchrone code te testen, heeft Apple een API geïntroduceerd waarmee ontwikkelaars een verwachting kunnen definiëren waaraan moet worden voldaan voordat de test succesvol is voltooid. De stroom is als volgt, definieer een verwachting, wacht tot de verwachting is voldaan en voldoe aan de verwachting wanneer de asynchrone code is voltooid. Bekijk het onderstaande voorbeeld voor verduidelijking.
- (void) testDoSomethingThatTakesSomeTime XCTestExpectation * completionExpectation = [self expectationWithDescription: @ "Long method"]; [self.vcToTest doSomethingThatTakesSomeTimesWithCompletionBlock: ^ (NSString * -resultaat) XCTAssertEqualObjects (@ "result", result, @ "Het resultaat was niet correct!"); [completionExpectation fulfilment]; ]; [self waitForExpectationsWithTimeout: 5.0 handler: nihil];
In dit voorbeeld testen we de doSomethingThatTakesSomeTimesWithCompletionBlock
methode. We willen het succes of falen van onze test op de waarde die wordt geretourneerd in het voltooiingsblok geroepen door de methode die wordt getest testen.
Om dit te doen, definiëren we een verwachting aan het begin van de testmethode. Aan het einde van de testmethode wachten we tot de verwachting is voldaan. Zoals u kunt zien, kunnen we ook een time-outparameter doorgeven.
De daadwerkelijke bewering van de test wordt gedaan in het voltooiingsblok van de te testen methode, waarin we ook de verwachting vervullen die we eerder hebben gedefinieerd. Als gevolg hiervan wacht de test tot de verwachting is dat de test wordt uitgevoerd of dat de test mislukt als de time-out verloopt en de verwachting niet wordt ingelost.
Een andere toevoeging aan unit testing in Xcode 6 is de mogelijkheid om de prestaties van een stuk code te meten. Hierdoor kunnen ontwikkelaars inzicht krijgen in de specifieke timinginformatie van de code die wordt getest.
Met prestatietests kunt u de vraag beantwoorden: "Wat is de gemiddelde tijd van uitvoering voor dit stuk code?" Als er een sectie is die bijzonder gevoelig is voor wijzigingen in de tijd die nodig is om het uit te voeren, dan kunt u prestatietests gebruiken om te meten hoeveel tijd het kost om uit te voeren.
U kunt ook een baseline-uitvoeringstijd definiëren. Dit betekent dat als de code die wordt getest significant afwijkt van die basislijn, de test mislukt. Xcode zal de code die wordt getest herhaaldelijk uitvoeren en de uitvoeringstijd ervan meten. Gebruik de. Om de prestaties van een stuk code te meten measureBlock:
API zoals hieronder getoond.
- (void) testPerformanceReverseString NSString * originalString = @ "himynameisandy"; [self measureBlock: ^ [self.vcToTest reverseString: originalString]; ];
Klik op het informatieve bericht dat verschijnt.
Stel de baseline uitvoeringstijd in of bewerk deze voor de prestatietest.
In deze zelfstudie hebt u geleerd hoe u met Xcode eenheidstests kunt maken om een iOS-toepassing op een programmatische en geautomatiseerde manier te verifiëren. Probeer het eens, op een bestaande codebase of op iets geheel nieuws. Of u nu volledig toegewijd bent aan het testen van eenheden of hier en daar wat tests wilt toevoegen, u voegt alleen waarde toe aan uw project door sterker geverifieerde software te schrijven die minder snel breekt met toekomstige wijzigingen. Het testen van eenheden is slechts het begin van geautomatiseerde softwaretests. Er zijn verschillende extra testlagen die u aan een iOS-applicatie kunt toevoegen.