Facebook - konwersja
Czytaj fragment
Pobierz fragment

  • nowość

Test-Driven Development w C# i .NET. Tworzenie wysokiej jakości kodu w architekturze DDD za pomocą znanych narzędzi i bibliotek - ebook

Wydawnictwo:
Data wydania:
28 stycznia 2025
Format ebooka:
EPUB
Format EPUB
czytaj
na czytniku
czytaj
na tablecie
czytaj
na smartfonie
Jeden z najpopularniejszych formatów e-booków na świecie. Niezwykle wygodny i przyjazny czytelnikom - w przeciwieństwie do formatu PDF umożliwia skalowanie czcionki, dzięki czemu możliwe jest dopasowanie jej wielkości do kroju i rozmiarów ekranu. Więcej informacji znajdziesz w dziale Pomoc.
Multiformat
E-booki w Virtualo.pl dostępne są w opcji multiformatu. Oznacza to, że po dokonaniu zakupu, e-book pojawi się na Twoim koncie we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu.
, PDF
Format PDF
czytaj
na laptopie
czytaj
na tablecie
Format e-booków, który możesz odczytywać na tablecie oraz laptopie. Pliki PDF są odczytywane również przez czytniki i smartfony, jednakze względu na komfort czytania i brak możliwości skalowania czcionki, czytanie plików PDF na tych urządzeniach może być męczące dla oczu. Więcej informacji znajdziesz w dziale Pomoc.
Multiformat
E-booki w Virtualo.pl dostępne są w opcji multiformatu. Oznacza to, że po dokonaniu zakupu, e-book pojawi się na Twoim koncie we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu.
, MOBI
Format MOBI
czytaj
na czytniku
czytaj
na tablecie
czytaj
na smartfonie
Jeden z najczęściej wybieranych formatów wśród czytelników e-booków. Możesz go odczytać na czytniku Kindle oraz na smartfonach i tabletach po zainstalowaniu specjalnej aplikacji. Więcej informacji znajdziesz w dziale Pomoc.
Multiformat
E-booki w Virtualo.pl dostępne są w opcji multiformatu. Oznacza to, że po dokonaniu zakupu, e-book pojawi się na Twoim koncie we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu.
(3w1)
Multiformat
E-booki sprzedawane w księgarni Virtualo.pl dostępne są w opcji multiformatu - kupujesz treść, nie format. Po dodaniu e-booka do koszyka i dokonaniu płatności, e-book pojawi się na Twoim koncie w Mojej Bibliotece we wszystkich formatach dostępnych aktualnie dla danego tytułu. Informacja o dostępności poszczególnych formatów znajduje się na karcie produktu przy okładce. Uwaga: audiobooki nie są objęte opcją multiformatu.
czytaj
na laptopie
Pliki PDF zabezpieczone watermarkiem możesz odczytać na dowolnym laptopie po zainstalowaniu czytnika dokumentów PDF. Najpowszechniejszym programem, który umożliwi odczytanie pliku PDF na laptopie, jest Adobe Reader. W zależności od potrzeb, możesz zainstalować również inny program - e-booki PDF pod względem sposobu odczytywania nie różnią niczym od powszechnie stosowanych dokumentów PDF, które odczytujemy każdego dnia.
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
czytaj
na tablecie
Aby odczytywać e-booki na swoim tablecie musisz zainstalować specjalną aplikację. W zależności od formatu e-booka oraz systemu operacyjnego, który jest zainstalowany na Twoim urządzeniu może to być np. Bluefire dla EPUBa lub aplikacja Kindle dla formatu MOBI.
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
czytaj
na czytniku
Czytanie na e-czytniku z ekranem e-ink jest bardzo wygodne i nie męczy wzroku. Pliki przystosowane do odczytywania na czytnikach to przede wszystkim EPUB (ten format możesz odczytać m.in. na czytnikach PocketBook) i MOBI (ten fromat możesz odczytać m.in. na czytnikach Kindle).
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
czytaj
na smartfonie
Aby odczytywać e-booki na swoim smartfonie musisz zainstalować specjalną aplikację. W zależności od formatu e-booka oraz systemu operacyjnego, który jest zainstalowany na Twoim urządzeniu może to być np. iBooks dla EPUBa lub aplikacja Kindle dla formatu MOBI.
Informacje na temat zabezpieczenia e-booka znajdziesz na karcie produktu w "Szczegółach na temat e-booka". Więcej informacji znajdziesz w dziale Pomoc.
Czytaj fragment
Pobierz fragment
79,00

Test-Driven Development w C# i .NET. Tworzenie wysokiej jakości kodu w architekturze DDD za pomocą znanych narzędzi i bibliotek - ebook

Spośród wielu koncepcji tworzenia oprogramowania na szczególną uwagę zasługuje model programowania sterowanego testami - TDD. Zastosowanie podejścia TDD ułatwia utrzymanie wysokiej jakości kodu. Technika ta opiera się na dodawaniu funkcjonalności do produktu dopiero po utworzeniu i przeprowadzeniu testów jednostkowych. TDD coraz częściej jest wyborem szanowanych firm programistycznych.

W tej praktycznej książce przedstawiono zasady TDD na rzeczywistych przykładach z użyciem popularnych frameworków, takich jak ASP.NET Core i Entity Framework. Po zapoznaniu się z solidnym wprowadzeniem do koncepcji TDD dowiesz się, jak można używać Visual Studio 2022 do tworzenia aplikacji internetowej z wykorzystaniem Entity Framework, a także baz danych SQL Server i Cosmos DB. Nauczysz się też korzystać z różnych wzorców, takich jak repozytorium, usługi i budowniczy. Ponadto omówiono tu architekturę DDD i inne najlepsze praktyki stosowane podczas tworzenia oprogramowania, w tym reguły SOLID i wskazówki FIRSTHAND. Nie zabrakło przydatnych uwag o biznesowych aspektach podejścia TDD.

W książce między innymi:

  • testy jednostkowe i mechanizm wstrzykiwania zależności
  • NSubstitute: imitacje i dublery używane podczas testów
  • zastosowanie TDD dla ASP.NET API, Entity Framework i baz danych
  • tworzenie potoków ciągłej integracji za pomocą GitHub
  • zaawansowane scenariusze używania imitacji
  • korzyści z wdrażania podejścia TDD przez zespoły i firmy

TDD wprowadza dobre praktyki i doskonali programistę!

Spis treści

 

Część I. Rozpoczęcie pracy i podstawy TDD

Rozdział 1. Przygotowanie pierwszej implementacji TDD

  • Wymagania techniczne
  • Wybór zintegrowanego środowiska programistycznego
    • Microsoft Visual Studio
    • JetBrains Rider
    • Visual Studio Code
    • Wersje .NET i C#
  • Utworzenie szkieletu rozwiązania razem z testami jednostkowymi
    • Wymagania
    • Utworzenie szkieletu projektu
    • Zapoznanie się z wbudowanymi narzędziami przeznaczonymi do przeprowadzania testów
  • Implementacja wymagań z zastosowaniem programowania sterowanego testami
    • SUT
    • Klasa testów
    • Warunki i oczekiwania
    • Czerwony - zielony
    • Wzorzec AAA
    • Jeszcze więcej testów
  • Podsumowanie
  • Dalsza lektura

Rozdział 2. Wprowadzenie do mechanizmu wstrzykiwania zależności

  • Wymagania techniczne
  • Aplikacja WFA
    • Utworzenie przykładowej aplikacji
    • Dodawanie komponentu odpowiedzialnego za dostarczanie rzeczywistej prognozy pogody
  • Poznawanie mechanizmu wstrzykiwania zależności
    • Typy abstrakcyjne i konkretne
    • Czym jest zależność?
    • Znaczenie zależności
    • Definiuj zależności od abstrakcji, a nie od konkretnej implementacji
  • Wprowadzenie do mechanizmu wstrzykiwania zależności
    • Pierwszy przykład wstrzykiwania zależności
    • Testowanie API
    • Czym jest szew?
    • Odwrócenie kontroli
  • Używanie kontenerów wstrzykiwania zależności
    • Rola kontenera
    • Kontenery podmiotów zewnętrznych
    • Cykl życiowy usługi
    • Refaktoryzacja pod kątem wstrzykiwania zależności
    • Rzeczywisty scenariusz użycia wstrzykiwania zależności
    • Wstrzykiwanie metody
    • Wstrzykiwanie właściwości
    • Lokalizator usługi
  • Podsumowanie
  • Dalsza lektura

