Uważasz, że im więcej masz testów (jednostkowych, integracyjnych, jakich-tam-jeszcze-chcesz) tym lepszy jest twój kod? I bardziej niezawodny system tworzysz? Też tak myślałem... kiedyś. Sama ILOŚĆ kodu testującego o niczym jednak nie świadczy. Dzisiaj cytat potwierdzający mój zwrot w poglądach na tą sprawę: Writing code in a testing namespace doesn’t count much in the way of testability Źródło: Udi Dahan

Niekiedy test jednostkowy sprawdza poprawność jakiegoś skomplikowanego algorytmu bądź parsera tekstu bądź czegokolwiek, co wymaga znacznych ilości danych. Zamiast umieszczać te dane w kodzie, niejednokrotnie wygodniej jest po prostu wrzucić je do pliku, plik dodać do projektu i ustawić jego właściwość "Copy to Output Directory" na Always. W normalnej sytuacji pobralibyśmy dane o tak: 1: string filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Locatio... [More]

Testowanie kodu wielowątkowego jest nie lada wyzwaniem. Teoretycznie powinno się tego unikać, ale czasami nie ma innego wyjścia. Co robić w sytuacji, gdy w komponencie tworzonym podczas naszego testu uruchamiany jest nowy wątek, a w nim wyskakuje wyjątek? Test oczywiście nie przechodzi, ale wcale niekoniecznie musimy wiedzieć dlaczego tak a nie inaczej się stało. Kiedyś pół godziny straciłem na wgapianie się w monitor zanim wpadłem na to, że w wątku pobocznym wyskakuje wyjątek. Bo jak wiadomo, w... [More]

