Zdecydowanie dobra lista. Oto kilka uwag na ten temat:
Najpierw napisz test, a potem kod.
Zgadzam się, na wysokim poziomie. Ale ja byłbym bardziej szczegółowy: „Najpierw napisz test, a następnie napisz kod wystarczający do zaliczenia testu i powtórz”. W przeciwnym razie bałbym się, że moje testy jednostkowe będą bardziej przypominały testy integracyjne lub akceptacyjne.
Projektuj klasy przy użyciu iniekcji zależności.
Zgoda. Kiedy obiekt tworzy własne zależności, nie masz nad nimi kontroli. Inversion of Control / Dependency Injection daje ci tę kontrolę, pozwalając ci odizolować testowany obiekt za pomocą mocków / stubów / itp. W ten sposób testujesz obiekty w izolacji.
Oddziel kod interfejsu użytkownika od jego zachowania za pomocą Model-View-Controller lub Model-View-Presenter.
Zgoda. Zwróć uwagę, że nawet prezenter / kontroler można przetestować za pomocą DI / IoC, przekazując mu skrótowy / symulowany widok i model. Sprawdź Presenter First TDD, aby uzyskać więcej informacji.
Nie pisz statycznych metod ani klas.
Nie jestem pewien, czy zgadzam się z tym. Możliwe jest testowanie jednostkowe metody / klasy statycznej bez używania makiet. Być może jest to jedna z tych specyficznych zasad Rhino Mock, o których wspomniałeś.
Programuj interfejsy, a nie klasy.
Zgadzam się, ale z nieco innego powodu. Interfejsy zapewniają twórcom oprogramowania dużą elastyczność - wykraczają poza tylko obsługę różnych struktur obiektów pozorowanych. Na przykład nie jest możliwe prawidłowe wsparcie DI bez interfejsów.
Izoluj zależności zewnętrzne.
Zgoda. Ukryj zależności zewnętrzne za własną fasadą lub adapterem (w razie potrzeby) z interfejsem. Pozwoli to odizolować oprogramowanie od zewnętrznych zależności, czy to usługi sieciowej, kolejki, bazy danych czy czegoś innego. Jest to szczególnie ważne, gdy Twój zespół nie kontroluje zależności (czyli zewnętrznej).
Oznacz jako wirtualne metody, które zamierzasz kpić.
To jest ograniczenie Rhino Mocks. W środowisku, które preferuje ręcznie kodowane kody pośredniczące zamiast makiety frameworka obiektowego, nie byłoby to konieczne.
I kilka nowych punktów do rozważenia:
Użyj kreatywnych wzorców projektowych. Pomoże to w przypadku DI, ale umożliwia również wyodrębnienie tego kodu i przetestowanie go niezależnie od innej logiki.
Pisz testy używając techniki Arrange / Act / Assert Billa Wake'a . Ta technika bardzo jasno określa, jaka konfiguracja jest konieczna, co faktycznie jest testowane i czego się oczekuje.
Nie bój się toczyć własnych prób. Często okaże się, że używanie makietowych struktur obiektowych sprawia, że testy są niezwykle trudne do odczytania. Wprowadzając własne, będziesz mieć pełną kontrolę nad swoimi makietami / kodami pośrednimi i będziesz w stanie zapewnić czytelność testów. (Wróć do poprzedniego punktu.)
Unikaj pokusy refaktoryzacji powielania testów jednostkowych do abstrakcyjnych klas bazowych lub metod konfiguracji / porzucenia. Spowoduje to ukrycie kodu konfiguracyjnego / czyszczącego przed programistą próbującym usprawnić test jednostkowy. W tym przypadku przejrzystość każdego pojedynczego testu jest ważniejsza niż refaktoryzacja duplikacji.
Wdrażaj ciągłą integrację. Wpisz swój kod na każdym „zielonym pasku”. Twórz oprogramowanie i uruchamiaj pełny zestaw testów jednostkowych przy każdym zameldowaniu. (Jasne, nie jest to praktyka kodowania sama w sobie; ale jest to niesamowite narzędzie do utrzymywania oprogramowania w czystości i pełnej integracji).