Rozdział 3. Rozpoczęcie pracy z testami jednostkowymi

  • Wymagania techniczne
  • Wprowadzenie do testów jednostkowych
    • Czym jest testowanie jednostkowe?
    • Frameworki testów jednostkowych
  • Wyjaśnienie struktury projektu stosującego testy jednostkowe
    • Dodawanie projektu xUnit za pomocą wiersza poleceń
    • Konwencje nazw w projekcie testów jednostkowych
    • Wykonanie przykładowego testu jednostkowego
    • Okno Test Explorer
  • Analiza anatomii klasy testu jednostkowego
    • Konwencja nadawania nazwy klasie
    • Metody testowe
    • Wzorzec "przygotowanie, działanie, asercja"
    • Testowany system
  • Omówienie podstaw frameworka xUnit
    • Atrybuty Fact i Theory
    • Wykonywanie testów
    • Klasa Assert
    • Klasa Record
  • Omówienie powiązań zachodzących między regułami SOLID a testami jednostkowymi
    • Reguła jednej odpowiedzialności
    • Reguła otwarte-zamknięte
    • Zasada podstawień Barbary Liskov
    • Zasada rozdzielania interfejsów
    • Zasada odwrócenia zależności
  • Podsumowanie
  • Dalsza lektura

Rozdział 4. Rzeczywiste stosowanie testów jednostkowych z wykorzystaniem dublerów używanych podczas testów

  • Wymagania techniczne
  • Wprowadzenie do koncepcji dublerów używanych podczas testów
    • Typy dublerów używanych podczas testów
    • Którego rozwiązania należy używać w programowaniu sterowanym testami?
  • Omówienie kolejnych kategorii testów
    • Testy integracyjne
    • Testy sintegration
    • Testy akceptacyjne
    • Wybór kategorii testów
  • Podsumowanie
  • Dalsza lektura

Rozdział 5. Programowanie sterowane testami

  • Wymagania techniczne
  • Filary programowania sterowanego testami
    • Najpierw testy
    • Czerwony, zielony, refaktoryzacja
  • Programowanie sterowane testami w praktyce
    • Utworzenie rozwiązania w wierszu poleceń
    • Dodawanie zadania programistycznego
    • Krótkie podsumowanie
  • Najczęściej zadawane pytania i zastrzeżenia do programowania sterowanego testami
    • Dlaczego potrzebne jest programowanie sterowane testami? Czy nie można po prostu używać testów jednostkowych?
    • Podejście w stylu TDD podczas tworzenia oprogramowania wydaje się nienaturalne
    • Stosowanie programowania sterowanego testami będzie nas spowalniać
    • Czy programowanie sterowane testami ma znaczenie dla startupów?
    • Nie lubię programowania sterowanego testami i wolę najpierw zająć się swoją bazą kodu
    • Testy jednostkowe nie sprawdzają rzeczywistych aspektów kodu
    • Podobno istnieją dwie szkoły w zakresie programowania sterowanego testami - londyńska i klasyczna. Jakie są między nimi różnice?
    • Dlaczego niektórzy programiści nie lubią testów jednostkowych i programowania sterowanego testami?
    • Jaki związek zachodzi między programowaniem sterowanym testami a programowaniem ekstremalnym?
    • Czy system jest w stanie przetrwać bez programowania sterowanego testami?
  • Programowanie sterowane testami i testy sintegration
    • Testy sintegration jako alternatywa dla testów jednostkowych w programowaniu sterowanym testami
    • Wyzwania pojawiające się podczas stosowania testów sintegration
  • Podsumowanie
  • Dalsza lektura

Rozdział 6. Wskazówki FIRSTHAND dotyczące programowania sterowanego testami

  • Wymagania techniczne
  • Wskazówka "pierwszy"
    • Później oznacza nigdy
    • Przygotowanie do użycia mechanizmu wstrzykiwania zależności
    • Opracowanie z perspektywy klienta
    • Promowanie testowania sposobu działania
    • Eliminowanie fałszywych alarmów
    • Eliminowanie kodu spekulatywnego
  • Wskazówka "intencja"
    • NazwaMetody_Warunek_Oczekiwanie
    • NazwaMetody_Should_When
    • Struktura testu jednostkowego
  • Wskazówka "czytelność"
    • Inicjalizacja konstruktora testowanego systemu
    • Wzorzec budowniczego
  • Wskazówka "jeden sposób działania"
    • Czym jest sposób działania?
    • Przykład sposobu działania
    • Testowanie jedynie zewnętrznie zdefiniowanego sposobu działania
    • Dlaczego nie testujemy elementów wewnętrznych?
    • Test sprawdza tylko jeden sposób działania
  • Wskazówka "dokładność"
    • Testy jednostkowe przeznaczone do testowania zależności
    • Co oznacza pokrycie kodu testami?
    • Bycie dokładnym
  • Wskazówka "wysoka wydajność"
    • Integracja jako ukryte jednostki
    • Testy jednostkowe w ogromnym stopniu wykorzystujące procesor i pamięć operacyjną
    • Istnienie zbyt wielu testów
  • Wskazówka "automatyzacja"
    • Automatyzacja począwszy od dnia pierwszego
    • Niezależność od platformy
    • Wysoka wydajność w potoku ciągłej integracji
  • Wskazówka "brak współzależności"
    • Odpowiedzialność frameworka testów jednostkowych
    • Odpowiedzialność programisty
  • Wskazówka "deterministyczność"
    • Przypadki niedeterministycznych testów jednostkowych
    • Przykład zamrożenia czasu
  • Podsumowanie

Część II. Stworzenie aplikacji z zastosowaniem podejścia w stylu TDD

Rozdział 7. Pragmatyczne omówienie architektury DDD

  • Wymagania techniczne
  • Praca z przykładową aplikacją
    • Projekt aplikacji
    • Projekt obiektów kontraktu
    • Projekt warstwy dziedziny
  • Poznawanie dziedzin
    • Obiekty dziedziny
    • Encje i obiekty wartości
    • Agregacja
    • Modele anemiczne
    • Wszechobecny język
  • Poznawanie usług
    • Zarządzanie postem
    • Usługi aplikacji
    • Usługi infrastruktury
    • Cechy charakterystyczne usługi
  • Poznawanie repozytoriów
    • Przykład repozytorium
    • Entity Framework i repozytoria
  • Połączenie wszystkiego w całość
    • Okno Solution Explorer
    • Widok architekturalny
  • Podsumowanie
  • Dalsza lektura

Rozdział 8. Opracowanie aplikacji pozwalającej na rezerwowanie wizyt

  • Wymagania techniczne
  • Zebranie wymagań biznesowych
    • Cele biznesowe
    • Historyjki użytkownika
  • Projektowanie w duchu architektury DDD
    • Obiekty dziedziny
    • Usługi dziedziny
    • Architektura systemu
  • Implementowanie tras
    • Frontend
    • Backend w postaci relacyjnej bazy danych
    • Backend w postaci bazy danych opartej na dokumentach
    • Używanie wzorca mediatora
  • Podsumowanie
  • Dalsza lektura

Rozdział 9. Wykorzystanie Entity Framework i relacyjnej bazy danych do opracowania aplikacji pozwalającej na rezerwowanie wizyt

  • Wymagania techniczne
  • Planowanie kodu źródłowego i struktury projektu
    • Analiza struktury projektu
    • Utworzenie projektów i konfiguracja zależności
    • Konfiguracja projektu dziedziny
    • Przygotowanie Entity Framework
    • Przygotowanie projektu witryny internetowej
  • Implementacja Web API z użyciem programowania sterowanego testami
    • Używanie działającego dostawcy EF dla magazynu danych w pamięci
    • Implementacja pierwszej historyjki użytkownika
    • Implementacja piątej historyjki użytkownika (zarządzanie czasem)
  • Udzielenie odpowiedzi na najczęściej zadawane pytania
    • Czy te testy jednostkowe są wystarczające?
    • Dlaczego nie utworzyliśmy testów jednostkowych dla kontrolerów?
    • Czy system został wystarczająco przetestowany?
    • Pominęliśmy testowanie pewnych obszarów, więc jak osiągnąć wysoki poziom pokrycia testami?
  • Podsumowanie

