NUnit Testy jednostkowe służą do walidacji, jak i weryfikacji działania klas i ich metod. W poważnych firmach testy jednostkowe są codziennością, gdyż  ręczne testowanie zajmuje więcej czasu. Także  człowiek jest bardziej omylny niż maszyna, czyli jego proces testowania  może być omylny.

W tym tutorialu opiszę, jak za pomocą kilku kroków  stworzyć  prosty test jednostkowy w NUnity.Chociaż  wypadałoby powiedzieć parę słów o programie NUnit. NUnit to framework open source do testów jednostkowych w platformie .NET. Spełnia takie same cele jak JUnit, który weryfikuje aplikacje Javy. Jak widać jest kilka framework z rodziny xUnit. 

Na sam początek pobierz najnowszą wersje NUnit ze strony.

http://www.nunit.org/

Prosta aplikacja, która będzie testowana

Utworzyłem w Visual Studio projekt aplikacji konsolowej , w tym wypadku może to być również projekt Class Library, gdyż będziemy testować jedną z klas w projekcie.
O to klasa “Calculator”, która posiada w sobie parę metod statycznych. Klasa musi być publiczna aby w przyszłości nasza aplikacja testująca miała do niej dostęp.

public static class Calculator
    {
    public static string Multiply (float arg1,float arg2)
    {
    return (arg1 * arg2).ToString();
    }

    public static string Divide (float arg1,float arg2)
    {
    return (arg1 % arg2).ToString();
    }

    public static string Adding (float arg1,float arg2)
    {
    return (arg1 + arg2).ToString();
    }

    public static string Substract(float arg1, float arg2)
    {
    Thread.Sleep(4000);
    return (arg1 - arg2).ToString();
    }

    }

Celowo umieściłem dwa błędy w tej klasie. Metoda, która ma wykonywać proces dzielenia tak naprawdę wykonuje proces dzielenia modulo. A odejmowanie wykona się dopiero po 4 sekundach , ponieważ wątek główny do tego czasu jest uśpiony. 

Zanim przejdziemy do aplikacji testującej określimy jakie wymagania powinna mieć nasza  poprawnie działająca klasa kalkulator.

Metoda arg1 arg2 Wynik Inne Wymagania
Adding 10 20 30 -
Substract 50 50 0 Powinien  wykonać się szybciej niż w 4 sekundy
Divide 14,16,25 4,4,5 3.5,4,5 -
Multiply Losowy 0 0 Każdy argument pomnożony przez 0 powinien dać zero.

Tworzenie aplikacji testującej

Wybierz z menu Visual Studio “File/Add New Project” i stwórz nowy “Class Project”. Do tego nowego projektu trzeba dodać referencje NUnit (nunity.framework.dll) . Poniższy obrazek pokazuje domyślną ścieżkę instalacyjną NUnit. 

Referencja NUnit

Do projektu trzeba też dodać referencje naszego programu, który ma być testowany w tym wypadku “SimpleNunit”.

NUnity referencje

Naturalnie by użyć klas wewnątrz tych bibliotek musimy dodać klauzurę using z przestrzeniami nazw.

using NUnit.Framework;
    using SimpleNunit;

Następnie utwórz klasę z atrybutem “TestFixture”. Kiedy stworzysz metodę z atrybutem “Test’ będziemy mieli w niej nasz test.

[TestFixture]
    public class TestingClass{
    [Test]
    public void TestCalculatorAdding()
    {
    string sol = Calculator.Adding(10, 20);
    Assert.AreEqual("30",sol);
    }
    }

Jak widać metoda “TestCaculatorAdding”  używa metody statycznej  Adding w klasie Calculator . Zapisuje wynik do napisu “sol”. Później za pomocą komendy “Assert” sprawdza czy spodziewany rezultat jest równy wynikowi.

Posiadając już tą prostą metodę możesz już teraz uruchomić program NUnit i otworzyć bibliotekę aplikacji testującej. W programie tylko trzeba wycisnąć przycisk Run i już możemy sprawdzić czy klasa kalkulator działa poprawnie. Jeśli zobaczysz kolor zielony wszystko działa poprawnie.

Po co to wszystko
Lampka Dobra , ale jaki w tym sens. Dlaczego muszę sprawdzać proste dodawanie w jakiś programie x i jeszcze do tego napisać swoją bibliotekę testującą? To może wydawać się dziwne , ale tak jak pisałem wcześniej , na co dzień w poważnych firmach zmiany w programach są wprowadzane dość często , a sam proces testujący jest traktowany dość poważnie i skrajnie paranoicznie.

W programowaniu tam, gdzie jest wielka kasa, tam jest duży złożony projekt , a w złożonych projektach nie powinno się tracić cennego czasu na testowanie i nie ma w nim miejsca na błędy.

Więcej bajerów

Dobra NUnity posiada oczywiście dużo więcej bajerów niż tylko sprawdzenie czy jakaś zmienna x równa się wartości oczekiwanej. Zresztą prawdziwa moc testów jednostkowych wychodzi w czasie klas dziedziczących i innych mechanizmów obiektowości.

O to kolejne metody testujące. Do odejmowanie dodałem atrybut “MaxTime”, który określa, w jakim maksymalnym czasie powinno się wykonać dany test, jeśli przekroczy on wymagany czas test zostanie uznany za niezaliczony.

Do mnożenia zastosowałem atrybut Random, który wybiera losową liczbę z zakresu zmiennej “int” i sam też wykonuje się 100 razy dla 100 losowych argumentów. Oczekujemy , że mnożenie przez 0 powinno zawsze dać zero i tak będzie w tym przypadku.

Dzielenie wykonuje się dla 3 różnych przypadków zmiennych, które są podane za pomocą atrybutu TestCase. Dzielenie nigdy nie wykona się poprawnie, ponieważ tak naprawdę klasa kalkulator wykonuje dzielenie modulo.

[Test]
    [MaxTime(4000)]
    public void TestCalculatorSubstract()
    {

    string sol = Calculator.Substract(50, 50);
    Assert.AreEqual("0", sol);
    }

    [Test]
    public void TestCalculatorMultiply(
    [Random(int.MinValue, int.MaxValue, 100)] float x)
    {
    string sol = Calculator.Multiply(x, 0);
    Assert.AreEqual("0", sol);
    }

    [TestCase(14, 4, "3.5")]
    [TestCase(16, 4, "4")]
    [TestCase(25, 5, "5")]
    public void TestCalculatorDivide(float x,float y,string s)
    {
    string sol = Calculator.Divide(x, y);
    Assert.AreEqual(s, sol);
    }

Testowanie w NUNIT

Aby przetestować aplikację trzeba otworzyć bibliotekę programu testującego. Jak widać 1 test dodawania wykonał się poprawnie oraz 100 testów mnożenia. Dzielenie zawiodło we wszystkich trzech próbach oraz odejmowanie zaszło po 4 sekundach i test został uznany za niezaliczony.

NUnity testowanie aplikacji


[download:http://dl.dropbox.com/u/22340217/DownloadPrograms/SimpleNunit.rar]

Referencje i więcej informacji: Dokumentacja NUnit 2.5.9

Jeśli spodobał ci się ten artykuł to proszę o subskrypcje.