W dzisiejszym artykule przybliżę Ci Test-Driven Development – czyli TDD. To podejście do tworzenia oprogramowania sprawi, że Twój kod będzie czystszy, bardziej niezawodny i łatwiejszy w utrzymaniu.
1. Czym jest TDD?
• Test-Driven Development to sposób wytwarzania oprogramowania, w którym najpierw piszemy testy, a dopiero później implementujemy właściwe rozwiązanie. TDD zmusza nas do dokładnego przemyślenia wymagań i interfejsów, zanim napiszemy docelową logikę.
2. Dlaczego warto stosować TDD w C#/.NET?
• Środowisko .NET jest bogate w narzędzia do testów jednostkowych (MSTest, xUnit, NUnit), co pozwala łatwo tworzyć i utrzymywać testy. Pisząc testy przed kodem produkcyjnym, ograniczamy ryzyko błędów oraz usprawniamy cały proces developmentu.
Na czym polega TDD? (Red-Green-Refactor)
W TDD mamy podział na 3 etapy.
Red:
Zaczynamy od napisania testu, który z definicji nie przejdzie, bo nie ma jeszcze implementacji. Jest to wyrazisty etap, bo widzimy czerwony wskaźnik w narzędziu do testów: test się wysypuje.
Green:
Następnie tworzymy minimalną implementację potrzebną do tego, by test przeszedł na zielono. Chodzi o to, by nie pisać zbyt dużo kodu, tylko dokładnie tyle, ile potrzebne.
Refactor:
Na koniec przychodzi pora na refaktoryzację – poprawiamy strukturę kodu, wyciągamy metody pomocnicze czy usuwamy duplikacje. Ważne, żeby wszystkie testy wciąż przechodziły.
Przykład w C#/.NET – Prosty Kalkulator
Teraz pokażę Ci krok po kroku, jak może wyglądać TDD na przykładzie tworzenia bardzo prostej klasy Calculator.
Projekt testowy
Najpierw dodajemy projekt testowy. Możemy użyć np. NUnit.
Zainstaluj pakiety:
NUnit
NUnit3TestAdapter
Shouldly
Microsoft.NET.Test.Sdk
using NUnit.Framework;
using Shouldly;
namespace MyConsoleProject.UnitTests
{
public class CalculatorTests
{
[Test]
public void Add_TwoNumbers_ReturnsCorrectResult()
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(2, 3);
// Assert
result.ShouldBe(5);
}
}
}
1. Arrange – tworzymy obiekt Calculator.
2. Act – wywołujemy metodę Add.
3. Assert – weryfikujemy, czy wynik jest taki, jak oczekiwaliśmy.
Na tym etapie klasa Calculator oraz metoda Add jeszcze nie istnieją, także test nie może przejść, ponieważ mamy błędy kompilacji. Test nie przechodzi (Red).
Testy możesz uruchamiać w widoku Test Explorer.
Implementacja minimalna (Green)
Teraz tworzymy klasę w projekcie głównym:
namespace MyConsoleProject
{
public class Calculator
{
public int Add(int number1, int number2)
{
return number1 + number2;
}
}
}
Dodaliśmy minimalną implementację, która spełnia wymagania testu. Teraz test powinien przechodzić na zielono (Green).
Refaktoryzacja (Refactor)
Załóżmy, że chcemy dodać logikę sprawdzającą, czy nie występuje np. przepełnienie. Jeśli nie jest to konieczne, możemy pozostać przy prostej metodzie. W codziennej praktyce TDD pojawia się więcej testów i okazji do refaktoryzacji, ale mechanizm zawsze jest ten sam: testujemy–implementujemy–czyścimy kod.
Kolejny krok – testy na błędne dane
Dobrym pomysłem jest dodanie testów sprawdzających nieoczywiste przypadki, np. gdy wynik może być bardzo duży, ujemny lub gdy przekazujemy argumenty w różnych warunkach.
[TestCase(int.MaxValue, 0, int.MaxValue)]
[TestCase(int.MinValue, 1, int.MinValue + 1)]
[TestCase(-5, -3, -8)]
public void Add_VariousCases_ReturnsCorrectResult(int a, int b, int expected)
{
// Arrange
var calculator = new Calculator();
// Act
var result = calculator.Add(a, b);
// Assert
result.ShouldBe(expected);
}
Dzięki temu nasz kod staje się bardziej odporny na błędy.
W prawdziwej aplikacji można by rozbudować logikę o obsługę wyjątków czy innych nieprzewidzianych sytuacji.
Zalety TDD w projektach .NET
1. Wyższa jakość kodu – testy wymuszają myślenie o architekturze.
2. Szybsze wykrywanie błędów – testy jednostkowe uruchamiamy po każdej zmianie.
3. Łatwość utrzymania – dobrze zaprojektowane testy pozwalają szybko zrozumieć, co robi dana klasa czy metoda.
4. Poprawa pewności wprowadzania zmian – refaktoryzacja w obecności testów jest mniej ryzykowna.
Jak zacząć z TDD?
1. Wybierz framework testowy – w .NET popularne są xUnit, NUnit oraz MSTest. Ja polecam NUnit.
2. Zainstaluj potrzebne paczki (NUnit,NUnit3TestAdapter, Microsoft.NET.Test.Sdk przez NuGet).
3. Skonfiguruj pipeline – uruchamiaj testy za każdym razem, gdy dokonujesz zmian w kodzie (idealnie w CI/CD).
4. Rozwijaj projekt zgodnie z cyklem Red-Green-Refactor. To znaczy:
• Napisz pierwszy prosty test
• Utwórz minimalną implementację.
• Refaktoryzuj i sprawdź, czy testy wciąż przechodzą.
• Powtarzaj ten cykl.
Szkolenie Online: Zostań Programistą .NET
Jeśli chcesz jeszcze bardziej zgłębić temat TDD i poznać różne wzorce projektowe w C#/.NET, zapraszam Cię do mojego szkolenia online: Zostań Programistą .NET. Uczymy się tam nie tylko testowania, ale też kompleksowego podejścia do tworzenia aplikacji w ekosystemie .NET. To szkolenie przeprowadzi Cię przez najważniejsze zagadnienia od podstaw, aż po zaawansowane techniki wytwarzania oprogramowania, w tym praktyki takie jak TDD. Jeśli więc chcesz wejść na wyższy poziom programowania w .NET, serdecznie zapraszam!
Podsumowanie
Mam nadzieję, że ten artykuł pomógł Ci zrozumieć, jak wygląda praca w podejściu TDD w C# i .NET. Pamiętaj, że TDD to nie tylko dodatkowy obowiązek – to przede wszystkim inwestycja w jakość kodu i pewność wprowadzania zmian.
To wszystkie na dzisiaj. Jeżeli taki artykuł Ci się spodobał, to koniecznie dołącz do mojej społeczności – darmowe zapisy, gdzie będziesz również miał dostęp do dodatkowych materiałów i przede wszystkim bonusów. Do zobaczenia w kolejnym artykule.