Niedawno opublikowałem posta o tym, jak nie należy pisać testów jednostkowych. Przytoczony przykład powodował bezsensowną duplikację kodu w aplikacji i testach. Dzisiaj bardzo krótka demonstracja tego, jak można zastosować atrybut ValuesAttribute z NUnit 2.5 do wygenerowania testów dla więcej niż jednej wartości naraz. Testować będziemy klasę, która oblicza 22%-ową stawkę podatku VAT. Jej implementacja jest oczywiście banalna: 1: public class VatCalculator 2: { 3: public double... [More]

PrincipalMock

30 października 2009 09:01 w kategorii: pro
Tagi: , ,
Podczas pisania testów jednostkowych możemy natknąć się na problem uprawnień – co jeśli testowana metoda wymaga, aby użytkownik był zalogowany, miał określoną nazwę bądź był przypisany do konkretnej roli? Nie chcemy przecież, aby testy jednostkowe w jakiś sposób logowały się do naszej aplikacji. Rozwiązaniem jest pomocnicza klasa, którą napisałem z wykorzystaniem frameworka Moq: 1: public static class PrincipalMock 2: { 3: public static IPrincipal Create(string name, params stri... [More]

Jak nie pisać testów jednostkowych

26 października 2009 07:31 w kategorii: pro
Tagi:
Testy jednostkowe pełnią dwie bardzo ważne role: poprawiają design aplikacji sprawdzają czy kod jest poprawny Drugi aspekt można rozumieć dwojako... Spójrzmy na przykładową metodę kalkulatora: 1: public class Calculator 2: { 3: public int Add(int first, int second) 4: { 5: return first + second; 6: } 7: 8: // more operations... 9: } Jej przetestowanie nie powinno sprawiać nikomu problemu. Ale... czy na pewno? Jestem przekonany, że... [More]

[Spis treści] Cykl o mock objects i Rhino Mocks

29 września 2009 07:36 w kategorii: pro
Tagi: ,
Dobiegł końca pierwszy na tym blogu cykl (chociaż posty pojawiały się częściej niż "teoretycznie co 28 dni") technicznych postów rozprawiających się z jednym zagadnieniem krok po kroku. A konkretnie: pisaniem testów jednostkowych z wykorzystaniem "obiektów mockujących" dostarczanych przez mechanizm zaimplementowany w bibliotece Rhino Mocks. Pomyślałem że dobrze będzie zebrać w jednym miejscu to co się wykluło od jego powstania do jego zakończenia, zatem poniżej spis postów p... [More]

Dzisiaj spojrzymy na sytuację, w której będziemy potrzebowali nie weryfikować, ale zapamiętać wartości przekazywane do mock objects w celu późniejszego ich wykorzystania. Scenariusz ten jest dość nietypowy, w moim przypadku SUT (System Under Test) rejestrował pewną operację w komponencie odpowiedzialnym za jej uruchomienie w odpowiednim momencie.  wykonanie. Rejestracja odbywała się z wykorzystaniem wyrażeń lambda, więc przetesowanie rejestrowanej akcji w sposób "zwykły" nie było ... [More]

Generalnie moment, w którym natkniemy się na potrzebę przetestowania testami jednostkowymi klasy abstrakcyjnej powinien być momentem okrzyku: "refactoring czas zacząć!". Takie coś teoretycznie nie powinno mieć miejsca; testuje się raczej funkcjonalność faktycznie wykorzystywaną w systemie, a więc bardziej klasy z niej dziedziczące. Odpowiednia hierarchia klas uzupełniona odpowiednią hierarchią testów jednostkowych rozwiązuje problem. Ale wiadomo – ideały sobie, a życie sobie. Cóż więc... [More]

Zdarzenia w mock objects

26 sierpnia 2009 06:27 w kategorii: pro
Tagi: ,
Testowanie obsługi zdarzeń oraz faktu ich wywołania jest niekiedy równie ważne co przetestowanie każdej innej integracji pomiędzy dwoma obiektami. Scenariusz jest na tyle specyficzny, że poświęcę mu osobną notkę. Wywoływanie zdarzeń Zapomnijmy na razie o maglowanym przez ostatnie kilka wpisów kontrolerze i spójrzmy na inną sytuację. Wyobraźmy sobie, że mamy w systemie klasę odpowiedzialną za podpinanie się pod różne zdarzenia i logowanie ich w celach diagnostycznych. Jednym z takich zdarzeń mo... [More]

Konfiguracja zachowania metod dla stubów

7 sierpnia 2009 06:39 w kategorii: pro
Tagi: ,
Po poprzednim odcinku potrafimy już dowolnie weryfikować i konfigurować wartości parametrów dla metod. Dzisiaj z kolei poustawiamy akcje, które mają się w momencie wywołania metod wykonać. Jest to czynność zdecydowanie prostsza, ponieważ właściwie wszystko mamy w Intellisense. Zobaczmy: Zwracana wartość Najprostsza możliwa konfiguracja to ustawienie wartości zwracanej przez metodę. Obiekt implementujący interfejs IMethodOptions<T> zwracany przez Stub(...) posiada konstrukcję Return(...) ... [More]

Weryfikacja parametrów metod w mock objects

3 sierpnia 2009 08:22 w kategorii: pro
Tagi: ,
Dość sporo teorii mamy za sobą, nadeszła więc pora na praktyczne przykłady. Tym razem spojrzymy na konfigurację zachowania stubów w zależności od parametrów przekazywanych do ich metod (oraz analizę wartości przekazanych do mocków przez testowane obiekty, co jest scenariuszem bardzo podobnym technicznie). Konkretne wartości W poniższym przypadku konfigurujemy zachowanie authenticationService tylko dla jednej pary parametrów o wartościach przekazanych w zmiennych userName i password. Każde inne... [More]

Zgłębiając arkana tworzenia testów jednostkowych z wykorzystaniem mock objects możemy natknąć się na trzy szkoły/sposoby pisania kodu. Zwykle możliwe jest zastosowanie więcej niż jednego podejścia za pomocą danej biblioteki. Wszystkie jednak charakteryzują się podobnymi "etapami": musimy stworzyć środowisko testowe, wykonać testowane operacje oraz sprawdzić ich poprawność. Różnice polegają na składni oferowanej przez framework oraz niejawnych założeniach sygnalizowanych przez daną meto... [More]

Dynamic Mock vs Strict Mock vs Stub

27 lipca 2009 06:06 w kategorii: pro
Tagi: ,
Zapoznając się z tematyką testów jednostkowych napotykamy podział mocków na trzy grupy: Dynamic Mock, Strict Mock oraz Stub. Dziś pora na poruszenie tego tematu wraz z prezentacją jak je wykorzystać w Rhino Mocks. Stub Stub jest niczym innym jak głupią i najprostszą implementacją zadanego interfejsu. Nie możemy go w żaden sposób przetestować, nie możemy sprawdzić jakie metody zostały na nim wywołane. Stub ma jednak jedną cechę, która czyni go niezastąpionym elementem testów jednostkowych: może... [More]

Wybór mock-object framework

22 lipca 2009 06:35 w kategorii: pro
Tagi: ,
Przed rozpoczęciem wykorzystywania mocków w swoim projekcie musimy zdecydować się z jakiego wspomagacza skorzystamy. Wiemy jedno: nie chcemy tworzyć mocków ręcznie (jak zostało to przedstawione tutaj). Zobaczmy więc co nam, programistom .NET, oferuje w tym zakresie wszechposiadający, uzależniający i niczym tlen niezastąpiony INTERNET. Nie jest moim zamierzeniem dokładna prezentacja i porównanie dostępnych rozwiązań - rzucę raczej okiem na kilka możliwych ścieżek. Przed dalszą lekturą można na ... [More]

Pisząc testy jednostkowe często musimy brać skądś testowe wartości, których wykorzystanie będziemy następnie weryfikować. Przy okazji ostatniego posta mieliśmy takie linijki: 1: string userName = "testUserName"; 2: string password = "testPassword"; Łatwo jednak sobie wyobrazić ile takich miejsc może pojawić się w skali całego projektu. Tysiące! I czy będzie się komuś chciało nadawać każdej zmiennej sensowną wartość? Wątpię. Z pewnością bardzo szybko da się za... [More]

Mock Objects - pierwszy test krok po kroku

16 lipca 2009 06:31 w kategorii: pro
Tagi: ,
W poprzednim poście zapoznaliśmy się z pojęciem "mock". Dzisiaj krok po kroku napiszemy pierwszy test jednostkowy z wykorzystaniem ASP.NET MVC, nUnit oraz RhinoMocks. Do dzieła. 1) Tworzymy projekt ASP.NET MVC Z odpowiedniej strony ściągamy instalator i... instalujemy. W VS wchodzimy w okno tworzenia nowego projektu i w sekcji Web wybieramy aplikację ASP.NET MVC. Po podaniu nazwy i lokalizacji kreator spyta nas czy utworzyć projekt dla testów jednostkowych. Jak widać domyślnie na liś... [More]

To co teraz czytacie jest początkiem serii postów o tworzeniu testów jednostkowych z użyciem mocków (btw: zna ktoś polskie tłumaczenie tego słowa?). Jak na początek przystało – dziś krótkie wprowadzenie. Testy jednostkowe badające poprawność zależności i integracji na poziomie pojedynczych klas wykorzystują specjalnie spreparowane, proste i na swój sposób "głupie" implementacje wymaganych przez dany komponent części systemu. Między innymi stąd tyle mówi się o Inversion of Control, c... [More]

Resharper 4.1 i MbUnit

19 lutego 2009 21:18 w kategorii: pro
Dziś miałem do czynienia z projektem, w którym do testów jednostkowych wykorzystano framework MbUnit. Oczywiście testy te zapragnąłem uruchomić za pomocą Resharpera (o którym napisałem już dużo). "Domyślnie" jednak zmuszeni jesteśmy buzię otworzyć i zrobić 'o-oo', gdyż R# potrafi obchodzić się jedynie z nUnit: Na szczęście ktoś mądry zauważył to niedociągnięcie i postanowił temu zaradzić. Tak powstała wtyczka do Resharpera: mbunit-resharper. Całość to mały plik .zip z kilkoma dllkami i batcha... [More]

Testowanie wystąpienia zdarzenia

24 listopada 2008 19:28 w kategorii: pro
Podczas implementacji testów jednostkowych zachodzi czasami potrzeba napisania kodu weryfikującego zachowanie obiektów po wystąpieniu zdarzeń. Scenariusz taki jest wspierany przez tzw "mocking frameworks". Za świetny przykład może służyć odświeżony w wersji 3.5 mechanizm biblioteki Rhino.Mocks ze swoją metodą rozszerzającą Raise. Co jednak w sytuacji odwrotnej, gdy nie chcemy badać reakcji na zdarzenie, a jedynie upewnić się, że zostało ono wywołane? Sposób przedstawiony tutaj ("Test Event Was ... [More]