Rozdział 10. Wykorzystanie wzorca repozytorium i bazy danych opartej na dokumentach do opracowania aplikacji pozwalającej na rezerwowanie wizyt

  • Wymagania techniczne
  • Planowanie kodu źródłowego i struktury projektu
    • Analiza struktury projektu
    • Utworzenie projektów i konfiguracja zależności
    • Konfiguracja projektu dziedziny
    • Wzorzec repozytorium
    • Przygotowanie projektu witryny internetowej
  • Implementacja Web API z użyciem programowania sterowanego testami
    • Implementacja pierwszej historyjki użytkownika
    • Implementacja piątej historyjki użytkownika (zarządzanie czasem)
  • Udzielenie odpowiedzi na najczęściej zadawane pytania
    • Czy te testy jednostkowe są wystarczające?
    • Dlaczego nie utworzyliśmy testów jednostkowych dla kontrolerów?
    • Dlaczego nie utworzyliśmy testów jednostkowych dla implementacji repozytoriów?
    • Czy system został wystarczająco przetestowany?
    • Pominęliśmy testowanie pewnych obszarów, więc jak osiągnąć wysoki poziom pokrycia testami?
  • Podsumowanie

Część III. Zastosowanie programowania sterowanego testami we własnych projektach

Rozdział 11. Wdrożenie potoku ciągłej integracji za pomocą usługi GitHub Actions

  • Wymagania techniczne
  • Wprowadzenie do systemu ciągłej integracji
    • Sposób działania systemu ciągłej integracji
    • Zalety systemu ciągłej integracji
  • Implementacja procesu ciągłej integracji za pomocą usługi GitHub Actions
    • Utworzenie przykładowego projektu w repozytorium GitHub
    • Zdefiniowanie sposobu działania
    • System ciągłej integracji i testowanie
    • Symulowanie testów zakończonych niepowodzeniem
    • Omówienie sposobu działania
  • Podsumowanie
  • Dalsza lektura

Rozdział 12. Praca z uaktualnianymi projektami

  • Wymagania techniczne
  • Analizowanie trudności
    • Obsługa mechanizmu wstrzykiwania zależności
    • Trudności związane z modyfikowaniem kodu źródłowego
    • Trudności związane z czasem i wysiłkiem
  • Strategia pozwalająca na zastosowanie programowania sterowanego testami
    • Rozważ ponowne utworzenie projektu
    • Zmiany kodu źródłowego
    • Natywna obsługa dla mechanizmu wstrzykiwania zależności
    • Poziom pokrycia testami przed dodaniem testów jednostkowych
  • Refaktoryzacja na potrzeby testów jednostkowych
    • Tworzenie egzemplarzy w kodzie
    • Zastępowanie statycznych elementów składowych
    • Zmiana struktury kodu źródłowego
  • Podsumowanie
  • Dalsza lektura

Rozdział 13. Zawiłości związane ze stosowaniem programowania sterowanego testami

  • Trudności techniczne
    • Projekt nowy czy uaktualniany?
    • Narzędzia i infrastruktura
  • Trudności w zespole
    • Doświadczenie zespołu
    • Ochota do działania
    • Czas
  • Trudności biznesowe
    • Korzyści biznesowe wynikające z programowania sterowanego testami
    • Wady testów jednostkowych z perspektywy biznesowej
  • Argumenty za programowaniem sterowanym testami i związane z nim błędne koncepcje
    • Testy jednostkowe, a nie programowanie sterowane testami
    • Testy jednostkowe nie są implementowane przez testerów
    • Sposób tworzenia i obsługi technicznej dokumentacji
    • Mamy niekompetentnych programistów
  • Podsumowanie

Dodatek A. Biblioteki, których najczęściej używa się podczas testów jednostkowych

  • Wymagania techniczne
  • Frameworki testów jednostkowych
    • MSTest
    • NUnit
  • Biblioteki imitacji
    • Moq
  • Biblioteki pomocnicze dla testów jednostkowych
    • Fluent Assertions
    • AutoFixture
  • Dalsza lektura

Dodatek B. Zaawansowane scenariusze związane z używaniem imitacji

  • Wymagania techniczne
  • Utworzenie biblioteki klienta OpenWeather
    • API One Call
    • Utworzenie szkieletu rozwiązania
    • Rozpoczęcie pracy nad implementacją z użyciem programowania sterowanego testami
    • Niezaliczenie i późniejsze zaliczenie testu
    • Podsumowanie
    • Analizowanie skomplikowanych scenariuszy imitacji
  • Dalsza lektura
Kategoria: Programowanie
Zabezpieczenie: Watermark
Watermark
Watermarkowanie polega na znakowaniu plików wewnątrz treści, dzięki czemu możliwe jest rozpoznanie unikatowej licencji transakcyjnej Użytkownika. E-książki zabezpieczone watermarkiem można odczytywać na wszystkich urządzeniach odtwarzających wybrany format (czytniki, tablety, smartfony). Nie ma również ograniczeń liczby licencji oraz istnieje możliwość swobodnego przenoszenia plików między urządzeniami. Pliki z watermarkiem są kompatybilne z popularnymi programami do odczytywania ebooków, jak np. Calibre oraz aplikacjami na urządzenia mobilne na takie platformy jak iOS oraz Android.
ISBN: 978-83-289-1694-4
Rozmiar pliku: 15 MB

FRAGMENT KSIĄŻKI

_Chciałbym podziękować mojej drogiej partnerce Elvirze za utrzymywanie mnie na właściwej drodze, za okazane wsparcie oraz za słowa zachęty podczas pracy nad tą książką. Bez Twojej pomocy to przedsięwzięcie by się nie udało. Dziękuję również moim kochanym synom Robinowi i Charliemu za wyrozumiałość, gdy byłem zajęty pracą._

_Chciałbym też podziękować osobie, które we mnie uwierzyła i mnie zachwyciła, mojemu nauczycielowi dr. Jaberowi M. Jaberowi, a także mojemu ulubionemu autorowi pozycji technicznych Charlesowi Petzoldowi, który zainspirował mnie swoim stylem pisania i prostotą._

_Podziękowania kieruję do redaktorów, którymi są Nithya Sadanandan i Yashi Gupta, za ich cierpliwość do mnie oraz za przekazane uwagi._

_Na koniec chciałbym podziękować korektorowi technicznemu Ahmedowi Ilyasowi za przekazane uwagi i życzliwe opinie co do każdego rozdziału, dzięki którym mogłem z pasją kontynuować pracę._O autorze

ADAM TIBI to mieszkający w Londynie konsultant oprogramowania z przeszło 20-letnim doświadczeniem w pracy z technologiami .NET, Python, stosem Microsoft i Azure. Zajmował się mentoringiem zespołów, projektowaniem architektury, promowaniem podejścia zwinnego, dobrymi praktykami w zakresie opracowywania oprogramowania oraz tworzeniem kodu. Adam pracował dla różnych firm, m.in. Shell, Lloyds Bank, Lloyd’s of London, Willis Towers Watson oraz licznych startupów. Jako konsultant z obszernym portfolio, zdobył solidną wiedzę na temat zawiłości programowania sterowanego testami, którą to podzielił się w niniejszej książce.O korektorze merytorycznym

AHMED ILYAS ma 18-letnie doświadczenie w tworzeniu oprogramowania.

Po opuszczeniu firmy Microsoft zdecydował się założyć własną firmę konsultingową, która oferuje najlepsze rozwiązania dla wielu branż i pomaga znajdować odpowiedzi na rzeczywiste problemy. Do budowania technologii — by zapewnić klientom najlepsze praktyki i wzorce oraz najlepsze oprogramowanie — używa wyłącznie produktów firmy Microsoft. To umożliwia długotrwałą stabilizację i zgodność w nieustannie zmieniającej się branży oprogramowania, a ponadto pomaga programistom z całego świata w ulepszaniu technologii i przesuwaniu ich granic.

Był trzykrotnie nagrodzony przez Microsoft tytułem MVP w dziedzinie C#. Dzięki doskonałej reputacji zdobył ogromną bazę klientów dla swojej firmy konsultingowej Sandler Software LLC, która obsługuje podmioty z wielu różnych branż. Klienci umieszczali go na swoich listach „zatwierdzonych konsultantów” jako zaufanego dostawcę i partnera, co ponownie zaprowadziło go do firmy Microsoft.

W przeszłości wielokrotnie zajmował się korektą książek wydawanych przez Packt Publishing i dziękuje wydawnictwu za to, że ponownie otrzymał taką możliwość.CZĘŚĆ 1
ROZPOCZĘCIE PRACY I PODSTAWY TDD

W tej części kolejno wprowadzę wszystkie koncepcje tworzące podejście programowania sterowanego testami. Rozpocznę od mechanizmu wstrzykiwania zależności, następnie przejdę do dublerów używanych podczas testów, a zakończę wskazówkami i najlepszymi praktykami dotyczącymi podejścia w stylu TDD.

Lektura części I książki zapewni wiedzę niezbędną do tworzenia aplikacji z wykorzystaniem programowania sterowanego testami. Oto rozdziały składające się na tę część:

- Rozdział 1., „Przygotowanie pierwszej implementacji TDD”
- Rozdział 2., „Wprowadzenie do mechanizmu wstrzykiwania zależności”
- Rozdział 3., „Rozpoczęcie pracy z testami jednostkowymi”
- Rozdział 4., „Rzeczywiste stosowanie testów jednostkowych z wykorzystaniem dublerów używanych podczas testów”
- Rozdział 5., „Programowanie sterowane testami”
- Rozdział 6., „Wskazówki FIRSTHAND dotyczące programowania sterowanego testami”ROZDZIAŁ 1.
PRZYGOTOWANIE PIERWSZEJ IMPLEMENTACJI TDD

Zawsze uwielbiałem książki, które rozpoczynały się od krótkiego przykładu przedstawiającego zagadnienia omawiane w tekście, a dopiero później zawierały dokładne omówienie tematu. Dzięki temu wiem, co będę poznawał podczas lektury książki. Chciałbym zastosować takie samo podejście i na początku książki zamieścić przykład w postaci niewielkiej aplikacji.

W tym miejscu zasymuluję minimalne wymagania biznesowe, a podczas ich implementacji przedstawię wybrane koncepcje związane z TESTAMI JEDNOSTKOWYMI i PROGRAMOWANIEM STEROWANYM TESTAMI (ang. _test-driven development_ , TDD ). Nie przejmuj się, jeśli te koncepcje nie są dla Ciebie jasne bądź wymagają dalszych wyjaśnień, ponieważ w tym rozdziale celowo przedstawiam je tylko pokrótce, aby dać Ci przedsmak tego, co znajdziesz w książce. W pozostałej części tekstu znajdziesz dokładne omówienie wszystkich poruszonych tutaj koncepcji.

Muszę dodać, że w książce wymiennie używam pojęć _testów jednostkowych_ i _podejścia w stylu TDD_ , z niewielką różnicą między nimi. Wszystko stanie się jaśniejsze w rozdziale 5.

Natomiast w tym rozdziale poruszam następujące tematy:

- wybór ZINTEGROWANEGO ŚRODOWISKA PROGRAMISTYCZNEGO (ang. _integrated development environment_ , IDE),
- utworzenie szkieletu rozwiązania razem z testami jednostkowymi,
- implementacja wymagań z zastosowaniem programowania sterowanego testami.

Zanim zakończysz lekturę rozdziału, będziesz umiał dość komfortowo tworzyć proste testy jednostkowe za pomocą XUNIT oraz ogólnie poznasz podejście w stylu TDD.

Wymagania techniczne

Kod dla tego rozdziału znajdziesz w repozytorium GitHub pod adresem _https://github.com/PacktPublishing/Pragmatic-Test-Driven-Development-in-C-Sharp-and-.NET/tree/main/ch01_ .

Wybór zintegrowanego środowiska programistycznego

Z perspektywy podejścia w stylu TDD wybór zintegrowanego środowiska programistycznego będzie miał wpływ na Twoją produktywność. Implementacja podejścia wykorzystującego programowanie sterowane testami może być wspomagana przez IDE oferujące możliwości refaktoryzacji i generowania kodu źródłowego. Wybór odpowiedniego środowiska IDE zmniejszy liczbę powtarzających się — i potencjalnie nużących — zadań koniecznych do wykonania.

W kolejnych punktach przedstawię trzy popularne środowiska IDE, które oferują obsługę projektów w języku C#: VISUAL STUDIO ( VS ), VISUAL STUDIO CODE ( VS CODE ) i JETBRAINS RIDER .

Microsoft Visual Studio

W tym rozdziale oraz w pozostałej części książki będę używał _Visual Studio 2022 Community Edition_ — możesz skorzystać również z wydań _Professional_ i _Enterprise_ . Programiści indywidualni mogą bezpłatnie używać wydania _Visual Studio Community Edition_ do tworzenia własnych aplikacji, zarówno bezpłatnych, jak i komercyjnych. Z kolei w przypadku organizacji istnieją pewne ograniczenia. Z pełną treścią licencji oraz ze szczegółami produktu możesz się zapoznać na stronie _https://visualstudio.microsoft.com/vs/_ _community/_ .

Jeżeli masz wcześniejsze wydanie Visual Studio i nie chcesz go uaktualniać, wówczas używane w książce _VS 2022 Community Edition_ możesz zainstalować równolegle z dowolną poprzednią wersją.

Wersje _Visual Studio 2022_ przeznaczone dla platform _Windows_ i _Mac_ zawierają narzędzia wymagane do utworzenia kodu oraz uruchomienia testów. W tej książce wszystkie projekty, rysunki i procedury zostały wykonane z użyciem wydania VS przeznaczonego dla platformy _Windows_ . Możesz je pobrać ze strony _https://visualstudio.microsoft.com/downloads/_ .

Aby można było wykonywać projekty zamieszczone w książce, podczas instalowania VS trzeba zaznaczyć pole wyboru przynajmniej przy _ASP.NET and web development_ , jak pokazałem na rysunku 1.1.

RYSUNEK 1.1. Wybór komponentów w trakcie instalacji Visual Studio

Jeżeli w systemie masz już zainstalowane wcześniejsze wydanie Visual Studio, wówczas możesz sprawdzić, czy komponent _ASP.NET and web development_ jest dostępny. W tym celu wykonaj wymienione tutaj kroki.

1. W Windows przejdź do _Ustawienia/Aplikacje/Zainstalowane aplikacje_ .
2. Odszukaj _Visual Studio_ na wyświetlonej liście aplikacji.
3. Kliknij przycisk przedstawiający pionowy wielokropek (trzy kropki jedna pod drugą).
4. Wybierz opcję _Modyfikuj_ , jak pokazałem na rysunku 1.2.

RYSUNEK 1.2. Modyfikacja ustawień opcji instalacyjnych Visual Studio

Visual Studio to duże oprogramowanie, składające się z wielu komponentów do zainstalowania. Ponadto już po zainstalowaniu to środowisko IDE będzie uruchamiało się wolniej od produktów _Visual Studio Code_ bądź _Rider_ , które również są przedstawione w rozdziale.

ReSharper

JETBRAINS RESHARPER to popularna komercyjna wtyczka przeznaczona dla Visual Studio, która wzbogaca je o wiele dodatkowych funkcjonalności. Z perspektywy programowania sterowanego testami jesteśmy zainteresowani wymienionymi tutaj aspektami:

- REFAKTORYZACJA . Wtyczka ReSharper zapewnia wiele związanych z refaktoryzacją funkcji, które okazują się przydatne na etapie refaktoryzacji kodu źródłowego.
- GENEROWANIE KODU . Ta funkcja okazuje się szczególnie przydatna, gdy najpierw tworzy się testy jednostkowe, a dopiero później generuje kod źródłowy.
- TESTY JEDNOSTKOWE . Wtyczka ReSharper wspomaga istniejące w Visual Studio narzędzia przeznaczone do pracy z testami jednostkowymi oraz zapewnia możliwość współpracy z większą liczbą frameworków testów jednostkowych.

ReSharper to produkt oferowany na zasadzie subskrypcji; dostępna jest jego 30-dniowa wersja próbna. Zachęcam do rozpoczęcia pracy z narzędziami testów jednostkowych w Visual Studio bez użycia wtyczki ReSharper. Gdy poznasz już możliwości VS w tym zakresie, wtedy sięgnij po wtyczkę ReSharper, a dostrzeżesz korzyści, jakie zapewnia.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Uwaga

