2011-02-05 20 views
25

Rozumiem ideę rozwoju opartego na testach, najpierw pisz testy, koduj testy, dopóki się nie powiodą. Po prostu nie spotykam się jeszcze w moim obiegu pracy.Przykłady testów jednostkowych?

Czy możesz podać mi przykłady, w których testy jednostkowe mogą być używane w kontekście tworzenia stron internetowych z przodu lub z tyłu?

+2

Polecam, patrząc na tę odpowiedź: http://stackoverflow.com/questions/18601/best-practice-for-integrating-tdd-w--web-application- development – Herter

+0

Ponieważ jest nieskończenie wiele przykładów, to pytanie jest zbyt szeroki. – Raedwald

Odpowiedz

64

Nie określiłeś języka, więc postaram się zachować to nieco ogólne. Będzie to trudne, ponieważ znacznie łatwiej jest wyrazić koncepcje za pomocą rzeczywistego kodu.

Testy jednostkowe mogą być początkowo nieco mylące. Czasami nie zawsze jest jasne, jak przetestować coś lub jaki jest cel testu.

Lubię traktować testowanie jednostek jako sposób testowania małych pojedynczych fragmentów kodu.

Pierwsze miejsce, w którym korzystam z testów jednostkowych, to sprawdzenie, czy jakaś metoda działa tak, jak oczekuję tego we wszystkich przypadkach. Niedawno napisałem metodę sprawdzania poprawności numeru telefonu mojej witryny. Akceptuję dowolne dane wejściowe z 123-555-1212, (123) 555-1212 itd. Chcę się upewnić, że moja metoda sprawdzania poprawności działa dla wszystkich możliwych formatów. Bez testu jednostkowego musiałbym ręcznie wprowadzić każdy inny format i sprawdzić, czy formularz jest poprawnie publikowany. Jest to bardzo uciążliwe i podatne na błędy. Później, jeśli ktoś zmieni kod weryfikacyjny telefonu, byłoby miło, gdybyśmy mogli łatwo sprawdzić, czy nic innego się nie zepsuło. (Może dodaliśmy obsługę kodu kraju). Więc tutaj jest trywialny przykład:

public class PhoneValidator 
{ 
    public bool IsValid(string phone) 
    { 
      return UseSomeRegExToTestPhone(phone); 
    } 
} 

mógłbym napisać test jednostkowy takiego:

public void TestPhoneValidator() 
{ 
    string goodPhone = "(123) 555-1212"; 
    string badPhone = "555 12" 

    PhoneValidator validator = new PhoneValidator(); 

    Assert.IsTrue(validator.IsValid(goodPhone)); 
    Assert.IsFalse(validator.IsValid(badPhone)); 
} 

te 2 linie dochodzić będzie upewnić się, że wartość zwracana z IsValid() jest prawdziwe i fałszywe odpowiednio.

W realnym świecie prawdopodobnie miałbyś wiele przykładów dobrych i złych numerów telefonów. Mam około 30 numerów telefonów, z którymi testuję. Samo uruchomienie tego testu w przyszłości powie ci, czy twoja logika weryfikacji telefonu jest zepsuta.

Możemy również użyć testów jednostkowych do symulacji rzeczy poza naszą kontrolą.

Testy jednostek powinny przebiegać niezależnie od zewnętrznych zasobów. Twoje testy nie powinny zależeć od obecności bazy danych ani od dostępności usługi internetowej. Zamiast tego symulujemy te zasoby, abyśmy mogli kontrolować, co zwracają. Na przykład w mojej aplikacji nie mogę zasymulować odrzuconej karty kredytowej przy rejestracji. Prawdopodobnie bank nie chciałby, żebym przesłał tysiące złych kart kredytowych, aby upewnić się, że mój kod obsługi błędów jest poprawny. Oto przykładowy kod:

public class AccountServices 
{ 
    private IBankWebService _webService = new BankWebService(); 

    public string RegisterUser(string username, string creditCard) 
    { 
     AddUserToDatabase(username); 

     bool success = _webService.BillUser(creditCard); 

     if (success == false) 
      return "Your credit card was declined" 
     else 
      return "Success!" 

    } 
} 

To tutaj testowanie jednostek jest bardzo mylące i nieoczywiste. Co powinien zrobić test tej metody? Po pierwsze, byłoby miło, gdybyśmy mogli sprawdzić, czy w przypadku niepowodzenia płatności, zwrócony został odpowiedni komunikat o błędzie. Jak się okazuje, za pomocą makiety istnieje sposób. Używamy tego, co nazywa się Inwersja kontroli. W tej chwili usługa AccountServices() jest odpowiedzialna za tworzenie obiektu BankWebService.Pozwólmy rozmówca tej klasy dostarczyć go jednak:

public class AccountServices 
{ 
    public AccountServices(IBankWebService webService) 
    { 
     _webService = webService; 
    } 

    private IBankWebService _webService; 

    public string RegisterUser(string username, string creditCard) 
    { 
     AddUserToDatabase(username); 

     bool success = _webService.BillUser(creditCard); 

     if (success == false) 
      return "Your credit card was declined" 
     else 
      return "Success!" 

    } 
} 

Ponieważ rozmówca jest odpowiedzialny za tworzenie obiektu BankWebService, nasze testy jednostkowe mogą tworzyć fałszywy:

public class FakeBankWebService : IBankWebService 
{ 
    public bool BillUser(string creditCard) 
    { 
     return false; // our fake object always says billing failed 
    } 
} 

public void TestUserIsRemoved() 
{ 
    IBankWebService fakeBank = FakeBankWebService(); 

    AccountServices services = new AccountServices(fakeBank); 

    string registrationResult = services.RegisterUser("test_username"); 

    Assert.AreEqual("Your credit card was declined", registrationResult); 
} 

Używając że fałszywy przedmiot , zawsze, gdy wywoływana jest funkcja BillUser() naszego banku, nasz fałszywy obiekt zawsze zwróci fałsz. Nasz test jednostkowy sprawdza teraz, czy jeśli połączenie z bankiem nie powiedzie się, RegisterUser() zwróci poprawny komunikat o błędzie.

Załóżmy pewnego dnia robią pewne zmiany, a skrada Bug w: „sukces”

public string RegisterUser(string username, string creditCard) 
{ 
    AddUserToDatabase(username); 

    bool success = _webService.BillUser(creditCard); 

    if (success) // IT'S BACKWARDS NOW 
     return "Your credit card was declined" 
    else 
     return "Success!" 

} 

Teraz, gdy rozliczeniowy zawodzi, metoda Twój RegisterUser() zwraca. Na szczęście masz napisany test jednostki. Ten test jednostkowy zakończy się niepowodzeniem, ponieważ nie będzie już zwracany "Twoja karta kredytowa została odrzucona".

Jest o wiele łatwiej i szybciej znaleźć błąd w ten sposób, niż ręcznie wypełnić formularz rejestracyjny złym kartą kredytową, aby sprawdzić komunikat o błędzie.

Kiedy spojrzysz na różne szydercze ramy, możesz zrobić jeszcze więcej potężnych rzeczy. Możesz sprawdzić, jakie fałszywe metody zostały wywołane, możesz zweryfikować ile razy metoda została wywołana, możesz zweryfikować parametry, z którymi metody zostały wywołane, itp.

Myślę, że kiedy zrozumiesz te 2 pomysły, zrozumiesz więcej niż wystarczająco, aby napisać wiele testów jednostkowych dla twojego projektu.

Jeśli powiesz nam, jakiego języka używasz, możemy skierować Cię lepiej.

Mam nadzieję, że to pomoże. Przepraszam, jeśli niektóre z nich są mylące. Sprzątnę to, jeśli coś nie ma sensu.

+2

To bardzo pomocne, po prostu chciałem uzyskać podstawowe zrozumienie, dziękuję bardzo! – eighteyes

+2

Cieszę się, że to pomaga. Testowanie jednostek wydaje się początkowo zaskakująco trudne do zrozumienia, a następnie zaskakująco łatwe po kliknięciu. Dla mnie było to raczej nauczenie się pisania testowalnego kodu. Jakiego języka używasz? Możemy podać lepsze rekomendacje dla Twojego konkretnego języka. – mfanto

+0

głównie w JavaScript, PHP i Pythonie. – eighteyes

Powiązane problemy