Kurs TDD cz. 10: Teorie

Doskonałym uzupełnieniem wpisów o testach parametryzowanych i kombinatorycznych jest omówienie tzw. „teorii”. Teoria jest specjalnym rodzajem testu, w którym weryfikujemy dane twierdzenie przy pomocy założeń (ang. assumptions).

Dla porównania:

  • W zwykłym teście dostarczamy zbiór danych wejściowych metodzie testowanej, a następnie weryfikujemy zbiór danych wyjściowych ze zbiorem danych wyjściowych oczekiwanych.
  • Teoria ma na celu weryfikację ogólnego twierdzenia dla danych wejściowych spełniających żądane kryteria.

Rozbijmy teorię teorii na czynniki pierwsze i wtedy wszystko stanie się jasne i proste…

Czytaj dalej

Kurs TDD cz. 9: Testy kombinatoryczne i sekwencyjne

Naturalnym krokiem po omówieniu testów parametryzowanych jest przejście do testów kombinatorycznych i sekwencyjnych. Do dyspozycji mamy dwa atrybuty NUnita — [Combinatorial] oraz [Sequential]. Sprawa jest bardzo prosta, więc zrozumienie działania tych dwóch funkcjonalności nie przysporzy żadnych problemów.

Bieżący kod z tego kursu znajduje się na GitHubie: https://github.com/dariusz-wozniak/TddCourse/.

Czytaj dalej

C# Pro Tip: Nested object initializer syntax

W C# istnieje mało znana składnia do inicjalizacji zagnieżdzonych obiektów (nested object initializer syntax). Po raz pierwszy zetknąłem się z nią przy okazji lektury The C# Programming Language (Covering C# 4.0), a później przy sugestii ReSharpera.

Na czym polega cała zabawa?

Spójrzmy na kod, za pomocą którego inicjalizujemy zagnieżdżony obiekt:

Rectangle rectangle = new Rectangle
{
    P1 = { X = 0, Y = 1 },
    P2 = { X = 2, Y = 3 }
};

Czytaj dalej

Kurs TDD cz. 8: Testy parametryzowane

Temat testów parametryzowanych pojawił się przy okazji pisania naszego „drugiego” testu jednostkowego. Wtedy to skorzystaliśmy z atrybutu [TestCase] pozwalającym na zdefiniowanie zestawów wartości, które są przekazywane do metody testowej. Stosując atrybuty do testów parametryzowanych (m. in. TestCase, Values, Range, Random) ograniczamy liczbę naszych metod testowych i redukujemy ilość redundantnego kodu. Ponadto, zyskujemy na czytelności naszych testów.

Kod źródłowy do kursu TDD pojawił się na GitHubie i jest dostępny pod adresem: https://github.com/dariusz-wozniak/TddCourse. Zapraszam do ściągania i dalszej lektury…
Czytaj dalej

Kurs TDD cz. 7: Inicjalizacja i czyszczenie danych (SetUp i TearDown)

W tej części kursu zajmiemy się pojęciem inicjalizacji i czyszczenia danych. Wielkiej filozofii tutaj nie ma; w NUnit działa to tak:

  • Jeśli chcemy, aby jedna z metod uruchamiała się przed każdym uruchomieniem naszego testu, aby np. inicjalizować dane, nakładamy na nią atrybut [SetUp].
  • Jeśli zechcemy, aby metoda uruchamiała się po każdym uruchomieniu testu w celu np. czyszczenia danych — nakładamy atrybut [TearDown].

Reguły gry są jasne:

  • Jeśli użyjemy więcej niż jeden atrybut [SetUp] i [TearDown] dla jednego [TestFixture], to kod skompiluje się poprawnie, ale testy nie uruchomią się.
  • Jeśli chcemy natomiast uruchomić kod jednorazowo przed wywołaniem\po wywołaniu wszystkich naszych testów w obrębie [TestFixture], możemy skorzystać z atrybutów [TestFixtureSetUp] i [TestFixtureTearDown].

Czytaj dalej

Kurs TDD cz. 6: Dobre i złe praktyki testów jednostkowych

W tej części opisane zostaną dobre i złe praktyki stosowane przy pisaniu testów jednostkowych. Co ciekawe, praktyki te odbiegają niekiedy od ogólnie przyjętych założeń i standardów kodowania. Przykładem może być zasada DRY—Don’t Repeat Yourself. W TDD kopiuj-wklej to niemal chleb powszedni; w TDD możemy stosować zasadę zgoła odwrotną—Do Repeat Yourself! Taka odrębność wynika z tego, że w kodzie testowym musimy zminimalizować prawdopodobieństwo pojawienia się błędu. Kod testowy musi być też bardzo prosty i czytelny. Kod testowy nie jest kodem produkcyjnym i w konsekwencji nie będziemy mieli potrzeby rozwijania kodu ani jego funkcjonalności.

Czytaj dalej