Zoeken…


Invoering

Bij het beginnen met unit-testen komen allerlei vragen aan de orde:

Wat is testen van eenheden? Wat is een SetUp en TearDown? Hoe ga ik om met afhankelijkheden? Waarom überhaupt een eenheid testen? Hoe maak ik goede eenheids-testen?

In dit artikel worden al deze vragen beantwoord, zodat u unit-testing kunt starten in elke gewenste taal.

Opmerkingen

Wat is testen van eenheden?

Eenheidstesten is het testen van code om ervoor te zorgen dat het de taak uitvoert die het moet uitvoeren. Het test code op het laagst mogelijke niveau - de individuele methoden van uw klassen.

Wat is een eenheid?

Elke afzonderlijke codemodule die afzonderlijk kan worden getest. Meestal zijn de klassen en hun methoden. Deze klasse wordt in het algemeen de "Class Under Test" (CUT) of de "System Under Test" (SUT) genoemd

Het verschil tussen eenheids- en integratietests

Het testen van eenheden is het afzonderlijk testen van een enkele klasse, volledig los van de feitelijke afhankelijkheden. Integratietesten is het testen van een enkele klasse samen met een of meer van zijn werkelijke afhankelijkheden.

De SetUp en TearDown

Wanneer gemaakt, wordt de SetUp-methode uitgevoerd voor elke test en de TearDown na elke test.

Over het algemeen voegt u alle vereiste stappen toe in de SetUp en alle opruimstappen in de TearDown. Maar u maakt deze methode alleen als deze stappen voor elke test nodig zijn. Als dit niet het geval is, worden deze stappen uitgevoerd binnen de specifieke tests in de sectie "schikken".

Hoe om te gaan met afhankelijkheden

Vaak is een klasse afhankelijk van andere klassen om zijn methoden uit te voeren. Om niet afhankelijk te zijn van deze andere klassen, moet je deze vervalsen. U kunt deze klassen zelf maken of een isolatie- of mockup-framework gebruiken. Een isolatieraamwerk is een verzameling code waarmee nepklassen eenvoudig kunnen worden gemaakt.

Valse lessen

Elke klasse die voldoende functionaliteit biedt om te doen alsof het een afhankelijkheid is die een CUT nodig heeft. Er zijn twee soorten vervalsingen: Stubs en Mocks.

  • Een stub: een nep die geen effect heeft op het slagen of mislukken van de test en die puur bestaat om de test uit te voeren.
  • Een nep: een nep die het gedrag van de CUT bijhoudt en slaagt voor de test op basis van dat gedrag.

Waarom testen op eenheden?

1. Bij het testen van eenheden worden bugs gevonden

Wanneer u een volledige reeks tests schrijft die definiëren wat het verwachte gedrag is voor een bepaalde klasse, wordt alles onthuld dat zich niet gedraagt zoals verwacht.

2. Het testen van eenheden houdt bugs op afstand

Breng een wijziging aan die een bug introduceert en uw tests kunnen deze de volgende keer dat u uw tests uitvoert onthullen.

3. Het testen van eenheden bespaart tijd

Schrijven van unit-testen helpt ervoor te zorgen dat uw code vanaf het begin werkt zoals ontworpen. Eenheidstests definiëren wat uw code moet doen en u zult dus geen tijd besteden aan het schrijven van code die dingen doet die het niet zou moeten doen. Niemand controleert in code dat ze niet geloven dat het werkt en je moet iets doen om jezelf te laten denken dat het werkt. Besteed die tijd om eenheidstests te schrijven.

4. Unit testen geeft gemoedsrust

Je kunt al die tests uitvoeren en weten dat je code werkt zoals het hoort. De status van uw code kennen, dat deze werkt en dat u deze zonder angst kunt bijwerken en verbeteren, is een zeer goede zaak.

5. Eenheidstests beschrijven het juiste gebruik van een klasse

Eenheidstests worden eenvoudige voorbeelden van hoe uw code werkt, wat ervan wordt verwacht en de juiste manier om uw te testen code te gebruiken.

Algemene regels voor het testen van eenheden

1. Volg de AAA-regel voor de structuur van een eenheidstest

Regelen:

Stel het te testen ding in. Zoals variabelen, velden en eigenschappen om de test uit te voeren en het verwachte resultaat.

Act: Roep eigenlijk de methode op die u test

assert:

Bel het testraamwerk om te verifiëren dat het resultaat van uw "act" is wat werd verwacht.

2. Test één ding tegelijkertijd afzonderlijk

Alle klassen moeten afzonderlijk worden getest. Ze moeten niet afhankelijk zijn van iets anders dan de spotjes en stompjes. Ze moeten niet afhankelijk zijn van de resultaten van andere tests.

3. Schrijf eerst eenvoudige "in het midden" -tests

De eerste tests die u schrijft, zouden de eenvoudigste tests moeten zijn. Zij zouden degenen moeten zijn die in principe en gemakkelijk de functionaliteit illustreren die u probeert te schrijven. Zodra deze tests zijn geslaagd, moet u beginnen met het schrijven van de meer gecompliceerde tests die de randen en grenzen van uw code testen.

4. Schrijf tests die de randen testen

Zodra de basis is getest en u weet dat uw basisfunctionaliteit werkt, moet u de randen testen. Een goede set tests zal de buitenranden verkennen van wat er met een bepaalde methode kan gebeuren.

Bijvoorbeeld:

  • Wat gebeurt er als er een overloop optreedt?
  • Wat als waarden naar nul of lager gaan?
  • Wat als ze naar MaxInt of MinInt gaan?
  • Wat als u een boog van 361 graden maakt?
  • Wat gebeurt er als u een lege string doorgeeft?
  • Wat gebeurt er als een string 2 GB groot is?

5. Test over grenzen heen

Eenheidstests moeten beide zijden van een bepaalde grens testen. Grenzen overschrijden zijn plaatsen waar uw code mogelijk mislukt of op onvoorspelbare manieren werkt.

6. Test het hele spectrum als je kunt

Als het praktisch is, test dan alle mogelijkheden voor uw functionaliteit. Als het een genummerd type betreft, test dan de functionaliteit met elk van de items in de opsomming. Het is misschien onpraktisch om elke mogelijkheid te testen, maar als je elke mogelijkheid kunt testen, doe het dan.

7. Bedek indien mogelijk elk codepad

Deze is ook een uitdaging, maar als je code is ontworpen voor testen en je maakt gebruik van een codedekkingstool, kun je ervoor zorgen dat elke regel van je code minstens één keer wordt gedekt door unit-tests. Het afdekken van elk codepad garandeert niet dat er geen bugs zijn, maar het geeft je zeker waardevolle informatie over de status van elke coderegel.

8. Schrijf tests die een bug aan het licht brengen en repareer het

Als je een bug vindt, schrijf dan een test die deze onthult. Vervolgens kunt u de bug eenvoudig verhelpen door de test te debuggen. Dan heb je een leuke regressietest om ervoor te zorgen dat als de bug om welke reden dan ook terugkomt, je het meteen weet. Het is heel gemakkelijk om een bug op te lossen als je een eenvoudige, ongecompliceerde test hebt om in de debugger uit te voeren.

Een bijkomend voordeel is dat u uw test hebt getest. Omdat je de test hebt zien mislukken en wanneer je hem hebt zien slagen, weet je dat de test geldig is omdat bewezen is dat deze correct werkt. Dit maakt het een nog betere regressietest.

9. Maak elke test onafhankelijk van elkaar

Tests mogen nooit van elkaar afhankelijk zijn. Als uw tests in een bepaalde volgorde moeten worden uitgevoerd, moet u de tests wijzigen.

10. Schrijf één bewering per test

U moet één bewering per test schrijven. Als u dat niet kunt, refractor dan uw code zodat uw SetUp- en TearDown-gebeurtenissen worden gebruikt om de omgeving correct te maken, zodat elke test afzonderlijk kan worden uitgevoerd.

11. Noem uw tests duidelijk. Wees niet bang voor lange namen

Omdat je één test per test doet, kan elke test erg specifiek zijn. Wees dus niet bang om lange, volledige testnamen te gebruiken.

Een lange volledige naam laat je meteen weten welke test is mislukt en wat de test precies probeerde te doen.

Lange, duidelijk genoemde tests kunnen uw tests ook documenteren. Een test genaamd "DividedByZeroShouldThrowException" documenteert precies wat de code doet wanneer u probeert te delen door nul.

12. Test dat elke opgeworpen uitzondering daadwerkelijk wordt opgeworpen

Als uw code een uitzondering oproept, schrijf dan een test om ervoor te zorgen dat elke uitzondering die u oproept in feite wordt verhoogd wanneer het de bedoeling is.

13. Vermijd het gebruik van CheckTrue of Assert.IsTrue

Controleer niet op een Booleaanse voorwaarde. Als u bijvoorbeeld controleert of twee dingen gelijk zijn aan CheckTrue of Assert.IsTrue, gebruikt u in plaats daarvan CheckEquals of Assert.IsEqual. Waarom? Door dit:

CheckTrue (verwacht, werkelijk) Dit zal iets melden als: "Sommige test is mislukt: verwacht was waar, maar het werkelijke resultaat was vals."

Dit zegt je niets.

CheckEquals (verwacht, werkelijk)

Dit zal je iets vertellen als: "Sommige test is mislukt: verwacht 7 maar het werkelijke resultaat was 3."

Gebruik CheckTrue of Assert.IsTrue alleen wanneer uw verwachte waarde daadwerkelijk een Booleaanse voorwaarde is.

14. Voer uw tests voortdurend uit

Voer uw tests uit terwijl u code schrijft. Uw tests moeten snel worden uitgevoerd, zodat u ze zelfs na kleine wijzigingen kunt uitvoeren. Als je je tests niet kunt uitvoeren als onderdeel van je normale ontwikkelingsproces, gaat er iets mis. Unit-tests worden vrijwel onmiddellijk uitgevoerd. Als ze dat niet zijn, is het waarschijnlijk omdat u ze niet afzonderlijk uitvoert.

15. Voer uw tests uit als onderdeel van elke geautomatiseerde build

Net zoals u tijdens het ontwikkelen test zou moeten uitvoeren, zouden ze ook een integraal onderdeel van uw continu integratieproces moeten zijn. Een mislukte test zou moeten betekenen dat je build kapot is. Laat falende tests niet blijven hangen. Beschouw het als een build-fout en repareer het onmiddellijk.

Voorbeeld van een eenvoudige eenheids-test in C #

Voor dit voorbeeld testen we de sommethode van een eenvoudige rekenmachine.

In dit voorbeeld testen we de applicatie: ApplicationToTest. Deze heeft een klasse genaamd Calc. Deze klasse heeft een methode Sum ().

De methode Sum () ziet er zo uit:

public void Sum(int a, int b)
{
    return a + b;
}

De eenheidstest om deze methode te testen ziet er als volgt uit:

[Testclass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        //Arrange
        ApplicationToTest.Calc ClassCalc = new ApplicationToTest.Calc();
        int expectedResult = 5;

        //Act
        int result = ClassCalc.Sum(2,3);

        //Assert
        Assert.AreEqual(expectedResult, result);
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow