Jak to jest z tymi mockami?

0
somekind napisał(a):
Riddle napisał(a):

Ale to że coś siedzi w bazie to szczegół implementacyjny Twojej persystencji, o którym testy nie powinny wiedzieć

Zgoda, ale przecież testy, które wywołują endpoint nie wiedzą nic o bazie.
Mam wrażenie, że @piotrpo miał na myśli testy integracyjne gdy pisał o testowaniu CRUDa.

Nie powinny, zgadzam się.

somekind napisał(a):
Riddle napisał(a):

Jak widzę takie nazwy, to już wiem że ten kod jest napisany w "pseudo obiektowy sposób" i i tak cała logika tej aplikacji jest rozsiana po tych klasach i nie da się jej przetestować w odizolowaniu.

I wiesz to nie widząc kodu, na podstawie samych nazw klas?

Pewny oczywiście nie jestem, ale mógłbym postawić np 1000zł że tak właśnie jest.

Takie nazwy sugerują że ktoś delikatnie się zapoznał z MVC, ale nie obszernie, i próbuje je odwzorować. Ale wiadomo, mogę się mylić. Może ktoś faktycznie zaprojektował dobrze ten system i akurat tak nazwał klasy. Ale my money is on the first option.

0
piotrpo napisał(a):

@somekind: Nie wiem czy to co mam na myśli, to testy integracyjne, jednostkowe, e2e czy może da się im nakleić jeszcze jakąś inną etykietkę. Wszystko co próbowałem nieudolnie napisać, to że testy powinny być tworzone maksymalnie wysoko i bez wnikania w sposób implementacji. Jeżeli mam np. mikroserwis, zajmujący się obsługą CRUD jakiegoś obiektu biznesowego, to da się jego funkcjonalność przetestować "black box", czyli z poziomu API, bo wywołanie POST, PUT, DELETE zmienia wynik zwracany przez GET. W takim razie, z tego poziomu powinno dać się przetestować całą funkcjonalność aplikacji.
Problemem jest to, że czasami nie da się tego zaimplementować, bo np. po drodze podnosi się jakiś wielgachny serwer aplikacyjny i trwa to najzwyczajniej w świecie za długo, albo rolą tej usługi jest nie tylko zmiana danych na warstwie persistent, ale również wysyłanie informacji o dokonanych zmianach do jakiejś kolejki. To wrzucenie do kolejki będzie pokryte z automatu, ale nie będzie przetestowanie, bo nie ma tam asercji. Pewnie nie chcemy tego robić na żywym systemie, albo nawet na jakimś środowisku, bo jeżeli 2 programistów w tym samym czasie puści testy, to ich wynik będzie przypadkowy. Więc zasadne stanie się użycie jakiegoś mocka. Tym mockiem może być albo lokalnie odpalona kolejka, albo jakiś mock drivera kolejki, na którym sprawdzimy, czy faktycznie zostało wywołane to co miało zostać wywołane. Wstawienie tego mock'a jest kompromisem pomiędzy tym co chcemy zrobić i jakimiś dodatkowymi ograniczeniami, typu działa za wolno, albo nie chcemy wysyłać tego przelewu naprawdę.

Jeżeli testujemy prostego CRUD'a, to testy ma poziomie REST API pozwalają przetestować całą funkcjonalność, bez nadmiernych kosztów, a jednocześnie to co jest za tym API, nie jest w żaden sposób zabetonowane testami.

Chyba mamy inne rozumienie tego co znaczy "przetestowana" funkcjonalność. Mam wrażenie że masz trochę niżej postawioną poprzeczkę, czegoś co według Ciebie można uznać za przetestowane.

Rozumiem że jeśli zrobić request pod endpoint i dostaniesz jakiś kod oraz response, to to znaczy że to jest przetestowane.

Ja mam trochę inne kryterium.

