Unit testing is een techniek waarbij individuele stukjes code (units) automatisch getest worden om te controleren of ze correct functioneren. Dit helpt bij het vroegtijdig opsporen van fouten en zorgt voor betrouwbare software.
Casus
Een webshop heeft een methode voor het bereken van de totale prijs van een bestelling. Om te controleren of deze methode werkt zoals verwacht wordt, kan een test wordt bedacht om de totale prijs te checken. In plaats van zelf het systeem te gebruiken en handmatig de waarden in te voeren, kan gebruik gemaakt worden van unit testing om deze test te automatiseren.
Hoe zit unit testing in elkaar?
Een unit test bestaat uit een testmethode die een specifieke methode of klasse controleert. De test vergelijkt de werkelijke output met de verwachte output en geeft een melding als deze afwijken. Unit testen zijn opgebouwd aan de hand van een patroon. Dit patroon is opgebouwd in drie onderdelen:
Arrange: In dit gedeelte worden alle waarden en klassen geïnitialiseerd en klaargezet om gebruikt te worden in het volgende onderdeel.
Act: In dit gedeelte wordt de daadwerkelijke actie uitgevoerd die getest moet worden (bijvoorbeeld het aanroepen van een methode).
Assert: Hier wordt het verwachte resultaat vergeleken met het werkelijke resultaat om te controleren of de test slaagt of faalt.
Codevoorbeeld
using Systemusing NUnit.Framework;[TestFixture]public class CalculatorTests { [Test] public void Sum_AddTwoNumbers_ReturnsSum() { //Arrange Calculator calc = new Calculator(); int getal1 = 2; int getal2 = 3; //Act int resultaat = calc.Sum(getal1, getal2); //Assert Assert.AreEqual(5, resultaat); }}
In dit codevoorbeeld wordt gebruik gemaakt van NUnit als unit test framework. Dit zal verder in het volgende kopje worden behandeld.
Naamgeving van testen
Om een duidelijk overzicht te geven wat in een unit test getest wordt. Hierbij zijn de volgende onderdelen van belang om te overwegen:
Methode naam (Bijvoorbeeld Sum)
Testscenario (Bijvoorbeeld AddTwoNumbers)
Verwacht resultaat (Bijvoorbeeld ReturnsSum)
Deze naamgeving is ook in het codevoorbeeld opgenomen.
Hoe gebruik je unit testing?
Unit testing wordt uitgevoerd met een testframework, zoals NUnit, xUnit of MSTest in C#. Dit framework draait testmethodes en rapporteert of ze slagen of falen. In Visual Studio worden deze drie frameworks aangeboden bij het aanmaken van een testproject.
Verschillen tussen frameworks
NUnit: Veelgebruikte en krachtige testframework met uitgebreide assert-functionaliteiten. Ideaal voor projecten die een breed scala aan assert-methodes nodig hebben.
xUnit: Modern alternatief met een eenvoudiger ontwerp en betere integratie met ASP.NET Core. Voorkeur voor ontwikkelaars die werken aan moderne applicaties met dependency injection.
MSTest: Het officiële testframework van Microsoft, goed geïntegreerd met Visual Studio. Geschikt voor teams die gebruik maken van Microsoft-technologieën en officiële ondersteuning willen.
Waarom de een boven de ander kiezen
Kies NUnit als je een krachtig en goed gedocumenteerd framework wilt met veel ingebouwde assert-functionaliteiten.
Kies xUnit als je een minimalistisch framework wilt dat goed aansluit op moderne ontwikkelingspatronen zoals dependency injection.
Kies MSTest als je een testframework nodig hebt dat naadloos werkt met Microsoft-tools en Visual Studio zonder extra configuratie.
Elk testframe heeft een verschillende manieren om testen aan te maken. Hierbij is het mogelijk om één testcase per test te maken of een test waar meerdere testcases op getest kunnen worden.
Casus
Input:a = 2 en b = 3
Verwachte output: 5
Werkelijke output: 5, dus Test geslaagd!
Mogelijke methode die getest moet worden van de casus
public class Calculator {
public int Som(int a, int b) {
return a + b;
}
}
Mogelijke uitwerking voor NUnit
using Systemusing NUnit.Framework//Met test cases[TestFixture]public class CalculatorTests { private readonly Calculator calculator = new Calculator(); [TestCase(1, 2, 3)] [TestCase(0, 0, 0)] [TestCase(-1, 1, 0)] [TestCase(-2, -3, -5)] public void Som_TweeGetallen_GeeftVerwachtResultaat(int a, int b, int verwacht) { Assert.AreEqual(verwacht, calculator.Som(a, b)); } }//Zonder test cases[TestFixture] public class CalculatorTests { private readonly Calculator calculator = new Calculator(); [Test] public void Som_PositieveGetallen_GeeftVerwachtResultaat() { var resultaat = calculator.Som(1, 2); Assert.AreEqual(3, resultaat); } [Test] public void Som_NegatieveGetallen_GeeftVerwachtResultaat() { var resultaat = calculator.Som(-1, -2); Assert.AreEqual(-3, resultaat); }}
Mogelijke uitwerking voor XUnit
using Systemusing XUnit//Met InlineDatapublic class CalculatorTests { private readonly Calculator calculator = new Calculator(); [Theory] [InlineData(1, 2, 3)] [InlineData(0, 0, 0)] [InlineData(-1, 1, 0)] [InlineData(-2, -3, -5)] public void Som_TweeGetallen_GeeftVerwachtResultaat(int a, int b, int verwacht) { Assert.Equal(verwacht, calculator.Som(a, b)); } }//Zonder InlineDatapublic class CalculatorTests { private readonly Calculator calculator = new Calculator(); [Fact] public void Som_PositieveGetallen_GeeftVerwachtResultaat() { var resultaat = calculator.Som(1, 2); Assert.Equal(3, resultaat); } [Fact] public void Som_NegatieveGetallen_GeeftVerwachtResultaat() { var resultaat = calculator.Som(-1, -2); Assert.Equal(-3, resultaat); }}
Mogelijke uitwerking voor MSTest
using Systemusing Microsoft.VisualStudio.TestTools.UnitTesting; //Met DataRows[TestClass] public class CalculatorTests { private readonly Calculator calculator = new Calculator(); [TestMethod] [DataRow(1, 2, 3)] [DataRow(0, 0, 0)] [DataRow(-1, 1, 0)] [DataRow(-2, -3, -5)] public void Som_TweeGetallen_GeeftVerwachtResultaat(int a, int b, int verwacht) { Assert.AreEqual(verwacht, calculator.Som(a, b)); } }//Zonder DataRows[TestClass] public class CalculatorTests { private readonly Calculator calculator = new Calculator(); [TestMethod] public void Som_PositieveGetallen_GeeftVerwachtResultaat() { var resultaat = calculator.Som(1, 2); Assert.AreEqual(3, resultaat); } [TestMethod] public void Som_NegatieveGetallen_GeeftVerwachtResultaat() { var resultaat = calculator.Som(-1, -2); Assert.AreEqual(-3, resultaat); }}