Rozpoczęcie nowego projektu z TDD

10

Studiuję TDD i czytam, że pomaga ci to również zdefiniować projekt aplikacji, prawda?

Postanowiłem więc rozpocząć tworzenie nowego projektu, aby pomóc mi go lepiej zrozumieć.

Chcę stworzyć prosty system rejestracji użytkowników, który zapyta o jego nazwę, adres e-mail, kraj (wybierze jeden z listy) i numer telefonu.

Pytanie brzmi więc ...

Stworzyłem nowe rozwiązanie w VS 2010, dodałem nowy projekt testowy i po prostu nie wiem, jakie testy napisać!

Ponieważ pomoże mi to zdefiniować projekt, jakie testy mogę tutaj napisać?

Dzięki za wszelką pomoc!


źródło
1
Pomoże ci to w sposobie, w jaki najpierw musisz pomyśleć o wzorcach, których będziesz używać, klasach, które napiszesz itp. - Zacznij od zdefiniowania klasy i napisz przypadki testowe dla metod, a następnie zacznij implementować metody zgodnie z ich przypadkiem testowym ..
halfdan

Odpowiedzi:

6

Pisząc testy jednostkowe, testujesz zachowanie aplikacji, więc ważne pytanie, jakie należy zadać, brzmi: co robi Twoja aplikacja ? Oto początek:

[TestFixture]
public class RegistrationTests
{
    [Test]
    public void Should_save_new_user_info()
    {
    }

    [Test]
    public void Should_throw_validation_exception_when_email_already_exists()
    {
    }

    [Test]
    public void Should_format_phone_number_when_country_code_is_us()
    {
    }
}

źródło
Cóż, wszystkie te testy już zdały, co dalej? :)
Scott Whitlock,
2

Samo tworzenie projektu testowego i pisanie niektórych metod testowych jest rodzajem TDD, ale z mojego doświadczenia nie ma dużej pomocy, chyba że pracujesz nad biblioteką, w której istnieje znany interfejs API, a wywołania metod odpowiadają bezpośrednio oczekiwaniom użytkownika . Musisz wymyślić odpowiednią listę testów, a dla nietrywialnej aplikacji może to być naprawdę trudne.

Polecam wypróbowanie SpecFlow - nadal definiuje testy ładnie oddzielone od implementacji, a struktura plików funkcji zmusza do myślenia o tym, co faktycznie testujesz.

Kiedy definiujesz funkcję, po prostu piszesz coś takiego

When a user is saved
Then the user should exist

Ponieważ nie ma w tym momencie pliku kodu, nie masz ochoty myśleć o szczegółach implementacji, takich jak metoda wywoływana w celu utworzenia użytkownika lub nawet klasa, w której jest ona implementowana. Możesz użyć znaczników, aby wybrać różne implementacje, więc na tym poziomie nie ma znaczenia, czy „użytkownik jest zapisany” oznacza wywołanie CreateUser lub otwarcie przeglądarki i przesłanie formularza.

Po zdefiniowaniu funkcji wszystkie testy są generowane i zaczynają się powierzać w miarę wdrażania definicji kroków i testowanego rzeczywistego kodu aplikacji.

W przypadku prostej aplikacji możesz po prostu utworzyć pliki funkcji, ale w przypadku bardziej skomplikowanych użyteczne jest wcześniejsze skompletowanie pełniejszej specyfikacji. Używam do tego aplikacji mapowania myśli na iPada, ale możesz użyć dowolnego narzędzia, z którym czujesz się najlepiej.

Zacznij od listy funkcji wysokiego poziomu, takich jak „Rejestracja użytkownika”. Są one zbyt szerokie, aby pisać testy bezpośrednio, więc podziel je na podfunkcje, które można jasno zdefiniować i ogólnie przypisać do określonej akcji użytkownika, takiej jak „Zapisz użytkownika” lub „Wyświetl istniejącego użytkownika”.

Każda z tych podfunkcji będzie wymagała listy scenariuszy, które razem całkowicie określają, czy funkcja działa, np. „Może zapisać poprawnego użytkownika” i „Nie można zapisać użytkownika ze zduplikowaną nazwą użytkownika”.

Podczas budowania tej listy na ogół stanie się jasne, gdzie należy dostosować strukturę - jeśli nie możesz wymyślić żadnych testów scenariuszy dla danej funkcji lub skończy się zbyt wiele w jednej funkcji, to ta funkcja jest prawdopodobnie zdefiniowana na niewłaściwy poziom i należy go podzielić lub zmienić.

Tom Clarkson
źródło
2

Zauważyłem, że dobrze jest tworzyć kopie zapasowe moich pierwszych eksperymentów w TDD, czytając i odcinając kod. Artykuł w Wikipedii na ten temat jest bardzo dobry i poprowadzi Cię przez wiele innych zasobów. Poszukaj rzeczy w szczególności od Kenta Becka - swego rodzaju ojca TDD.

Inną rzeczą, która może pomóc ci się w tym huśtać, jest wykonywanie katas - prostych, prawie bezmyślnych ćwiczeń. Roy Osherove ma kilka dobrych.

Ponadto pamiętaj o kluczowych pomysłach TDD - pisz jeden test na raz i nie kontynuuj, dopóki nie przejdą wszystkie poprzednie testy. Napisz tylko tyle kodu, aby spełnić bieżący test, unikaj pokusy, by pisać więcej. W miarę upływu czasu zatrzymuj się co jakiś czas i pomyśl, czy możesz wyczyścić kod lub testy. Zawsze rozwijaj w cyklu czerwonym (test negatywny), zielonym (test pozytywny), cyklu refaktora.

Na początek możesz zacząć od podania imienia i nazwiska. Czego będziesz potrzebować

Prawdopodobnie będziesz potrzebować klasy. Napisz do tego test (niektóre osoby pomijają to, ale na początku zrób to dla ćwiczenia) i napisz klasę.

Następnie twoja klasa będzie musiała zapisać imię. Napisz test potwierdzający, że Twoja klasa rzeczywiście może. Następnie ponownie napisz kod, aby test przeszedł pomyślnie.

Być może masz jeszcze jakieś reguły biznesowe. Może chcesz, aby twoje imię i nazwisko zawierało minimalną liczbę znaków. Napisz test, zobacz, jak się nie udaje, napisz kod.

I tak dalej...

David Hall
źródło
1

Myślę, że nie jest możliwe przedstawienie krótkiej odpowiedzi na temat TDD. Musisz „zobaczyć” praktykę sombody, aby poczuć to. Najlepszym zasobem, jaki kiedykolwiek znalazłem na ten temat, jest http://pragprog.com/titles/achbd/the-rspec-book . Zanim powiesz mi, że Ruby nie jest twoim językiem: przeczytaj przedmowę wujka Boba! ;-)

Achim
źródło
1
Książka rspec jest w porządku. Jeśli OP zamierza przeczytać książkę na temat TDD, powinna to być: amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530
Julio
0

Możesz skonfigurować test, który próbuje dodać wiele różnych wartości do pola e-mail, niektóre są prawidłowe, a inne nie. Nie przestawaj się rozwijać, dopóki wszystkie testy nie dadzą oczekiwanej wartości. Takie rzeczy.

Kyle Sletten
źródło
0

Jak opisano system, na poziomie aplikacji jest tylko jeden test:

[Test] public void Save_and_retrieve_user (nazwa ciągu, ciąg wiadomości e-mail, ...) {// Zapisz // Pobierz // Zweryfikuj}

Po dopracowaniu wymagań dodaj więcej testów.

Kevin Cline
źródło