Testowanie klas niepublicznych

0
MrBean Bean napisał(a):
Łukasz Hylicki napisał(a):
MrBean Bean napisał(a):

A ktoś słyszał o czymś takim jak framework izolacji( Moćkowania :D ) który wykorzystuje API Profiler ?
Jeśli chcesz sprawdzić wywołanie prywatnej metody to dało by radę przez np. TypeMock.
Co do testowania To nie można użyć mechanizmu refleksji.... ?

Nie testuje się prywatnych metod w ogóle. Jeżeli masz kod, do którego chcesz wprowadzić testy, a kod nie jest testowalny, to polecam upublicznić metodę, którą chcesz przetestować. Przez jakiś czas naruszysz hermetyzację, ale to koszt wprowadzania testów do kodu legacy.
Częściowe, tymczasowe popsucie API to nic złego jeśli strategicznie zyskujesz więcej niż tracisz :)

Czyli najpierw psujesz kod jeszcze bardziej a potem go testujesz ? Przecież to absurd, jeśli z jakiegoś powodu potrzebujesz w testach operować na prywatnych metodach to jak mówiłem API Profiler i mechanizm refleksji.

Tak. Jeśli chcesz poprawić jakość kodu legacy powinieneś najpierw pokryć dany kawałek kodu testami, a potem mając już siatkę bezpieczeństwa zrefaktoryzować go. Dopisany test Ci zagwarantuje, że refaktoryzując nie zepsujesz funkcjonalności.
Często właśnie się nie da napisać testu, bo kod jest niedostosowany i warto zrobić wtedy krok do tyłu, zepsuć enkapsulację, dopisać test, aby potem refactoringiem zrobić 10 kroków do przodu :)

0
JPrim napisał(a):
Łukasz Hylicki napisał(a):

Nie testuje się prywatnych metod w ogóle.

W przypadku części moich programów takie podejście byłoby absurdem.

W prywatnych metodach mam np. implementacje bardzo skomplikowanych algorytmów statystycznych, gdzie można łatwo gdzieś się pomylić, a publiczne np. przyjmują informacje o dwóch produktach i używając tych skomplikowanych prywatnych określają czy zakup pierwszego jest bardziej opłacalny niż drugiego.

Dalej nie rozumiem dlaczego nie testujesz metody wywołującej prywatną metodę jeśli ona przekazuje tylko swój argument i ewentualnie wywołuje metodę try?

0
JPrim napisał(a):

W przypadku części moich programów takie podejście byłoby absurdem.

W prywatnych metodach mam np. implementacje bardzo skomplikowanych algorytmów statystycznych, gdzie można łatwo gdzieś się pomylić, a publiczne np. przyjmują informacje o dwóch produktach i używając tych skomplikowanych prywatnych określają czy zakup pierwszego jest bardziej opłacalny niż drugiego.

Myślę, że tutaj design kodu może być problemem. Jak testowanie internalowych klas popieram tak z testowaniem prywatnych metod zgodzić się nie mogę ;)
Często lekka zmiana podejścia, wprowadzenie nadrzędnej klasy rozwiązuje problem.

0
Łukasz Hylicki napisał(a):
MrBean Bean napisał(a):
Łukasz Hylicki napisał(a):
MrBean Bean napisał(a):

A ktoś słyszał o czymś takim jak framework izolacji( Moćkowania :D ) który wykorzystuje API Profiler ?
Jeśli chcesz sprawdzić wywołanie prywatnej metody to dało by radę przez np. TypeMock.
Co do testowania To nie można użyć mechanizmu refleksji.... ?

Nie testuje się prywatnych metod w ogóle. Jeżeli masz kod, do którego chcesz wprowadzić testy, a kod nie jest testowalny, to polecam upublicznić metodę, którą chcesz przetestować. Przez jakiś czas naruszysz hermetyzację, ale to koszt wprowadzania testów do kodu legacy.
Częściowe, tymczasowe popsucie API to nic złego jeśli strategicznie zyskujesz więcej niż tracisz :)

Czyli najpierw psujesz kod jeszcze bardziej a potem go testujesz ? Przecież to absurd, jeśli z jakiegoś powodu potrzebujesz w testach operować na prywatnych metodach to jak mówiłem API Profiler i mechanizm refleksji.

Tak. Jeśli chcesz poprawić jakość kodu legacy powinieneś najpierw pokryć dany kawałek kodu testami, a potem mając już siatkę bezpieczeństwa zrefaktoryzować go. Dopisany test Ci zagwarantuje, że refaktoryzując nie zepsujesz funkcjonalności.
Często właśnie się nie da napisać testu, bo kod jest niedostosowany i warto zrobić wtedy krok do tyłu, zepsuć enkapsulację, dopisać test, aby potem refactoringiem zrobić 10 kroków do przodu :)

Gdzie to wyczytałeś?? przecież w ten sposób zwiększasz kruchość kodu produkcyjnego. Rozumiesz co to jest API Profiler? i mechanizm refleksji, różnica pomiędzy System i System Under Test ? Jeśli pracujesz z Legacy Cod to robisz warstwę adaptera, wystawiając potrzebne API a nie zmieniasz w nim metody z prywatnych do publicznych to bez sensu.

0
MrBean Bean napisał(a):

Gdzie to wyczytałeś?? przecież w ten sposób zwiększasz kruchość kodu produkcyjnego. Rozumiesz co to jest API Profiler? i mechanizm refleksji, różnica pomiędzy System i System Under Test ? Jeśli pracujesz z Legacy Cod to robisz warstwę adaptera, wystawiając potrzebne API a nie zmieniasz w nim metody z prywatnych do publicznych to bez sensu.

Nie ma się co denerwować :) Czy ktoś tutaj powiedział, że wrzucam to od razu na produkcję?
A co byś zrobił gdybyś nie mógł dobrać się do metod prywatnych za pomocą refleksji? Ogólnie zasada jest taka, że pisząc test nie powinieneś wiedzieć jaka jest wewnętrzna implementacja :)

Polecam posłuchać:

1
JPrim napisał(a):
Łukasz Hylicki napisał(a):

Nie testuje się prywatnych metod w ogóle.

W przypadku części moich programów takie podejście byłoby absurdem.

W prywatnych metodach mam np. implementacje bardzo skomplikowanych algorytmów statystycznych, gdzie można łatwo gdzieś się pomylić, a publiczne np. przyjmują informacje o dwóch produktach i używając tych skomplikowanych prywatnych określają czy zakup pierwszego jest bardziej opłacalny niż drugiego.

Absurdem jest architektura Twoich programów. Te algorytmy powinny zostać przeniesione do oddzielnych klas, wystawione jako publiczne metody i testowane normalnie. Teraz Twój kod łamie SRP, a testy są mało użyteczne, bo testują zbyt wiele.

Łukasz Hylicki napisał(a):

Tak. Jeśli chcesz poprawić jakość kodu legacy powinieneś najpierw pokryć dany kawałek kodu testami, a potem mając już siatkę bezpieczeństwa zrefaktoryzować go. Dopisany test Ci zagwarantuje, że refaktoryzując nie zepsujesz funkcjonalności.
Często właśnie się nie da napisać testu, bo kod jest niedostosowany i warto zrobić wtedy krok do tyłu, zepsuć enkapsulację, dopisać test, aby potem refactoringiem zrobić 10 kroków do przodu :)

Dlatego w przypadku refaktoryzacji najbardziej przydają się testy integracyjne. :)
No i gdzieś tam na szczycie zawsze jest jakaś publiczna metoda, do której można napisać testy, więc czy jest sens upubliczniać na siłę?

0
somekind napisał(a):

Dlatego w przypadku refaktoryzacji najbardziej przydają się testy integracyjne. :)
No i gdzieś tam na szczycie zawsze jest jakaś publiczna metoda, do której można napisać testy, więc czy jest sens upubliczniać na siłę?

A to testowanie integracyjne to nie jest testowanie na siłę? ;)
Bardzo często nikt wcześniej nie pomyślał, że ktoś chciałby w przyszłości dopisać testy i dlatego napisanie testu integracyjnego, który mock'uje dużą ilość serwisów, jakieś dostępy do bazy i wiele wiele innych zależności wiąże się z bardzo dużym kosztem czasowym.
Łatwiej wtedy jest coś na chwilę upublicznić, dopisać testy, zrefaktoryzować odważniej i finalnie ukryć implementację :)

0

Testy integracyjne, czyli testy sprawdzające rzeczywiste zachowanie systemu. Bez żadnych mocków.

0
somekind napisał(a):

Testy integracyjne, czyli testy sprawdzające rzeczywiste zachowanie systemu. Bez żadnych mocków.

To ok. Trochę odbiegliśmy od pierwotnego problemu.
Z mojej strony tylko krótka myśl: nie ma jedynego, słusznego rozwiązania każdej sytuacji w projekcie.
W jednych przypadkach testy integracyjne nam pomogą i zagwarantują bezpieczeństwo przy refactoringu, innym razem warto zaryzykować, coś potencjalnie zepsuć, aby potem poprawić sytuację w kodzie. Ważne aby rozważyć kilka strategii i wybrać tą, która najszybciej przyniesie korzyść :)

Pozdrawiam :)

0
somekind napisał(a):

Testy integracyjne, czyli testy sprawdzające rzeczywiste zachowanie systemu. Bez żadnych mocków.

@somekind, czyli do takiego podejścia warto postawić testową infrastrukturę? I np. robić replikę bazy co jakiś czas ?

2

@error91: bazę testową to ja zazwyczaj robię dla każdego test fixture nową. To ułatwia znalezienie błędów w razie jak się test wysypie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1