Każde nowe wydanie Visual Studio zawiera dodatkowe możliwości w zakresie refaktoryzacji i generowania kodu, podobne do oferowanych przez wtyczkę ReSharper. Jednak obecnie to ReSharper ma więcej funkcji zaawansowanych.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

O wtyczce ReSharper wspominam tylko w tym miejscu książki. Więcej informacji na jej temat znajdziesz na stronie _https://www.jetbrains.com/resharper/_ .

JetBrains Rider

_JetBrains_ to firma stojąca za środowiskiem IDE _Rider_ oraz popularną wtyczką do Visual Studio, czyli _ReSharper_ . Jeżeli zdecydujesz się na wybór JETBRAINS RIDER jako środowiska programowania na platformie .NET, wówczas będziesz mieć dostęp do wszystkich funkcjonalności, które są wymagane podczas lektury niniejszej książki. Rider oferuje wiele funkcji, m.in.:

- potężne środowisko WYKONYWANIA TESTÓW JEDNOSTKOWYCH , które może konkurować z oknem _Test Explorer_ w Visual Studio,
- rozbudowane możliwości w zakresie refaktoryzacji i generowania kodu źródłowego, wraz ze znacznie bardziej zaawansowanymi funkcjami niż te dostępne w Visual Studio 2022.

Wymienione punkty mają znaczenie krytyczne podczas budowania systemu z wykorzystaniem podejścia w _stylu TDD_ . Mimo to w książce zdecydowałem się na użycie środowiska Visual Studio zamiast Rider. Niemniej jednak zamieszczone w tekście informacje można zastosować również w przypadku środowiska Rider. Trzeba tylko pamiętać, że Rider korzysta z innego systemu menu i innych skrótów klawiszowych.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Uwaga
VS .NET (wydanie Visual Studio zapewniające obsługę platformy .NET) pojawiło się w lutym 2002 roku, podczas gdy środowisko Rider dopiero w sierpniu 2017 roku. Dlatego też produkt firmy Microsoft jest znacznie częściej używany przez programistów .NET. To miało wpływ na wybór środowiska IDE na potrzeby niniejszej książki.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Więcej informacji na temat środowiska Rider znajdziesz na stronie _https://www.jetbrains.com/rider/_ .

Visual Studio Code

Jeżeli zaliczasz się do zwolenników Visual Studio Code, z zadowoleniem przyjmiesz informację o dodaniu przez Microsoft wizualnej obsługi testów jednostkowych (co ma krytyczne znaczenie w programowaniu sterowanym testami) do wersji Visual Studio Code 1.59, wydanej w lipcu 2021 roku.

VS Code to lekkie środowisko IDE, które zapewnia natywne opcje dotyczące refaktoryzacji oraz obsługuje wiele wtyczek refaktoryzacji opracowanych przez podmioty zewnętrzne. Prostota i elegancja VS Code mogą przyciągać wielu zwolenników programowania sterowanego testami. Jednak dostępna funkcjonalność związana z programowaniem w języku C# — zwłaszcza dla osób z doświadczeniem w stosowaniu podejścia w stylu TDD — nie jest tak zaawansowana jak ta, którą można znaleźć w produktach Visual Studio i Rider.

Wprawdzie w książce korzystam ze środowiska Visual Studio, ale przykłady można dostosować także do Visual Studio Code. Więcej informacji na temat tego produktu znajdziesz na stronie _https://visualstudio.microsoft.com/downloads/_ .

Wersje .NET i C#

Wydanie Visual Studio 2022 jest dostarczane razem z obsługą .NET 6 i C# 10 . Tego wydania będę używał na potrzeby niniejszego rozdziału oraz pozostałej części książki.

W swojej grupie w serwisie LinkedIn przeprowadziłem małą ankietę mającą na celu zebranie od użytkowników informacji o używanych przez nich środowiskach IDE. Wyniki tej ankiety pokazałem na rysunku 1.3.

RYSUNEK 1.3. Wyniki ankiety przeprowadzonej przeze mnie w serwisie LinkedIn

Jak możesz zobaczyć, najwięcej respondentów (58%) używa Visual Studio, przy czym 18% korzysta także z wtyczki ReSharper. Na drugim miejscu znalazł się Rider, który wybrało 24% badanych. Najmniejszą popularnością cieszy się Visual Studio Code (18%). Biorąc pod uwagę fakt, że w ankiecie wzięło udział jedynie 45 respondentów, wyniki są jedynie orientacyjne i na pewno nie odzwierciedlają sytuacji na rynku.

Wybór odpowiedniego środowiska IDE to indywidualna decyzja programisty. Gdy pytam programistę stosującego podejście w stylu TDD o wybrane przez niego środowisko, za każdym razem jestem przekonywany, jak świetne jest używane przez niego środowisko. Reasumując, zdecyduj się na środowisko IDE, które zapewni Ci najlepszą produktywność.

Utworzenie szkieletu rozwiązania razem z testami jednostkowymi

Skoro omówienie wymagań technicznych mamy już za sobą, możemy przejść do zbudowania naszej pierwszej implementacji. Na potrzeby tego rozdziału oraz by skoncentrować się na koncepcjach programowania sterowanego testami, rozpoczniemy od prostych wymagań biznesowych.

Przyjmujemy założenie, że jesteś programistą pracującym dla fikcyjnej firmy UNICORN QUALITY SOLUTIONS INC. ( UQS ), która zajmuje się tworzeniem wysokiej jakości oprogramowania.

Wymagania

Zespoły tworzące oprogramowanie w firmie _UQS_ stosują w trakcie tego procesu podejście zwinne (ang. _agile_ ), więc wymagania biznesowe zostają przedstawione w postaci tzw. HISTORYJEK UŻYTKOWNIKA .

Pracujesz nad biblioteką matematyczną, która będzie miała postać pakietu używanego przez innych programistów. Można założyć, że zajmujesz się opracowaniem funkcjonalności w BIBLIOTECE NUGET przeznaczonej do użycia przez inne aplikacje. Oto historyjka użytkownika, którą wybrałeś do zaimplementowania.

---------------------------------------------------------------------------------------------------------------------
TYTUŁ HISTORYJKI:

_Dzielenie całkowite_

OPIS HISTORYJKI:

_Jako klient biblioteki matematycznej chcę mieć możliwość dzielenia dwóch liczb całkowitych._

KRYTERIA AKCEPTACJI:

_Obsługa danych wejściowych typu Int32 i danych wyjściowych typu decimal._

_Zapewnienie wysokiej dokładności danych wyjściowych bez ich zaokrąglania bądź jedynie z minimalnym zaokrągleniem._

_Obsługa dzielenia liczb całkowitych zarówno podzielnych, jak i niepodzielnych._

_Zgłoszenie wyjątku DivideByZeroException w przypadku dzielenia przez zero._
---------------------------------------------------------------------------------------------------------------------

Utworzenie szkieletu projektu

Dla tej historyjki użytkownika będą potrzebne dwa projekty C#. Pierwszy to BIBLIOTEKA KLAS zawierająca produkcyjny kod źródłowy, a drugi to testy jednostkowe dla tej biblioteki.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Uwaga

Biblioteka klas pozwala na umieszczanie funkcjonalności w module, który następnie może być używany przez wiele aplikacji. Podczas kompilacji powstaje plik tzw. BIBLIOTEKI DOŁĄCZANEJ DYNAMICZNIE (ang. _dynamic-link library_ , DLL). Biblioteka klas nie może funkcjonować samodzielnie, natomiast może działać jako część aplikacji.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Jeżeli nie masz doświadczenia w pracy z biblioteką klas, na potrzeby tej książki możesz ją traktować jako aplikację działającą w konsoli (wiersz poleceń) bądź jako aplikację internetową.

Utworzenie projektu biblioteki klas

Te same projekty zostaną utworzone na dwa sposoby — za pomocą GRAFICZNEGO INTERFEJSU UŻYTKOWNIKA (ang. _graphical user interface_ , GUI ) oraz za pomocą INTERFEJSU WIERSZA POLECEŃ (ang. _command-line interface_ , CLI ). Wybierz preferowany przez siebie sposób bądź ten, w pracy z którym masz doświadczenie.

Użycie graficznego interfejsu użytkownika