Możesz sobie nawet podmienić tę Javę na Pythona i testy nadal będą przechodzić, pomijając ewentualne trudności z ich odpaleniem. Jeżeli napiszę testy do kontrolera, to z jednej strony jakiś kawałek logiki aplikacji nie zostanie pokryty testami (mapowanie na endpointy, konfiguracja parsera JSON itp.), z drugiej strony zabetonuję np. nazwy metod tego kontrolera, czyli patrząc tylko na testy - jest gorzej. Nie twierdzę, że nie wolno tak robić, albo, że tak jest źle, ale płacimy jakością testów i muszę sobie zadać pytanie co za to kupuję i czy ta cena nie jest zbyt wysoka.

Ale nadal testowanie aplikacji jest uzależnione od interfejsu HTTP.

Zgadzam się że testowanie aplikacji jest trudne. Musi być spełniony szeroki szereg wymagań, żeby można było powiedzieć że coś jest dobrze przetestowane, rozwiązanie które Ty prezentujesz spełnia tylko kilka z nich. Więc dla mnie nie jest wystarczająco dobre. Jasne, ma kilka zalet, ale wady też masz. Według mnie należałoby poprawić te testy żeby wyeliminować te wady, jednocześnie nie prowadząc do overenigneeringu. To jest trudne, co wyjaśnia czemu większość programmerów tego nie robi, ale jeśli już się umie to zyski są warte wysiłku, zarówno na krótką i długa metę.

2

@Riddle: To gdzie twoim zdaniem jest ta poprzeczka? Mam do zrobienia serwis, którego jedynym zadaniem jest obsługa GET, POST, PUT, DELETE na konkretnym endpoincie. To przetestuję, czy on to robi, włączając w to przypadki brzegowe, typu pobranie pustej listy.
Mogę albo zrobić to przez HTTP (dodatkowa zależność, bo test padnie jak np. jakiś tam port na maszynie będzie już zajęty), albo pozbyć się tego ryzyka i testować "logikę", ale kosztem nie testowania mapowań endpointu na konkretne metody logiki biznesowej.

2
Riddle napisał(a):
iksde napisał(a):

Czyli zakładając, że masz jakiś ProductController, ProductRepository i ProductService przetestowałbyś:

  1. ProductController, mockując ProductService
  2. ProductService, mockując ProductRepository
  3. ProductRepository na "żywej" bazie?

Jak widzę takie nazwy, to już wiem że ten kod jest napisany w "pseudo obiektowy sposób" i i tak cała logika tej aplikacji jest rozsiana po tych klasach i nie da się jej przetestować w odizolowaniu.

Należałoby je zrefaktorować w taki sposób, żeby faktycznie wszystko czego wymagałbym od systemu jest w tej klasie "service", ale nie sądzę że to można powiedzieć o takim przykładzie.

Przypominam, że rozważamy prosty CRUD (a właściwie CR bez UD) gdzie jedyne wymagania dot. serwisu to zapisanie produktu przez POST /products i pobranie wszystkich produktów pod GET /products. Nie napisałem tego explcit, ale wydaje mi się, że jasno to wynikało z mojego wcześniejszego posta.

Chcesz, żeby wszystkie te rzeczy były zaimplementowane w "service"? Czyli "service" parsowałby request HTTP, tłumaczyłby go na request domenowy, odpalał logikę sprawdzającą czy taki produkt można dodać, a potem zapisywałby go gdzieś?

Rozumiem że jeśli zrobić request pod endpoint i dostaniesz jakiś kod oraz response, to to znaczy że to jest przetestowane.

Jeśli założenie systemu jest takie, że request pod endpoint zwraca taki kod i taki response, to tak, moim zdaniem taki test wystarczy. Jeśli twoim nie to podaj kontrprzykład.

Myślę też że gdybym zaproponował jakie zmiany należałoby wprowadzić, żeby należycie przetestować te klasy to odpowiedziałbyś "nie ma to sensu " albo "nie ma na to czasu ", tym samym tracąc szanse na dobre przetestowanie tego.

To źle myślisz. Napisz co i jak byś zrobił.

0
iksde napisał(a):

Jeśli założenie systemu jest takie, że request pod endpoint zwraca taki kod i taki response, to tak, moim zdaniem taki test wystarczy. Jeśli twoim nie to podaj kontrprzykład.

Nie wystarczy, bo to nie są wymagania aplikacji.

To jest specyfika interfejsu który został wybrany.

To nie jest wymaganie samo w sobie.

0
Szalony Programista2 napisał(a):

Mocki się do niczego nie nadają, albo testujesz test, infrastrukturę, na co testować bibliotekę do testowania.

Oczywiście że się nadają. Nikt nie każe ci testować biblioteki do testowania.

Abstrahując już od mockowania infrastruktury czy jakichś zewnętrznych usług to można na przykład bardzo wygodnie przetestować skomplikowany branching na poziomie testów jednostkowych. Wystarczy tylko wprowadzić system w odpowiedni stan i zweryfikować czy jakaś konkretna metoda została wywołana z mniej lub bardziej skonkretyzowanymi parametrami.

1
var napisał(a):
Szalony Programista2 napisał(a):

Mocki się do niczego nie nadają, albo testujesz test, infrastrukturę, na co testować bibliotekę do testowania.

Oczywiście że się nadają. Nikt nie każe ci testować biblioteki do testowania.

Abstrahując już od mockowania infrastruktury czy jakichś zewnętrznych usług to można na przykład bardzo wygodnie przetestować skomplikowany branching na poziomie testów jednostkowych. Wystarczy tylko wprowadzić system w odpowiedni stan i zweryfikować czy jakaś konkretna metoda została wywołana z mniej lub bardziej skonkretyzowanymi parametrami.

I tym samym utrudnić refaktor tych usług.

Ludzie mylnie myślą o testach jako o "narzędziach do sprawdzania". Podczas gdy dużo lepiej jest o nich myśleć jak o "narzędziach zapewniających stabilność systemu podczas zmian i refaktoru".

1
Riddle napisał(a):

I tym samym utrudnić refaktor tych usług.

Nie wiem czy to takie wielkie utrudnienie. Przychodzi taka chwila że trzeba przestać myśleć o ciągłym refaktorze bo kod który się pisze nie jest celem samym w sobie. Pisze się go przede wszystkim po to aby umożliwić klientowi (kimkolwiek on jest) osiągnięcie jakiegoś określonego celu. Ideały ideałami ale realia są takie że ciągły refaktoring dość rzadko jest możliwy. Oczywiście, miejsca które się rozgrzebuje przy pracy warto sprzątać ale wątpię żeby wiele firm czy osób było zainteresowane płaceniem przede wszystkim za próby doprowadzania kodu do niemożliwej do osiągnięcia perfekcji.

Są miejsca które bardzo rzadko się zmienia. Kod w podstawowych bibliotekach, takich jak np obsługa komunikacji musi działać w 100% zgodnie z wymaganiami. W takich przypadkach rozsądnym posunięciem jest raczej traktować testy jako narzędzie do sprawdzania.

Skoro mamy wymagania, że jeśli wystąpi stan A to ma się wykonać akcja a i b a kiedy wystąpi stan B to ma się wykonać akcja c to dlaczego mam unikać testów które potwierdzają zgodność z wymaganiami?

Riddle napisał(a):

Ludzie mylnie myślą o testach jako o "narzędziach do sprawdzania". Podczas gdy dużo lepiej jest o nich myśleć jak o "narzędziach zapewniających stabilność systemu podczas zmian i refaktoru".

No ale przecież narzędzie zapewniające stabilność systemu podczas zmian i refaktoru robi to poprzez nic innego jak właśnie sprawdzanie zgodności działania kodu z jakąś specyfikacją.

2

@Riddle: Proste pytanie do ciebie, masz do napisania crud dla jednego obiektu.

  • Jaki test napiszesz pierwszy
  • Jakie kolejne testy uważasz za konieczne
  • Kiedy uznasz, że można skończyć
  • Czy i kiedy użyjesz do tego mocków?
0
var napisał(a):
Riddle napisał(a):

I tym samym utrudnić refaktor tych usług.

Nie wiem czy to takie wielkie utrudnienie. Przychodzi taka chwila że trzeba przestać myśleć o ciągłym refaktorze bo kod który się pisze nie jest celem samym w sobie. Pisze się go przede wszystkim po to aby umożliwić klientowi (kimkolwiek on jest) osiągnięcie jakiegoś określonego celu. Ideały ideałami ale realia są takie że ciągły refaktoring dość rzadko jest możliwy. Oczywiście, miejsca które się rozgrzebuje przy pracy warto sprzątać ale wątpię żeby wiele firm czy osób było zainteresowane płaceniem przede wszystkim za próby doprowadzania kodu do niemożliwej do osiągnięcia perfekcji.

Są miejsca które bardzo rzadko się zmienia. Kod w podstawowych bibliotekach, takich jak np obsługa komunikacji musi działać w 100% zgodnie z wymaganiami. W takich przypadkach rozsądnym posunięciem jest raczej traktować testy jako narzędzie do sprawdzania.

Skoro mamy wymagania, że jeśli wystąpi stan A to ma się wykonać akcja a i b a kiedy wystąpi stan B to ma się wykonać akcja c to dlaczego mam unikać testów które potwierdzają zgodność z wymaganiami?

Wymieniłeś kilka z kryteriów dobrych testów, ale nie wszystkie. Są jeszcze inne, które dobry programista powinien wziąć pod uwagę.

Nie osiągniesz perfekcji kodu, zgadzam się. Ale to nie oznacza że możesz świadomie zostawiać dziury w test suicie. To nie jest takie czarno-białe jak się wydaje.

Dodatkowo, jak zrobisz "narzędzie zapewniające stabilność podczas refaktoru" to ono też będzie w stanie całkowicie przetestować aplikacje. Tylko że przy okazji zapewni jego utrzymywalność na długie lata.

Riddle napisał(a):

Ludzie mylnie myślą o testach jako o "narzędziach do sprawdzania". Podczas gdy dużo lepiej jest o nich myśleć jak o "narzędziach zapewniających stabilność systemu podczas zmian i refaktoru".

No ale przecież narzędzie zapewniające stabilność systemu podczas zmian i refaktoru robi to poprzez nic innego jak właśnie sprawdzanie zgodności działania kodu z jakąś specyfikacją.

Tak Ci się zdaje, ale dobry test suite musi spełnić szereg kryteriów, i nie łatwo taki zrobić.

5

Wiem, ze to nie mozliwe, bo nikt nie bedzie tego robil po godzinach za frajer. Ale bardzo chetnie zobaczyl bym taka minimalistyczna apke, gdzie wszystkie testy sa "poprawne", nie ma mockow itp itd.

Niestety wiekszosc postow tutaj brzmi troche bardziej jak ideologia czy religia i ciezko znalezc odniesienie do rzeczywistosci.

2
Seken napisał(a):

Wiem, ze to nie mozliwe, bo nikt nie bedzie tego robil po godzinach za frajer. Ale bardzo chetnie zobaczyl bym taka minimalistyczna apke, gdzie wszystkie testy sa "poprawne", nie ma mockow itp itd.

Niestety wiekszosc postow tutaj brzmi troche bardziej jak ideologia czy religia i ciezko znalezc odniesienie do rzeczywistosci.

Możemy zrobić taką.

2
Seken napisał(a):

Ostatnio rozpocząłem prace w zupełnie innej dziedzinę zarówno pod względem technologii jak i produktu. Piszę głównie w Go, trochę mikroserwisow, z którymi jeszcze nie miałem do czynienia. W testach masa rzeczy jest zamockowana. Z jednej strony wygląda to "ładnie", a drugiej okazuje się że są bugi których te testy najwidoczniej nie łapią.

Pracując w C++ trafiałem na takie projekty gdzie tych mockow praktycznie nie było, a jak już to stanowiły powiedzmy z 10% zawartości testów w bardzo specyficznych przypadkach.

Przechodząc do rzeczy. Kiedy warto stosować mocki? Znacie również jakieś przykłady kiedy te "atrapy" są nadużywane? Co wtedy zrobić jeśli chcę być dobrym samarytaninem i polepszyć kod w którym na codzień się obracam?

Ja staram się trzymać zasad poniżej:

  • w Go wg mnie bardzo łatwo generuje się test double z pomocą IDE, mockery i podobne rodzaje tooli nie są konieczne jeśli zwraca się uwagę na architekturę.
  • mockujemy IO i granice modułów a nie wszystko, nie każdego kolaboratora bo to betonuje kod produkcyjny często
  • jak już korzystamy z bibliotek do mockowania to zwracam uwagę na kohezje klasy bo często łatwość w użyciu tych bibliotek sprawia że wrzuca się to wszędzie "jak leci"
1
TomG napisał(a):

Ja staram się trzymać zasad poniżej:

  • w Go wg mnie bardzo łatwo generuje się test double z pomocą IDE, mockery i podobne rodzaje tooli nie są konieczne jeśli zwraca się uwagę na architekturę.
  • mockujemy IO i granice modułów a nie wszystko, nie każdego kolaboratora bo to betonuje kod produkcyjny często
  • jak już korzystamy z bibliotek do mockowania to zwracam uwagę na kohezje klasy bo często łatwość w użyciu tych bibliotek sprawia że wrzuca się to wszędzie "jak leci"

Z pomoca ktorego IDE? Pewnie Goland masz na mysli czy moze sa takie pluginy do vscode? U mnie z tego co widze stostuje sie z zamilowaniem gomock w polaczeniu z mockgenem.
Cos konkretnie w temacie mockow?
U mnie jest sporo mikroserwisow (z ktorymi nigdy w zyciu nie mialem do czynienia) i przykladowo mamy mikroserwis A, ktory komunikuje sie z B oraz komunikuje sie z C, ale za posrednictwem B.

No i teraz praktycznie wszystkie testy gdzie wykorzystuje sie B i C sa zamockowane od gory do dolu.
Do tego dzisiaj zaliczylem jeszcze lepszego WTFa, bo poruszylem temat mockowania. Jest sobie test, ktory sprawdza czy pewien obiekt podczas tworzenia prawidlowo korzysta z envwow (tak wynika bezposrednio z nazwy testu!). No i w tescie mamy 6 linijek testu i 11 mockow z expectami itd. I teraz logika mojego kolegi z zespolu:
Jezeli wywalimy metode krzak() obiektu, ktory jest przekazywany podczas konstruowania to bez mockow nie zauwazymy, ze tej metody nie ma.

Moja odpowiedz byla prosta:

  1. Nazwa testu mowi jednoznacznie co sprawdzami, wiec co mnie jakies krzaki obchodza.
  2. Moze wlasnie najwidoczniej ta metoda krzak nie bedzie potrzebna, bo zostanie zastapiana krzakv2 i wszystko bedzie dzialac ladnie, a mocki to tylko betonuja.

No i niestety moje argumenty nie zostaly zrozumiane. Jest jakikolwiek sens w ogole kopac sie z takimi ludzmi?

0
1a2b3c4d5e napisał(a):

celem testów jest zapewnienie że kod działa (teraz i w przyszłości). celem testów nie jest refaktor, bo celem pisania kodu nie jest jego refaktorowanie.

Dawno nie widziałem większej bzdury.

1
Seken napisał(a):
TomG napisał(a):

Ja staram się trzymać zasad poniżej:

  • w Go wg mnie bardzo łatwo generuje się test double z pomocą IDE, mockery i podobne rodzaje tooli nie są konieczne jeśli zwraca się uwagę na architekturę.
  • mockujemy IO i granice modułów a nie wszystko, nie każdego kolaboratora bo to betonuje kod produkcyjny często
  • jak już korzystamy z bibliotek do mockowania to zwracam uwagę na kohezje klasy bo często łatwość w użyciu tych bibliotek sprawia że wrzuca się to wszędzie "jak leci"

Z pomoca ktorego IDE? Pewnie Goland masz na mysli czy moze sa takie pluginy do vscode? U mnie z tego co widze stostuje sie z zamilowaniem gomock w polaczeniu z mockgenem.
Cos konkretnie w temacie mockow?

Nie, nic odkrywczego. Goland i generowanie metod po interfejsach w Go

U mnie jest sporo mikroserwisow (z ktorymi nigdy w zyciu nie mialem do czynienia) i przykladowo mamy mikroserwis A, ktory komunikuje sie z B oraz komunikuje sie z C, ale za posrednictwem B.

No i teraz praktycznie wszystkie testy gdzie wykorzystuje sie B i C sa zamockowane od gory do dolu.

Tego w ogóle nie rozumiem. Jak piszesz testy jakieś integracyjne dla serwisu A to korzystasz z B i C które maja mocki o_O czy B i C są w teście A mockowane? Jeśli to drugie to w miarę dobrze bo to jest (prawdopodobnie) IO, ale od czego jest docker, testcontainers albo lepiej contract testing (pact.io)?

Do tego dzisiaj zaliczylem jeszcze lepszego WTFa, bo poruszylem temat mockowania. Jest sobie test, ktory sprawdza czy pewien obiekt podczas tworzenia prawidlowo korzysta z envwow (tak wynika bezposrednio z nazwy testu!). No i w tescie mamy 6 linijek testu i 11 mockow z expectami itd. I teraz logika mojego kolegi z zespolu:
Jezeli wywalimy metode krzak() obiektu, ktory jest przekazywany podczas konstruowania to bez mockow nie zauwazymy, ze tej metody nie ma.

To wygląda raczej na whitebox testing więc 2/10, więc...

Moja odpowiedz byla prosta:

  1. Nazwa testu mowi jednoznacznie co sprawdzami, wiec co mnie jakies krzaki obchodzą

...tutaj chyba masz rację.

  1. Moze wlasnie najwidoczniej ta metoda krzak nie bedzie potrzebna, bo zostanie zastapiana krzakv2 i wszystko bedzie dzialac ladnie, a mocki to tylko betonuja.

i tutaj też, ale trzeba by zobaczyć cały kod bo nie wiem czy dobrze rozumiem. Może być tak że metoda krzak to część algorytmu i np to chcemy zweryfikować. Tutaj wydaje mi się że lepiej by było napisać sobie swojego stub'a i pisać prosty test input, output a nie sprawdzać interakcje.

No i niestety moje argumenty nie zostaly zrozumiane. Jest jakikolwiek sens w ogole kopac sie z takimi ludzmi?

Podesłać im odnośniki do literatury i napisać kod lepiej pokazując zalety i wady nowego podejścia.

0
TomG napisał(a):

Tego w ogóle nie rozumiem. Jak piszesz testy jakieś integracyjne dla serwisu A to korzystasz z B i C które maja mocki o_O czy B i C są w teście A mockowane? Jeśli to drugie to w miarę dobrze bo to jest IO, ale od czego jest docker, testcontainers albo lepiej contract testing (pact.io)?

Tak, chodzi o unit testy i mockowanie B i C w testach serwisu A.

i tutaj też, ale trzeba by zobaczyć cały kod bo nie wiem czy dobrze rozumiem. Może być tak że metoda krzak to część algorytmu i np to chcemy zweryfikować. Tutaj wydaje mi się że lepiej by było napisać sobie swojego stub'a i pisać prosty test input, output a nie sprawdzać interakcje.

Tzn to nie jest czesc algorytmu, a skladowa jakiegos tam procesu inicjalizacji. Nie mniej jednak nawet jesli mialaby nas interesowac ta metoda (a raczej nie powinna) to konieczne powinnismy to robic w innym tescie, bo ten jasno wskazuje, ze sprawdza envy i tyle, metoda krzak zupelnie nie jest z nimi zwiazana.

No i niestety moje argumenty nie zostaly zrozumiane. Jest jakikolwiek sens w ogole kopac sie z takimi ludzmi?

Podesłać im odnośniki do literatury i napisać kod lepiej pokazując zalety i wady nowego podejścia.

No wlasnie pokazalem na przykladzie tego testu o ktorym rozmawiamy, moje rozwiazanie mialo 10 linijek wraz z calym sprzataniem, a ich kolo 22 + mase zawilych expectow. Ale 80% ludzi w zespole zachowuje sie jakby mieli wszystko gdzies i tylko chcieli odsiedziec dupogodziny, wiec sie nie odzywa. A moj nemezis twierdzi, ze to wlasnie jest bez sensu, bo jego zdaniem jak juz mowilem:
Jezeli wywalimy metode krzak() obiektu, ktory jest przekazywany podczas konstruowania to bez mockow nie zauwazymy, ze tej metody nie ma.

btw. Tym packtem wlasnie zaczynam sie powoli interesowac. Czy to rozwiazanie ma jakikolwiek sens bez zastosowania brokera? Ile mniej wiecej zajelo Ci ogarniecie tej libki zeby zaczac pisac sensowne testy z jej wykorzystaniem? Z testami kontraktow api nie mialem zbyt wiele do czynienia.

2
Seken napisał(a):

Jezeli wywalimy metode krzak() obiektu, ktory jest przekazywany podczas konstruowania to bez mockow nie zauwazymy, ze tej metody nie ma.

  • Dlaczego bez mocków nie zauważysz, że jakaś metoda nie istnieje (i dlaczego z mockami zauważysz)?
  • Czy brak tej metody spowoduje, że jednostka, którą testujesz nie będzie działać?
0

@piotrpo:
Zauwazysz, bo robisz expecta, ale ja przeciez juz na to wszystko odpowiedzialem wyzej, wiec troche nie rozumiem do czego zmierzasz.

Seken napisał(a):

Moja odpowiedz byla prosta:

  1. Nazwa testu mowi jednoznacznie co sprawdzami, wiec co mnie jakies krzaki obchodza.
  2. Moze wlasnie najwidoczniej ta metoda krzak nie bedzie potrzebna, bo zostanie zastapiana krzakv2 i wszystko bedzie dzialac ladnie, a mocki to tylko betonuja.

No i niestety moje argumenty nie zostaly zrozumiane. Jest jakikolwiek sens w ogole kopac sie z takimi ludzmi?

0

@Seken: Czy dobrze rozumiem, że metoda krzak() to request do innego mikroserwisu? a rolą A, jest dostać żądanie i wygenerować kolejne do innej usługi?

0
piotrpo napisał(a):

@Seken: Czy dobrze rozumiem, że metoda krzak() to request do innego mikroserwisu? a rolą A, jest dostać żądanie i wygenerować kolejne do innej usługi?

Nie. Mamy metode, ktora tworzy nam obiekt sluzacy do zarzadzania mikroserwisem A (powiedzmy w telegraficznym skrocie). Ta metoda przyjmuje w argumentach inne obiekty i jakis tam obiekt X wola sobie wlasnie metode krzak wewnatrz wczesniej wspomnianej metody.

3

celem testów jest zapewnienie że kod działa (teraz i w przyszłości). celem testów nie jest refaktor, bo celem pisania kodu nie jest jego refaktorowanie.

Celem testów jest też łatwiejsza możliwość refaktoru kodu lub zmiany funkcji systemu. Ja piszę po to też testy (integracyjne) żebym mógł zrobić refaktor czy zmienić logikę związaną z daną częścią systemu, nie martwiąc się że rozwale proda.

1

@scibi_92

Celem testów jest też łatwiejsza możliwość refaktoru kodu lub zmiany funkcji systemu.

imo to jest po prostu dodatkowy bonus.

Ja piszę test po to, aby

  1. udowodnić że aktualna implementacja jest poprawna
  2. udowodnić że zmiany w kodzie w przyszłości nadal są poprawne

ktoś może dyskutować że w sumie 2 to tak jakby refaktor, isn't it? imo nie.

A to że tam kiedyś być może będzie jakiś refaktor to nawet nie biorę pod uwagę w 9/10 przypadków, bo przecież jeżeli bym podejrzewał że będzie, to od razu bym to napisał "dobrze"

A ta reszta przypadków to właśnie umyślne zaciąganie "technicznej inwestycji" (tech debt ;)) albo po prostu życie, ale to jest po prostu mniej prawdopodobne niż to, że raz napisany kod się po prostu nie zmieni.

1

@Seken: W takim razie, te testy z mockami nie testują co, tylko jak. Zakładając, że np, taki nowoutworzony obiekt musi się zarejestrować gdzieś tam, w czymś tam, to nie widzę sensu pisania takiego testu.

4

A to że tam kiedyś być może będzie jakiś refaktor to nawet nie biorę pod uwagę w 9/10 przypadków, bo przecież jeżeli bym podejrzewał że będzie, to od razu bym to napisał "dobrze"

Takie założenie byłoby słuszne gdybys założył że Twoja wiedza i umiejętności są statyczne oraz nie jesteś w stanie długoterminowo zauważyć co nie tak zrobileś. Dodatkowo refaktor nie koniecznie musi wynikać z błędu. Na przykład możemy założyć że w danym systemie obsługujemy tylko dany rodzaj eksportu plików, i nie ma sensu robić na zapas jakiejś abstrakcji. Później może się okazać że jednak chcemy móc eksportować do wielu różnych typów plików.

0
piotrpo napisał(a):

@Seken: W takim razie, te testy z mockami nie testują co, tylko jak. Zakładając, że np, taki nowoutworzony obiekt musi się zarejestrować gdzieś tam, w czymś tam, to nie widzę sensu pisania takiego testu.

Ja rowniez twierdze, ze te testy sa o kant d**y. Stad moje pytanie:

No i niestety moje argumenty nie zostaly zrozumiane. Jest jakikolwiek sens w ogole kopac sie z takimi ludzmi?

0

@scibi_92:

Takie założenie byłoby słuszne gdybys założył że Twoja wiedza i umiejętności są statyczne oraz nie jesteś w stanie długoterminowo zauważyć co nie tak zrobileś.

No dobra, to teraz wróćmy do prawdopodobieństwa.

Jaki masz stosunek linijek których nigdy nie zmieniłeś do takich, które zmieniłeś?

Bo ja śmiem twierdzić że przeważająca większość nie ulega zmianie, a zatem nie podchodzę do pisania kodu z myślą że będę go refaktorował, bo po prostu jest to unlikely.

0
1a2b3c4d5e napisał(a):

No dobra, to teraz wróćmy do prawdopodobieństwa.

Jaki masz stosunek linijek których nigdy nie zmieniłeś do takich, które zmieniłeś?

A może trochę inna statystyka. Jaki procent błędów powstał na skutek zmiany w kodzie, a jaki na skutek braku takiej zmiany?

0

Jaki masz stosunek linijek których nigdy nie zmieniłeś do takich, które zmieniłeś?

Są takie funkcje systemu które cały czas praktycznie zmieniam , są takie które są zmieniane raz na rok czy dwa lata, ale nadal myślę że sporo kodu jest zmieniane.

0

@piotrpo:

Jak błąd może "powstać" wskutek braku zmiany/refaktora?

Jeżeli rzeczywistość uległa zmianie i kod już tego nie odzwierciedla, to jego niedostosowanie zazwyczaj wynika z nieświadomości, z powodów biznesowych (kasa), czy może nawet technicznych ograniczeń, ale to chyba skrajność.

A jeżeli nie jesteś świadomy, to i tak nie stoisz przed decyzją - robić zmianę/refaktor czy też nie?

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