Wątek przeniesiony 2020-03-08 22:38 z Java przez Shalom.

Granice testów jednostkowych

Odpowiedz Nowy wątek
2020-03-06 14:04

Rejestracja: 4 miesiące temu

Ostatnio: 3 miesiące temu

0

Czy pisząc test dla danej metody z jakiegoś serwisu uderzając do testowej bazy danych to nadal test jednostkowy? Czy już integracyjny? Gdzie zaczynają są granice testów jednostkowych? Czy pisząc taki test powinno się mockować odpowiedź czy używać bazy danych?

Dobre pytanie, też się chętnie dowiem gdzie są te granice. :) - Michał Sikora 2020-03-06 14:18

Pozostało 580 znaków

2020-03-06 16:35

Rejestracja: 12 lat temu

Ostatnio: 2 godziny temu

0

https://github.com/ghsukumar/[...].T-Principles-of-Unit-Testing


IT menedżer

Pozostało 580 znaków

2020-03-06 17:11

Rejestracja: 5 lat temu

Ostatnio: 4 minuty temu

Lokalizacja: Poznań

4

Jednostką jest system :]

Testuejsz jednostkowo -> testujesz system


Spring? Ja tam wole mieć kontrole nad kodem ᕙ(ꔢ)ᕗ
Haste - mała biblioteka do testów z czasem.
edytowany 1x, ostatnio: danek, 2020-03-06 17:11
Czytałem materiały z ISTQB jak żona robiła z tego certyfikat. Definiują tam że testy jednostkowe testują jednostkę. Niestety nie znalazłem tam definicji czym jest jednostka :D - KamilAdam 2020-03-06 19:24

Pozostało 580 znaków

2020-03-06 17:34

Rejestracja: 6 miesięcy temu

Ostatnio: 4 tygodnie temu

0

Na to pytanie nie ma jednej odpowiedzi, wiele zalezy od kontekstu.

Dla przykładu bezpośrednie testy wewnętrznych rzeczy to wrażliwa sprawa i lepiej dla systemu gdyby zostały przetestowane nie wprost przez publiczne API, prawda?

Problemem dużych projektów jest fakt, że są zbyt duże. Jeśli wewnętrznie czuje się potrzebę przetestowania jakiejś wewnętrznej implementacji (bo łatwiej pisze się szczegółowe przypadki) to zastanów się czy nie lepiej byłoby wybranego kawała kodu zmienić w osobną bibliotekę.

I wtedy warto zadać sobie pytanie ile mamy tych API?

Jeśli masz osobną bibliotekę i napiszesz dla niej testy to mamy zbrodnię czy już jej nie mamy? A przecież przed chwilą kod tej biblioteki stanowił jakiś wewnętrzną część systemu :-)

Wydzielony kod nawet gdyby był ogólnego przeznaczenia (w sumie tym lepiej!) to nie jest koszt na zaś. Jeśli ktoś wydzieli z kodu implementacje listy, jakiejś matematycznej funkcji to pod wpływem zmiany wymagań wybrany fragment kodu nie straci swojego pierwotnego znaczenia. Tak samo jak liczenie sumy to nadal suma.

edytowany 1x, ostatnio: semicolon, 2020-03-06 17:35
mamy zbrodnię czy już jej nie mamy nie mamy, bo teraz testujesz funkcje osobnego systemu, jakim jest ta libka czy serwis ;) To jest zresztą taka sama dyskusja jak pomysły ludzi zeby testować nie tylko publiczne metody (co juz jest słabe) ale też i prywatne ;) - Shalom 2020-03-06 17:43
@semicolon: Chyba mylisz API z jakimiś Restami/SOAPami. Każda libka, każdy moduł powinien mieć publiczne api w sensie interfejsu w Javie przykładowo. I w testach właśnie powinieneś testować moduł tak jak inni go będą wykorzystywać. - nie100sowny 2020-03-06 21:48
Pod warunkiem, że istnieje. - semicolon 2020-03-06 21:58

Pozostało 580 znaków

2020-03-06 18:38

Rejestracja: 6 miesięcy temu

Ostatnio: 4 tygodnie temu

0

W sumie mam jeszcze jedną myśl wartą odnotowania à propos granic testów.

Granice testów (jakichkolwiek!) nie powinien wyznaczać ich rodzaj pokroju integracyjne/nieintegracyjne, szybkie/wolne, publiczne/prywatne, a fakt z jakim wiążą się ryzykiem.

Myślę, że ryzyko z projektem ciężej jest pojąć osobie, która co miesiąc robi to samo za to samo. Zupełnie inaczej podejście wygląda, gdy masz ograniczony budżet.

To nie jest tak, że wraz z kolejnym testem rośnie wartość projektu. W praktyce test to nic innego jak inwestycja, która oznacza pewien koszt i też jak inwestycja może w ogóle się nie zwrócić.

Programista powinien potrafić ocenić skalę ryzyka. Powinien wiedzieć co warto, a co nie warto testować. Powinien umieć to argumentować albo chociaż odwlekać w czasie aż lepiej zrozumie sytuację.

Programista, który tego nie czuje, i pisze testy jak z automatu bo task trzeba spiąć (lub w ogóle ich nie pisze) to strata. Bezmyślne testy nikomu nie służą.

Już lepiej ten czas na testy przeznaczyć na przemyślenie rozwiązania. Może jesteś w stanie coś uprościć, wpłynąć na wymaganie albo chociaż lepiej poznać potrzeby biznesowe jakie za nimi stoją :-) Taka zmiana jest 1000 razy więcej warta niż kolejny bezmyślny test.

edytowany 1x, ostatnio: semicolon, 2020-03-06 18:39
Pokaż pozostałe 10 komentarzy
Co do DSL to zwraca się jak masz złożony pipeline + jednocześnie dokumentuje przypadki pracy z systemem. A jak mieszasz testy jednostkowe i integracyjnie jednocześnie to tak naprawdę do końca nie wiadomo co osoba testuje. - semicolon 2020-03-06 21:43
Ah te skarjności. Ja nie powiedziałem że w 100% rezygnujemy z integracyjnych, a że nie trzeba ich dużo. dobrze skonfigurowałeś security chociażby security (permissions) sprawdza handler, no bo co innego? controller? <lol>, a controller (lub action) co najwyżej ma atrybut Authorize że user musi być zalogowany, tu nie ma co testować, ale i tak to przetestowaliśmy tym 1 czy 2 e2e. - WeiXiao 2020-03-06 21:46
Jeżeli weryfikacja uprawnień wymaga postawienia całej kobyły (HTTP) to chyba coś jest nie tak :O var user = CreateUserWithoutPermissionABC(); AssertEqual(NotSufficientPermissionResult, handler.Handle(command, user)) - WeiXiao 2020-03-06 21:49
@WeiXiao: pisałeś kiedykolwiek system z jakąś autentykacją i autoryzacją poważną (jakiś OAuth, CAS, Single-Sign-On) ? Bo mam wrażenie że nie jeśli wydaje ci się że to jest prosta rzecz do zrobienia i nie ma tam co testować ;) - Shalom 2020-03-06 22:17
@Shalom: zwykłe logowanie + uwierzytelnianie z innego servera (www.a.com => www.b.com, czyli SSO właściwie) za pomocą jwt (to już poważnie czy jeszcze nie? :D). I tego akurat nie chcesz testować unitowo, no ale przecież nie testujesz w każdym teście (np. dodania produktu) również SSO, bo po co? do tego masz kilka osobnych testów i tyle - WeiXiao 2020-03-06 22:25

Pozostało 580 znaków

2020-03-06 19:53

Rejestracja: 5 lat temu

Ostatnio: 4 minuty temu

Lokalizacja: Warszawa

3

Ja to tylko zostawie


Nie pomagam przez PM. Pytania zadaje się na forum.

Pozostało 580 znaków

2020-03-06 22:07

Rejestracja: 4 lata temu

Ostatnio: 12 minut temu

Lokalizacja: Kraków

3

Nie dziwi mnie, że temat jest tak rozgrzany. Na moje oko bezmyślne testowanie z moksturbacją to jeden z większych raków dzisiaj.

Zasady są proste:

  1. Dzielić system per usecase / agregat / funkcjonalność / komponent co kto ma u siebie.
  2. Ukrywać bebechy i eksponować wyłącznie publiczny interfejs do naszego usecase / agregatu / funkcjonalności / komponentu co kto ma u siebie.
  3. Testy pisać dla tego publicznego interfejsu, bo zwykle się rzadko zmienia. Bebechy często.
  4. Bazy danych, pliki, Resty stawiać w kodzie. Większość tego dzisiaj można postawić w pół sekundy i pięcioma linijkami w Javie. Pomaga tu np. localstack, Test Containers etc.
  5. Nic tylko refaktorować bebechy później, podbijać wersję Javy, przechodzić na GralVM i z Oracle na Postgresa :) Sama przyjemność.
  6. Staramy się testować wszystkie wartościowe dane wejściowe i stany, ale bez przesady. Aby nie duplikować kodu sprawdzają się testy parametryczne.

Ja jeszcze eksperymentuję z takim podejściem modułowym:
mózg-domain
mózg-application
mózg-tests

Czyli testy mam do domeny napisane w osobny module i importuję je w <scope>test</scope> zarówno w module domain i application. Z tym, że w domain podstawiam do nich mocki, a w application jakieś in-memory + docker cuda. Dzięki czemu lokalnie robię sobie szybkie TDD na mockach, a przed commitem o kilkanaście sekund wolniejsze mvn test. Z tym, że nie testowałem tego na PROD nigdzie. :) Unikam też w module domain zależności do połowy Maven Central w testach.

Co o tym sądzicie?


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"


edytowany 3x, ostatnio: nie100sowny, 2020-03-06 23:50

Pozostało 580 znaków

2020-03-06 23:21

Rejestracja: 6 lat temu

Ostatnio: 3 godziny temu

0

@Shalom: @jarekr000000: @semicolon
Czyli waszym zdaniem trzeba testować tak (każdą ścieżkę):
https://4programmers.net/Pastebin/15262

A testowanie w ten sposób:
https://4programmers.net/Pastebin/15261

To zbrodnia? A co jak by doszły jeszcze dwa warunek do metody get_count_pokemons? Wtedy trzeba by dodać 14 kolejnych testów. A jeszcze jakby jakiś nowy warunek na status doszedł to znowu mnożymy liczbę testów a to przecież raptem kilka warunków

Te testy można sparametryzować. - Inject 2020-03-06 23:32

Pozostało 580 znaków

2020-03-07 09:18
Moderator

Rejestracja: 16 lat temu

Ostatnio: 15 minut temu

1

@anonimowy: Jak zrobisz ten test parametryczny to będzie tylko jedna metoda i zestaw inputów/outputów, w praktyce jeszcze mniej kodu niż te twoje unit testy. A te unity w ogóle są słabe, bo nie wiadomo co testują. Nazwa testu powinna jasno określać co chcesz sprawdzić tak żeby wywalenie sie jasno komunikowało co nie działa. Jak masz 1000 asercji i realnie testujesz zupełnie różne rzeczy, to jest słabe.
Teraz wyobraź sobie że leci refaktor tego kodu i np. metoda get_is_seedable znika i zastępujemy to wszystko jakąś inną logiką, tak że wszystko nadal działa. Co się teraz stało?
W jednym przypadku masz cały czas testy chroniące przed regresją, bo sprawdzają czy funkcja systemu działa. W drugim masz praktycznie tylko testy do zaorania bo nawet sie nie skompilują. Spoko, możesz napisać nowe, kto bogatemu zabroni, tylko nie wiesz czy masz regresje czy nie...


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
edytowany 1x, ostatnio: Shalom, 2020-03-07 09:19

Pozostało 580 znaków

2020-03-07 10:33

Rejestracja: 6 lat temu

Ostatnio: 3 godziny temu

0

@Shalom No nie jestem w stanie zrozumieć twierdzenia, że nie ma tu regresji. Przecież mam test, który sprawdza widok w kilku przypadkach a jak get_is_seedable znika to znika również test do niego (co jest jak najbardziej ok i normalne, bo już się nie przyda po prostu. Tak samo jak byś wywalił logikę biznesowa to zmieniasz testy w Twoim przypadku).

Z tym, że jest dużo asercji to się zgodzę ale pisałem to na szybko i byle jak, chodziło mi o pokazanie koncepcji. Ale to jakby osobna kwestia.

W Twoim przypadku jeśli doszło by do jeszcze kilku innych warunków to przecież żeby każdą ścieżkę przerobić byłoby potrzebne tysiące testów a w niektórych przypadkach setki tysięcy czy miliony, to nie miałoby możliwości szybko działać.

Mógłbyś pokazać przykład takiego sparametryzowanego testu na moim przykładzie jak to powinno wyglądać według Ciebie?

Ja oczywiście nie neguję waszego podejścia do testowania ale uważam, że testowanie metod też jest jak najbardziej przydatne i pozwala szybciej wprowadzać zmiany

Pozostało 580 znaków

2020-03-07 12:27
Moderator

Rejestracja: 16 lat temu

Ostatnio: 15 minut temu

1

W Twoim przypadku jeśli doszło by do jeszcze kilku innych warunków to przecież żeby każdą ścieżkę przerobić byłoby potrzebne tysiące testów

To znaczy ze masz *ujowy design jak masz milion warunków ;)

Przecież mam test, który sprawdza widok w kilku przypadkach

W kilku wybranych xD sprawdzasz kro i mer a innych już nie. Jakiś geniusz wywalił przypadkiem obsługę pozostałych a ty nawet o tym nie wiesz :D

Mógłbyś pokazać przykład takiego sparametryzowanego testu na moim przykładzie jak to powinno wyglądać według Ciebie?

Serio? Przecież widzisz że wszystkie te testy wyglądają identyczne. Zrób w takim razie argumenty do nich...


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

Odpowiedz

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