Aby utworzyć bibliotekę klas, uruchom Visual Studio i wykonaj przedstawioną tutaj procedurę.

1. Wybierz opcję menu _File/New/Project_ .
2. W wyświetlonym oknie dialogowym wyszukaj element _Class Library (C#)_ .
3. Zaznacz znaleziony element, a następnie kliknij przycisk _Next_ . Na ekranie zostanie wyświetlone okno dialogowe _Add a new project_ , jak pokazałem na rysunku 1.4.

RYSUNEK 1.4. Wyszukiwanie szablonu projektu Class Library (C#)

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Uwaga

Upewnij się, że w oknie widzisz tag C # oraz że _NIE_ został wybrany element _Class Library (.NET Framework)_ . W książce korzystamy z platformy .NET (a nie z klasycznej .NET Framework).
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4. W oknie dialogowym _Configure your new project_ wpisz Uqs.Arithmetic w polu _Project name_ i UqsMathLib w polu _Solution name_ , a następnie kliknij przycisk _Next_ . Spójrz na rysunek 1.5.

RYSUNEK 1.5. Okno dialogowe przeznaczone do konfiguracji nowego projektu

5. W oknie dialogowym _Additional information_ z rozwijanego menu wybierz opcję _.NET 6.0 (Long-term support)_ , jak pokazałem na rysunku 1.6., i kliknij przycisk _Create_ .

RYSUNEK 1.6. Okno dialogowe Additional information

W taki sposób projekt biblioteki klas został przygotowany za pomocą graficznego interfejsu użytkownika _Visual Studio_ .

Użycie wiersza poleceń

Jeżeli preferujesz tworzenie projektu za pomocą wiersza poleceń, w tym miejscu znajdziesz polecenia, które trzeba w tym celu wydać.

1. Utwórz katalog o nazwie _UqsMathLib_ (wydaj polecenie md UqsMathLib ).
2. W wierszu poleceń przejdź do nowego katalogu (wydaj polecenie cd UqsMathLib ), jak pokazałem na rysunku 1.7.

RYSUNEK 1.7. Okno wiersza poleceń zawierające niezbędne polecenia

3. Utwórz plik rozwiązania (z rozszerzeniem _.sln_ ), który zostanie wygenerowany z nazwą odpowiadającą nazwie katalogu — czyli w omawianym przykładzie to plik _UqsMathLib.sln_ . W tym celu wydaj następujące polecenie:
dotnet new sln

4. Utwórz nową bibliotekę klas o nazwie _Uqs.Arithmetic_ w katalogu o tej samej nazwie i użyj platformy _.NET 6.0_ . Oto polecenie, które należy w tym celu wydać:
dotnet new classlib -o Uqs.Arithmetic -f net6.0

5. Nowy projekt dodaj do pliku rozwiązania, co odbywa się przez wykonanie przedstawionego tutaj polecenia.
dotnet sln add uqs.arithmetic

W taki sposób projekt biblioteki klas został przygotowany za pomocą wiersza poleceń.

Utworzenie projektu testów jednostkowych

W tym momencie mamy rozwiązanie zawierające tylko jeden projekt, czyli bibliotekę klas. Kolejnym zadaniem jest dodanie do naszego rozwiązania biblioteki testów jednostkowych. W tym celu skorzystamy z projektu XUNIT TEST PROJECT .

xUnit.net to dostępne bezpłatnie, otwartoźródłowe narzędzie testów jednostkowych dla platformy .NET. Zostało udostępnione na licencji Apache 2. Visual Studio natywnie zapewnia możliwość dodawania i uruchamiania projektów xUnit, więc korzystanie z tego frameworka nie wymaga używania żadnego specjalnego narzędzia ani wtyczki.

Dokładne omówienie xUnit znajdziesz w rozdziale 3.

Będziemy stosować powszechnie przyjętą konwencję nadawania projektom testów jednostkowych nazw w postaci _.Tests.Unit_ . Dlatego też nasz projekt otrzymuje nazwę _Uqs.Arithmetic.Tests.Unit_ .

Zaprezentuję dwa sposoby, na jakie jest możliwe utworzenie projektu testów jednostkowych. Wybierz ten, który Ci bardziej odpowiada.

Użycie graficznego interfejsu użytkownika

Aby utworzyć projekt testów jednostkowych, przejdź do okna _Solution Explorer_ i wykonaj przedstawioną tutaj procedurę.

1. Prawym przyciskiem myszy kliknij plik rozwiązania ( _UqsMathLib_ ).
2. Wybierz opcję menu _Add/New Project…_ , jak pokazałem na rysunku 1.8.

RYSUNEK 1.8. Utworzenie nowego projektu w rozwiązaniu

3. W wyświetlonym oknie dialogowym wyszukaj element _xUnit Test Project_ , wybierz go, a następnie kliknij przycisk _Next_ .
4. W polu _Project name_ wpisz wartość Uqs.Arithmetic.Tests.Unit .
5. Kliknij przycisk _Next_ , wybierz platformę _.NET 6.0_ , a następnie kliknij przycisk _Create_ .

W ten sposób projekt testów jednostkowych został utworzony za pomocą graficznego interfejsu użytkownika Visual Studio. Ten projekt wymaga jeszcze odwołania do biblioteki klas. Aby je dodać, wykonaj wymienione tutaj kroki.

1. W oknie eksploratora rozwiązań prawym przyciskiem myszy kliknij element _Dependencies_ projektu _Uqs.Arithmetic.Tests.Unit_ .
2. Wybierz opcję menu _Add Project Reference…_ .
3. Zaznacz element _Uqs.Arithmetic_ i kliknij przycisk _OK_ .

W ten sposób rozwiązanie zostało w pełni przygotowane za pomocą graficznego interfejsu użytkownika Visual Studio. Tę samą procedurę można przeprowadzić za pomocą wiersza poleceń. Dokładnie to wyjaśnię w następnym podpunkcie.

Użycie wiersza poleceń

Obecnie mamy rozwiązanie zawierające tylko jeden projekt, bibliotekę klas. Kolejnym zadaniem jest dodanie do naszego rozwiązania biblioteki testów jednostkowych.

Utwórz nowy projekt xUnit o nazwie _Uqs.Arithmetic.Tests.Unit_ w katalogu o tej samej nazwie i zdecyduj o użyciu platformy _.NET 6.0_ . Oto polecenie, które trzeba wydać:

dotnet new xunit -o Uqs.Arithmetic.Tests.Unit -f net6.0

Nowy projekt dodaj do pliku rozwiązania, co odbywa się przez wykonanie przedstawionego tutaj polecenia.

dotnet sln add Uqs.Arithmetic.Tests.Unit

W ten sposób nasze rozwiązanie zawiera dwa projekty. Skoro projekt testów jednostkowych jest przeznaczony do testowania biblioteki klas, powinien mieć do niej odwołanie.

Wprawdzie projekt został utworzony za pomocą wiersza poleceń, ale nadal projekt testów jednostkowych musi zawierać odwołanie do biblioteki klas. W tym celu należy dodać odwołanie z _Uqs.Arithmetic.Tests.Unit_ do _Uqs.Arithmetic_ , jak pokazałem w kolejnym fragmencie kodu:

dotnet add Uqs.Arithmetic.Tests.Unit reference

Uqs.Arithmetic

Przedstawione rozwiązanie zostało w pełni przygotowane za pomocą wiersza poleceń.

Ostateczne rozwiązanie

Niezależnie od metody użytej do utworzenia rozwiązania — za pomocą graficznego interfejsu użytkownika bądź wiersza poleceń — w tym momencie będziesz mieć te same pliki. Jeżeli otworzysz rozwiązanie w Visual Studio, zobaczysz okno pokazane na rysunku 1.9.

RYSUNEK 1.9. Struktura ostatecznego rozwiązania

Aby rozpocząć pracę od czystego stanu, usuń plik _Class1.cs_ . Został dodany automatycznie przez szablon i nie będziemy go używać.

Na rysunku 1.10 pokazałem logiczną strukturę dwóch naszych projektów.

RYSUNEK 1.10. Logiczna struktura naszych przykładowych projektów

Dotychczas utworzyliśmy dwa projekty. Pierwszy ( _Uqs.Arithmetic_ ) będzie na pewnym etapie przekazany do środowiska produkcyjnego, natomiast drugi ( _Uqs.Arithmetic.Tests.Unit_ ) jest przeznaczony do przetestowania tego pierwszego projektu. Plik rozwiązania zapewnia połączenie między wymienionymi projektami.

Po zakończeniu tej mniej przyjemnej fazy budowania szkieletu projektu i definiowania zależności można przystąpić do znacznie przyjemniejszych zadań, które są bezpośrednio powiązane z testami jednostkowymi.

Zapoznanie się z wbudowanymi narzędziami przeznaczonymi do przeprowadzania testów

Osiągnęliśmy stan, kiedy trzeba rozejrzeć się oraz sprawdzić, jak wykrywać i wykonywać testy. To będzie wymagało poznania dostępnych narzędzi.

Mamy już kod wygenerowany przez szablon xUnit — zapoznaj się z kodem znajdującym się w pliku _UnitTest1.cs_ i zamieszczonym w kolejnym fragmencie kodu.

using Xunit;

namespace Uqs.Arithmetic.Tests.Unit;

public class UnitTest1

{

public void Test1()

{

}

}

To jest zwykła klasa C#. Fact to atrybut pochodzący z frameworka xUnit. Wskazuje on każdemu narzędziu zgodnemu z xUnit, że metoda udekorowana tym atrybutem jest METODĄ TESTU JEDNOSTKOWEGO . Narzędzia zgodne z xUnit, np. okno _Test Explorer_ i _.NET CLI Test Command_ , powinny mieć możliwość znalezienia tej metody w rozwiązaniu i jej uruchomienia.

Podążając za trendem z wcześniejszej części rozdziału, dostępne narzędzia przeznaczone do przeprowadzania testów można wykorzystać na dwa sposoby — za pomocą graficznego interfejsu użytkownika oraz z poziomu wiersza poleceń.

Użycie graficznego interfejsu użytkownika

Visual Studio oferuje wyposażone w graficzny interfejs użytkownika narzędzie przeznaczone do wykrywania i wykonywania testów — ma ono postać okna o nazwie _Test Explorer_ . Aby zobaczyć, w jaki sposób to narzędzie będzie wykrywało metody testów, z poziomu menu wybierz opcję _Test/Test Explorer_ . Na ekranie pojawi się okno dialogowe pokazane na rysunku 1.11.

RYSUNEK 1.11. Okno Test Explorer wyświetlające niewykonane testy

Jak możesz zobaczyć, to narzędzie wykryło wszystkie testy istniejące w naszym rozwiązaniu oraz wyświetliło je w hierarchii _Nazwa projektu/Przestrzeń nazw/Klasa/Metoda_ . Zwróć uwagę na wyświetlenie hierarchii w kolorze szarym oraz ze znakiem wykrzyknika. Ten znak oznacza, że testy nigdy nie zostały wykonane. Aby uruchomić te testy, możesz kliknąć przycisk URUCHOMIENIA PROJEKTU w lewym górnym rogu okna (skrót klawiszowy _Ctrl+R, T_ — naciśnij i przytrzymaj klawisz _Ctrl_ , a następnie w krótkich odstępach czasu naciśnij kolejno klawisze _R_ i _T_ ). To spowoduje skompilowanie projektu i wykonanie kodu zdefiniowanego w metodach udekorowanych atrybutem Fact . Wynik tej operacji pokazałem na rysunku 1.12.

RYSUNEK 1.12. Okno Test Explorer wyświetla wynik wykonania testów

Nie oczekuj żadnych fajerwerków, ponieważ mamy jedynie pusty szkielet projektu. Jednak przynajmniej testy będą oznaczone kolorem zielonym, co potwierdzi poprawność działania przygotowanego środowiska. W podobny sposób testy można wykrywać i wykonywać za pomocą wiersza poleceń.

Użycie wiersza poleceń

Testy można również wykonywać za pomocą wiersza poleceń. W tym celu należy przejść do katalogu zawierającego rozwiązanie, a następnie wydać przedstawione tutaj polecenie:

dotnet test

Efekt wykonania tego polecenia pokazałem na rysunku 1.13.

RYSUNEK 1.13. Polecenie .NET przeznaczone do wykrywania i wykonywania testów

Możliwość używania tego rodzaju poleceń okazuje się przydatna na późniejszych etapach pracy, gdy zachodzi potrzeba automatyzacji wykonywania testów.

Implementacja wymagań z zastosowaniem programowania sterowanego testami

Przed przystąpieniem do tworzenia jakiegokolwiek kodu rozsądne wydaje się poznanie terminologii i konwencji, aby przygotować się na słownictwo związane z testami jednostkowymi. Dlatego też pokrótce przedstawię koncepcje TESTOWANEGO SYSTEMU (ang. _system under test_ , SUT ), testów typu CZERWONY I ZIELONY (ang. _red/green tests_ ) oraz podejścia typu „ PRZYGOTOWANIE, DZIAŁANIE, ASERCJA ” (ang. _arrange-act-assert_ , AAA ). Więcej informacji na temat tej terminologii znajdziesz w późniejszych rozdziałach. Natomiast w tym miejscu przedstawię jedynie podstawy, które pozwolą na wykonanie kilku testów.

Podczas poznawania terminologii i konwencji ułatwimy sobie implementację rozwiązania. Jedyną kwestią, którą możesz uznać za nową i nietypową, jest to, że w przypadku programowania sterowanego testami najpierw tworzy się test jednostkowy, a dopiero później kod produkcyjny. To jest jeden z najważniejszych aspektów podejścia w stylu TDD i spotkasz się z nim w tym podrozdziale.

SUT

Kod tworzący produkt zwykle jest określany mianem PRODUKCYJNEGO KODU ŹRÓDŁOWEGO . Typowy kod tego rodzaju utworzony z zastosowaniem programowania ZORIENTOWANEGO OBIEKTOWO (ang. _object-oriented programming_ , OOP ) ma postać podobną do tutaj przedstawionej.

public class NazwaKlasy

{

public Type NazwaMetody(...)

{

// Kod wykonujący użyteczne zadania.

}

// Jeszcze więcej kodu.

}

Podczas testowania tego fragmentu kodu test jednostkowy będzie wywoływał metodę o podanej nazwie ( NazwaMetody ) i sprawdzał jej sposób działania. W trakcie działania ta metoda może wywoływać inne elementy klasy, a także może używać innych klas bądź je wywoływać. Kod wykonywany przez tę metodę ( NazwaMetody ) jest określany mianem testowanego systemu (SUT) bądź TESTOWANEGO KODU (ang. _code under test_ , CUT ). Znacznie częściej można spotkać to pierwsze określenie, SUT.

Testowany system będzie oferować punkt wejścia, który następnie będzie wykorzystywany przez testy jednostkowe. Ten punkt wejścia to najczęściej metoda wywoływana z poziomu testów jednostkowych. Na rysunku 1.14 pokazałem w sposób graficzny ideę testowanego systemu i punktu wejścia.

RYSUNEK 1.14. Testy jednostkowe działające w SUT

W sytuacji pokazanej na rysunku 1.14 można zobaczyć kilka testów jednostkowych wywołujących ten sam punkt wejścia testowanego systemu. Dokładne omówienie koncepcji SUT znajdziesz w rozdziale 3.

Klasa testów

Zgodnie z konwencją typowa klasa testów jednostkowych używa tych samych nazw pochodzących z SUT. W kolejnym fragmencie kodu pokazałem przykład typowej klasy testów jednostkowych.

public class NazwaKlasyTests

{

public void NazwaMetody_Warunek1_Oczekiwanie1()

{

// Testy jednostkowe Testing wywołujące metodę o nazwie NazwaMetody.

}

// Pozostałe testy…

public void NazwaMetody_WarunekN_OczekiwanieN()

{

// Testy jednostkowe Testing wywołujące metodę o nazwie NazwaMetody.

}



}

Zwróć uwagę na to, że nazwy klasy ( NazwaKlasy ) i metody ( NazwaMetody ) w dwóch poprzednich fragmentach kodu nie są przypadkowe. Zgodnie z konwencją powinny być takie same. Aby rozpocząć przygotowanie naszych klas testujących, musimy określić nazwy klasy i metody.

Nazwa klasy

Zgodnie z wymaganiami będzie nam potrzebna klasa przeznaczona do przechowywania wszystkich metod operacji dzielenia. Nadajemy więc tej klasie nazwę Division . Jeżeli chcesz dla niej utworzyć klasę testów jednostkowych, wówczas musi mieć ona nazwę DivisionTests . Następnym krokiem jest zmiana nazwy klasy UnitTest1 na DivisionTests . To obejmuje również zmianę nazwy pliku klasy na _DivisionTests.cs_ .

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wskazówka

Po umieszczeniu wskaźnika myszy w dowolnym miejscu nazwy klasy w kodzie źródłowym (w omawianym przykładzie to była nazwa UnitTest1 ) należy nacisnąć klawisze _Ctrl+R, R_ (trzymając wciśnięty klawisz _Ctrl_ , w krótkim odstępie czasu dwukrotnie naciśnij klawisz _R_ ). Wpisz nową nazwę, DivisionTests , i naciśnij klawisz _Enter_ . To spowoduje także zmianę nazwy pliku, o ile zostało zaznaczone pole wyboru _Rename symbol’s file_ .
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Nazwa metody

Na szczęście wymagania w omawianym przykładzie są proste, więc nazwa naszej metody to po prostu Divide . Zgodnie z wymaganiami ta metoda będzie akceptowała dwa argumenty w postaci liczb całkowitych ( int32 ) i zwróci wartość typu decimal . Kolejnym krokiem jest refaktoryzacja istniejącego testu jednostkowego z Test1 na postać DivideWarunek1_Oczekiwanie1 .

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Uwaga

PRZYPOMNIENIE ZWIĄZANE Z TERMINOLOGIĄ STOSOWANĄ W ARYTMETYCE : w przypadku wyrażenia 10 / 5 = 2 wartość 10 to dzielna, 5 to dzielnik, 2 zaś to współczynnik.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Warunki i oczekiwania

Podczas testowania następuje określenie warunku oraz tego, co jest oczekiwane w przypadku spełnienia danego warunku. Rozpoczynamy od _warunku podstawowego_ , nazywanego również _ścieżką pozytywną_ bądź _ścieżką szczęśliwą_ . Najpierw trzeba przygotować wszystkie ścieżki pozytywne, a dopiero później można przejść do innych przypadków. Nasz cel w testach jednostkowych sprowadza się do ustalenia warunku i oczekiwań oraz przygotowania testu jednostkowego dla każdego wariantu.

Aby pokazać związek między testowanymi metodami (metoda w naszym testowanym systemie) a warunkami i oczekiwaniami, wykorzystamy doskonale znaną konwencję, której przykład zastosowania jest pokazany w kolejnym fragmencie kodu.

public void NazwaMetody_Warunek_Oczekiwanie()

{

...

Oto kilka losowo wybranych nazw metod testów jednostkowych, które pomogą oswoić się ze wspomnianą wcześniej konwencją:

- SaveUserDetails _MissingEmailAddress_EmailIsMissing
- ValidateUserCredentials_HashedPasswordDoesntMatch_False
- GetUserById_IdDoesntExist_UserNotFoundException

Więcej przykładów poznasz podczas definiowania testów jednostkowych.

Podstawowym wymaganiem jest przeprowadzenie dzielenia dwóch liczb całkowitych. Najprostsza implementacja polega na podzieleniu dwóch liczb całkowitych i otrzymaniu w wyniku również liczby całkowitej. W takim przypadku warunkiem jest istnienie PODZIELNYCH LICZB CAŁKOWITYCH (ang. _divisible integers_ ), oczekiwanie zaś to zwrócenie przez tę operację LICZBY CAŁKOWITEJ (ang. _whole number_ ). Teraz należy więc uaktualnić sygnaturę naszego testu jednostkowego do postaci Divide_DivisibleIntegers_WholeNum ber oraz zdefiniować tę metodę w sposób przedstawiony w kolejnym fragmencie kodu.

public void Divide_DivisibleIntegers_WholeNumber()

{

int dividend = 10;

int divisor = 5;

decimal expectedQuotient = 2;

decimal actualQuotient = Division.Divide(dividend,

divisor);

Assert.Equal(expectedQuotient, actualQuotient);

}

Ten kod nie skompiluje się, ponieważ na tym etapie klasa Division jeszcze nie istnieje. Doskonale o tym wiemy, bo pod nazwą klasy Division znajduje się falista linia. To jest ten rzadki przypadek, w którym niemożliwość skompilowania klasy ze względu na brak pewnego komponentu nie jest czymś złym. W ten sposób otrzymujemy informację, że _test zakończył się niepowodzeniem_ , co w tym przypadku również jest dobrą wiadomością.

Wprawdzie wydaje się głupie zakończenie testu niepowodzeniem z powodu braku możliwości skompilowania kodu, ponieważ klasa Division nie istnieje, ale to jednocześnie oznacza, że nie został utworzony kod testowanego systemu. W rozdziale 5. dowiesz się więcej na temat uwzględniania tego przypadku.

Assert to klasa pochodząca z frameworka xUnit. Metoda statyczna Equal jest wielokrotnie przeciążana, w omawianym kodzie zaś użyto wersji o następującej sygnaturze:

public static void Equal(T expected, T actual)

Po uruchomieniu ta metoda będzie sygnalizowała frameworkowi xUnit, że wartości oczekiwana i faktycznie otrzymana nie są takie same. Jeżeli po wykonaniu testu wynikiem tej asercji jest true , to oznacza zaliczenie testu.

Czerwony — zielony

Niepowodzenie jest tym, co nas najbardziej interesuje. W późniejszych rozdziałach wyjaśnię, dlaczego tak się dzieje. W tym miejscu wystarczy wiedzieć, że pracę trzeba rozpocząć od nieudanej budowy (kompilacji) bądź testu zakończonego niepowodzeniem (nieudana asercja), a następnie doprowadzić do jego zaliczenia. Podejście typu niezaliczony-zaliczony jest również określane mianem TECHNIKI REFAKTORYZACJI CZERWONY — ZIELONY , która odzwierciedla ideę _zły — dobry_ i _stój — idź_ .

Konieczne jest dodanie klasy Division oraz metody Divide , a także utworzenie minimalnej ilości kodu, dzięki któremu test zostanie zaliczony. W projekcie _Uqs.Arithmetic_ utwórz nowy plik o nazwie _Division.cs_ i przedstawionej tutaj zawartości.

namespace Uqs.Arithmetic;

public class Division

{

public static decimal Divide(int dividend, int divisor)

{

decimal quotient = dividend / divisor;

return quotient;

}

}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Wskazówka
Klasę można utworzyć przez umieszczenie wskaźnika w dowolnym miejscu nazwy klasy (w omawianym przykładzie to Division ) i naciśnięcie klawiszy _Ctrl+._ (trzymając wciśnięty klawisz _Ctrl_ , naciśnij klawisz przedstawiający kropkę). Wybierz opcję _Generate new type…_ , a następnie z rozwijanego menu _Project_ wybierz Uqs.Arithmetic i naciśnij przycisk _OK_ . Dalej, aby wygenerować metodę, umieść wskaźnik w klasie Divide i naciśnij klawisze _Ctrl+._ , wybierz opcję _Generate method ‘Division.Divide’_ , a otrzymasz w klasie Division szkielet metody gotowy do wypełnienia własnym kodem.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Trzeba koniecznie pamiętać, że _w kodzie C# wynikiem dzielenia dwóch liczb całkowitych jest liczba całkowita_ . Spotykałem się z sytuacjami, w których starsi programiści zapominali o tym, co z kolei prowadziło do poważnych konsekwencji. W zaimplementowanym kodzie zostało uwzględnione jedynie dzielenie liczb całkowitych, które prowadzi do wyniku w postaci liczby całkowitej. To powinno pozwolić na zaliczenie testu.

W tym momencie jesteśmy gotowi do wykonania testów za pomocą okna _Test Explorer_ w Visual Studio. Naciśnij więc klawisze _Ctrl+R, A_ , aby w ten sposób skompilować projekty, a następnie wykonać wszystkie znajdujące się w nich testy (obecnie to tylko jeden). Zauważ, że okno _Test Explorer_ wskazuje kolor zielony, a między nazwą testu i atrybutem Fact znajduje się zielona ikona. Jej kliknięcie spowoduje wyświetlenie pewnych opcji związanych z testami, jak pokazałem na rysunku 1.15.

mniej..

BESTSELLERY

Kategorie: