unit-testing
De allmänna reglerna för enhetstestning för alla språk
Sök…
Introduktion
När du börjar med enhetstest dyker upp alla typer av frågor:
Vad är enhetstestning? Vad är en SetUp och TearDown? Hur hanterar jag beroenden? Varför gör enhetstest alls? Hur gör jag bra enhetstester?
Den här artikeln kommer att besvara alla dessa frågor så att du kan starta enhetstestning på vilket språk du vill.
Anmärkningar
Vad är enhetstestning?
Enhetstestning är testning av kod för att säkerställa att den utför den uppgift som den är tänkt att utföra. Den testar koden på den allra lägsta möjliga nivån - de enskilda metoderna för dina klasser.
Vad är en enhet?
Varje diskret kodmodul som kan testas isolerat. De flesta av tidsklasserna och deras metoder. Denna klass kallas generellt "Class Under Test" (CUT) eller "System Under Test" (SUT)
Skillnaden mellan enhetstestning och integrationstestning
Enhetstestning är att testa en enda klass isolerat, helt bortsett från något av dess faktiska beroenden. Integrationstestning är att testa en enda klass tillsammans med ett eller flera av dess faktiska beroenden.
SetUp och TearDown
När det görs körs SetUp-metoden före varje enhetstest och TearDown efter varje test.
Generellt lägger du till alla förutsatta steg i SetUp och alla saneringssteg i TearDown. Men du gör bara den här metoden om dessa steg behövs för varje test. Om inte, än dessa steg vidtas inom de specifika testerna i avsnittet "ordna".
Hur man hanterar beroenden
Många gånger har en klass beroende av andra klasser för att utföra sina metoder. För att inte kunna vara beroende av dessa andra klasser måste du förfalska dessa. Du kan skapa dessa klasser själv eller använda en ram för isolering eller mockup. En isoleringsram är en kodkod som gör det enkelt att skapa falska klasser.
Falska klasser
Varje klass som tillhandahåller funktionalitet som är tillräcklig för att låtsas att det är ett beroende som krävs av en CUT. Det finns två typer av förfalskningar: Stubbar och håna.
- En stubbe: En falskhet som inte har någon effekt på testets godkännande eller misslyckande och som existerar endast för att testet ska kunna köras.
- En skräp: En falsk som håller reda på beteendet hos CUT och klarar eller misslyckas testet baserat på det beteendet.
Varför testar enhet?
1. Enhetstest hittar buggar
När du skriver en fullständig serie tester som definierar vad det förväntade beteendet är för en viss klass, avslöjas allt som inte uppför sig som förväntat.
2. Enhetstestning kommer att hålla felen borta
Gör en förändring som introducerar ett fel och dina tester kan avslöja det nästa gång du kör dina tester.
3. Enhetstestning sparar tid
Skrivningsenhetstester hjälper dig att säkerställa att din kod fungerar som designad redan från början. Enhetstester definierar vad din kod ska göra och därmed kommer du inte att spendera tid på att skriva kod som gör saker som den inte borde göra. Ingen kontrollerar koden att de inte tror fungerar och du måste göra något för att få dig att tro att det fungerar. Spendera den tiden för att skriva enhetstester.
4. Enhetstest ger ro i sinnet
Du kan köra alla testerna och veta att din kod fungerar som den ska. Det är mycket bra att känna till koden, att den fungerar och att du kan uppdatera och förbättra den utan rädsla.
5. Enhetstest dokumenterar korrekt användning av en klass
Enhetstester blir enkla exempel på hur din kod fungerar, vad den förväntas göra och det rätta sättet att använda din kod som testas.
Allmänna regler för enhetstestning
1. Följ AAA-regeln för strukturen för ett enhetstest
Ordna:
Ställ in saken som ska testas. Som variabler, fält och egenskaper för att testet ska kunna köras såväl som det förväntade resultatet.
Act: Ring faktiskt metoden du testar
Hävda:
Ring testramen för att verifiera att resultatet av din "handling" är vad som förväntades.
2. Testa en sak åt gången isolerat
Alla klasser bör testas isolerat. De borde inte vara beroende av något annat än håna och stubbarna. De borde inte bero på resultaten från andra tester.
3. Skriv enkla "höger i mitten" -tester först
De första testerna du skriver bör vara de enklaste testerna. Det borde vara de som i princip och enkelt illustrerar den funktionalitet du försöker skriva. Sedan bör du skriva de mer komplicerade testen som testar kanterna och gränserna för din kod när de har gått.
4. Skriv tester som testar kanterna
När grunderna har testats och du vet att din grundläggande funktionalitet fungerar bör du testa kanterna. En bra uppsättning tester kommer att utforska ytterkanten på vad som kan hända med en given metod.
Till exempel:
- Vad händer om ett översvämning inträffar?
- Tänk om värden går till noll eller lägre?
- Vad händer om de går till MaxInt eller MinInt?
- Tänk om du skapar en båge på 361 grader?
- Vad händer om du passerar en tom sträng?
- Vad händer om en sträng är 2 GB stor?
5. Testa över gränserna
Enhetstester bör testa båda sidor av en given gräns. Att flytta över gränser är platser där din kod kan misslyckas eller fungerar på oförutsägbara sätt.
6. Testa hela spektrumet om du kan
Om det är praktiskt kan du testa hela uppsättningen möjligheter för din funktionalitet. Om det handlar om en uppräknad typ, testa funktionaliteten med alla objekt i uppräkningen. Det kan vara opraktiskt att testa alla möjligheter, men om du kan testa alla möjligheter, gör det.
7. Om möjligt, täck varje kodväg
Den här är också utmanande, men om din kod är utformad för testning och du använder ett kodtäckningsverktyg kan du se till att varje rad i din kod täcks av enhetstester minst en gång. Att täcka varje kodväg garanterar inte att det inte finns några buggar, men det ger dig värdefull information om tillståndet för varje kodrad.
8. Skriv tester som avslöjar ett fel och fixa det sedan
Om du hittar ett fel, skriv ett test som avslöjar det. Sedan kan du enkelt fixa felet genom att felsöka testet. Sedan har du ett trevligt regressionstest för att se till att om felet kommer tillbaka av någon anledning, vet du direkt. Det är verkligen lätt att fixa ett fel när du har ett enkelt, rakt fram test för att köra i felsökaren.
En biverkning här är att du har testat ditt test. Eftersom du har sett testet misslyckas och sedan när du har sett det passera, vet du att testet är giltigt eftersom det har visat sig fungera korrekt. Detta gör det till ett ännu bättre regressionstest.
9. Gör varje test oberoende av varandra
Test bör aldrig bero på varandra. Om dina test måste köras i en viss ordning måste du ändra testen.
10. Skriv ett påstående per test
Du bör skriva ett påstående per test. Om du inte kan göra det, refrahera din kod så att dina SetUp- och TearDown-händelser används för att skapa miljön korrekt så att varje test kan köras individuellt.
11. Namnge dina tester tydligt. Var inte rädd för långa namn
Eftersom du gör ett påstående per test kan varje test bli mycket specifikt. Var därför inte rädd för att använda långa, fullständiga testnamn.
Ett långt komplett namn låter dig omedelbart veta vad testet misslyckades och exakt vad testet försökte göra.
Långa, tydligt namngivna tester kan också dokumentera dina tester. Ett test med namnet "DividedByZeroShouldThrowException" dokumenterar exakt vad koden gör när du försöker dela med noll.
12. Testa att varje undantag faktiskt tas upp
Om din kod ger ett undantag, skriv sedan ett test för att säkerställa att varje undantag du faktiskt höjer när det är tänkt.
13. Undvik att använda CheckTrue eller Assert.IsTrue
Undvik att kontrollera för ett booleskt tillstånd. Om du till exempel kontrollerar om två saker är lika med CheckTrue eller Assert.IsTrue, använd CheckEquals eller Assert.IsEqual istället. Varför? På grund av detta:
CheckTrue (förväntat, faktiskt) Detta kommer att rapportera något som: "Vissa test misslyckades: Förväntat var sant men faktiskt resultat var falskt."
Det här säger ingenting.
CheckEquals (förväntat, faktiskt)
Detta kommer att säga något som: "Vissa test misslyckades: Förväntat 7 men faktiskt resultat var 3."
Använd endast CheckTrue eller Assert.IsTrue när ditt förväntade värde faktiskt är ett booleskt tillstånd.
14. Kör hela tiden dina tester
Kör dina tester medan du skriver kod. Dina tester bör köras snabbt, så att du kan köra dem efter ännu mindre förändringar. Om du inte kan köra dina tester som en del av din normala utvecklingsprocess så går något fel. Enhetstester ska köras nästan omedelbart. Om de inte är det, beror det antagligen på att du inte kör dem isolerat.
15. Kör dina tester som en del av varje automatiserad build
Precis som du bör testa medan du utvecklar, borde de också vara en integrerad del av din kontinuerliga integrationsprocess. Ett misslyckat test bör innebära att din byggnad är trasig. Låt inte misslyckade test dröja. Betrakta det som ett byggfel och fixa det omedelbart.
Exempel på enkel enhetstest i C #
För detta exempel testar vi summan metoden för en enkel räknare.
I det här exemplet testar vi applikationen: ApplicationToTest. Den här har en klass som heter Calc. Denna klass har en metod Sum ().
Metoden Sum () ser så här ut:
public void Sum(int a, int b)
{
return a + b;
}
Enhetstestet för att testa den här metoden ser ut så här:
[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);
}
}