Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [OOP][TDD][BDD] Algorytm a jego testowalność
Forum PHP.pl > Forum > PHP > Object-oriented programming
Riggs
Witam,
chciałbym poruszyć mam nadzieję ciekawe zagadnienie. Otóż ostatnio pisałem sobie dość rozbudowany algorytm i chciałem wykonać go za pomocą metodyk TDD/BDD i narzędzi PHPSpec i PHPUnit. Mam jednak co do niego kilka wątpliwości. Weźmy za przykład algorytm który kiedyś robiłem i wiem, że działa dobrze. Koncepcja też jest chyba ok.

SudokuSolver - klasa, która jako konstruktor przyjmuje tablicę 9x9 częściowo wypełnioną. Posiada metodę solve() dostępną publicznie która zwraca albo rozwiązanie w postaci tablicy 9x9 bez wartości null (czyli całą wypełnioną) albo rzuca wyjątkiem jeśli nie ma rozwiązania. Wiadomo, że metodę w metodzie solve() trzeba wywołać częściowe metody np. sprawdzające rozwiązanie, np. checkColumn, checkRow, check3x3. Zakodowałem je jako metody prywatne bo nie widzę potrzeby możliwości wywołania ich poza ciałem klasy - z resztą solve ma dać wynik. Jak podejść do pisania testów takiej klasy? W PHPSpec mógłbym tylko odwoływać się do solve() i oczekiwać wyniku. w PHPUnit od biedy można zrobić ReflectionClass ale to chyba nie o to chodzi w testowaniu... Chciałbym mieć możliwie największe pokrycie kodu testami, tak żeby mieć pewność że algorytm działa prawidłowo. Jak testować poszczególne etapy - czy np checkColumn zostało wywołane x razy itp.. Czy może bez wystawienia metod jako public nie mam szans na dobre przetestowanie kodu?
Crozin
Pomijając szczególne przypadki, metody niepubliczne nie powinny być testowane bezpośrednio. W Twoim przypadku:
1. Powinieneś mieć serię testów, która dla danych wejściowych sprawdza czy zwrócony wynik jest taki jak przewidywano (tablica A -> tablica B, bądź tablica A -> wyjątek). W sumie będziesz miał kilkanaście/dziesiąt testów, a właściwie zestawów testowych.
2. Możesz rzucić sobie okiem na wyniki pokrycia kodu testami w celu przygotowaniu takiego zestawu danych wejściowych by przetestować wszystkie wewnętrzne mechanizmy.
destroyerr
Jeżeli chcesz testować różne warunki sprawdzania to może wydziel sprawdzanie do osobnych obiektów. Wtedy do obiektu rozwiązującego załadujesz sobie kolekcję takich "sprawdzaczy", ułatwione masz wtedy testowanie tego co chcesz.
Riggs
@destroyerr jest to jakiś pomysł, pewnie tylko prosta klasa rozrośnie się do dość dużych rozmiarów ale to jest dobry pomysł żeby testować każdy komponent.
Pyton_000
Możesz wydzielić "Valiataors" np. RowValidator, ColValidator, SquareValidator. Wszystkie na jakimś wspólnym interfejsie.
W klasie bazowej podajesz tylko listę Validatorów i odpalasz jeden po drugim.
Wtedy testujesz każdy validator oddzielnie i na koniec całość jako komponent.
lukaskolista
Cytat
w PHPUnit od biedy można zrobić ReflectionClass ale to chyba nie o to chodzi w testowaniu...
Czemu niby nie?

Co powiesz na MockBuilder https://phpunit.de/manual/current/en/test-doubles.html Działa podobnie do biblioteki Reflection o ile na niej nie bazuje (nie znam kodu MockBuildera).
destroyerr
@Pyton_000 No co Ty nie powiesz...
Pyton_000
Hahaha biggrin.gif Tak to jest jak się nie odświeża stron haha.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.