Testy integracyjne - MockMVC vs WebTestClient

2
hawus napisał(a):

To nie jest trudnie, to jest fizycznie niemożliwe. Jak mam zrobić, żeby test polegający na czymś, nad czym nie mam kontroli, zawsze był zielony? To, że go nazwę jednostkowym a nie integracyjnym nic nie zmieni. Nawet taki najczystszy, jednostkowy (wg wszelkich definicji) test może się wykrzaczyć przez bit flip, a co dopiero test, który polega na komunikacji międzyprocesowej i zewnętrznym systemie. Karta sieciowa odmówi posłuszeństwa. Zewnętrzny system ma memory leaka, albo działa inaczej jak jest pełnia. Nie jesteś w stanie tego przewidzieć.

No i?
Czy to znaczy, że testów nie warto robić, bo może być bit flip?
Jaki zewnętrzny system? A jak używasz HashMapy w javie to jest zewnętrzny system?
Bo generalnie czy używasz hashmapy czy bazy danych to różnica prawie żadna? Wywołujesz cudzy kod.
Przy bazie danych jest to może 3 linijki kodu więcej na starcie.
I żadne karty sieciowe (moze poza wirtualnymi) nie muszą być w to zamieszane. (mogą, ale nie muszą).

0
jarekr000000 napisał(a):
hawus napisał(a):

To nie jest trudnie, to jest fizycznie niemożliwe. Jak mam zrobić, żeby test polegający na czymś, nad czym nie mam kontroli, zawsze był zielony? To, że go nazwę jednostkowym a nie integracyjnym nic nie zmieni. Nawet taki najczystszy, jednostkowy (wg wszelkich definicji) test może się wykrzaczyć przez bit flip, a co dopiero test, który polega na komunikacji międzyprocesowej i zewnętrznym systemie. Karta sieciowa odmówi posłuszeństwa. Zewnętrzny system ma memory leaka, albo działa inaczej jak jest pełnia. Nie jesteś w stanie tego przewidzieć.

No i?
Czy to znaczy, że testów nie warto robić, bo może być bit flip?

Absolutnie nie, piję tylko do stwierdzenia, że każdy test może być w 100% deterministyczny.

0
hawus napisał(a):
jarekr000000 napisał(a):
hawus napisał(a):

To nie jest trudnie, to jest fizycznie niemożliwe. Jak mam zrobić, żeby test polegający na czymś, nad czym nie mam kontroli, zawsze był zielony? To, że go nazwę jednostkowym a nie integracyjnym nic nie zmieni. Nawet taki najczystszy, jednostkowy (wg wszelkich definicji) test może się wykrzaczyć przez bit flip, a co dopiero test, który polega na komunikacji międzyprocesowej i zewnętrznym systemie. Karta sieciowa odmówi posłuszeństwa. Zewnętrzny system ma memory leaka, albo działa inaczej jak jest pełnia. Nie jesteś w stanie tego przewidzieć.

No i?
Czy to znaczy, że testów nie warto robić, bo może być bit flip?

Absolutnie nie, piję tylko do stwierdzenia, że każdy test może być w 100% deterministyczny.

Mi chodziło o to, że powinieneś mieć takie testy, że można bez problemu je odpalić np. 100 razy i dają taki sam wynik. Ale mają działać też szybko.

Chciałem się odnieść do wcześniejszego tekstu, że ktoś ma testy, które odpala kilka razy, bo 2/3 dają poprawny wynik, a 1/3 mają false-positive, i chciałęm powiedzieć że takie testy są bardzo słabe, i należy je poprawić. Wiadomo że raz na milion może wyjść jakiś dziwny case, bo promień kosmiczny walnie w tranzysor, czy coś; mi chodzi tylko o to że nie można pracować tak że cały dzień odpalasz testy, i one co chwila randomowo failują. To takie testy są worthless.

0
Riddle napisał(a):

Chciałem się odnieść do wcześniejszego tekstu, że ktoś ma testy, które odpala kilka razy, bo 2/3 dają poprawny wynik, a 1/3 mają false-positive, i chciałęm powiedzieć że takie testy są bardzo słabe, i należy je poprawić. Wiadomo że raz na milion może wyjść jakiś dziwny case, bo promień kosmiczny walnie w tranzysor, czy coś; mi chodzi tylko o to że nie można pracować tak że cały dzień odpalasz testy, i one co chwila randomowo failują. To takie testy są worthless.

Jeśli to do mojej wypowiedzi. To napisałem, że nie da się fizycznie tego poprawić bo webdrivery do przeglądarek mają bugi.
Tutaj np link https://bugs.chromium.org/p/chromedriver/issues/detail?id=4698 do buga gdzie zwykła kombinacja click() i navigate.to() cytuje potwierdzenie buga z komentarza, że "ChromeDriver requires 30 - 120 attempts to get crashed".

I chyba nie istniała sytuacja gdzie jak testujesz na 6-8 przeglądarkach (firefox, chrom, safari + wersje mobilne) że w którymś akurat nie ma bugów na którymś środowisku.

Więc alternatywą jest retry an CI albo zatrudnienie dodatkowych paru testerów na full time. BO NIE MA INNEJ TECHNOLOGICZNEJ ALTERNATYWY.
Więc licząc nawet 4h na tydzien na sprawdzanie czy jebło to rocznie przy 50tygodniach masz 25MD vs 500MD w przypadku zatrudnienia testerów.

0
Schadoow napisał(a):

Jeśli to do mojej wypowiedzi. To napisałem, że nie da się fizycznie tego poprawić bo webdrivery do przeglądarek mają bugi.
Tutaj np link https://bugs.chromium.org/p/chromedriver/issues/detail?id=4698 do buga gdzie zwykła kombinacja click() i navigate.to() cytuje potwierdzenie buga z komentarza, że "ChromeDriver requires 30 - 120 attempts to get crashed".

I chyba nie istniała sytuacja gdzie jak testujesz na 6-8 przeglądarkach (firefox, chrom, safari + wersje mobilne) że w którymś akurat nie ma bugów na którymś środowisku.

Więc alternatywą jest retry an CI albo zatrudnienie dodatkowych paru testerów na full time. BO NIE MA INNEJ TECHNOLOGICZNEJ ALTERNATYWY.
Więc licząc nawet 4h na tydzien na sprawdzanie czy jebło to rocznie przy 50tygodniach masz 25MD vs 500MD w przypadku zatrudnienia testerów.

No i? Bugi są w każdym systemie.

Twój argument brzmi "nie da się napisać deterministycznych testów bo jest bug w chrome driverze"? Co za bzdura.

  • Po pierwsze dlatego, że bugi można naprawić. Możesz nawet zrobić forka i sam go poprawić.
  • Po drugie - zasadność tego argumentu - Czy jak znajde buga w dockerze, to mogę głosić "wirtualizacja jest niemożliwa"?
  • Po trzecie, każe Ci ktoś używać tego konkretnego drivera?
  • Po czwarte, każe Ci ktoś odpalać testy w takim środowisku? Są inne sposoby na napisanie testów, tylko trzeba chcieć je znaleźć. Np edytor postów na forum z którego korzystasz ma jakieś 1000 testów które się odpalają na node+jsdom, i jakoś działają i mają 100% coverage, i nie failują randomowo. Wiadomo że nie nadaje się to do każdego projektu, ale do każdego projektu da się znaleźć jakieś rozwiązanie.
  • Po piąte - ja normalnie w każdym jednym projekcie w jakim pracuje znajduje jakoś sposób na napisanie deterministycznych testów. To co, farta mam że mi się udaje? Czy może kłamię? Czy co? Czy może jednak nie mam zatwierdzonego w głowie dziwnego pomysłu że "czasem testy mogą failować randomowo".

Jak czytam Twoje posty, to po prostu strasznie chcesz znaleźć jakąś wymówkę która pozwoliłaby Ci nie pisać testów dobrych bo Ci się nie chce. Ludzie normalnie tworzą całe UI z deterministycznymi testami i żyją. Ale nie, bo @Schadoow mówi że jest bug w driverze.

Powtarzam: Twoja nieumiejętność do napisania takich testów, to nie jest argument przeciwko nim. To jest po prostu sygnał dla Ciebie że masz room na improvement.

Jeśli strasznie chcesz rozmawiać na przykładzie, to stwórz jakiś projekt w którym masz jakieś zachowanie które chcesz dodać, to Ci pokażę jak napisać deterministyczny test pod to. Podeślij linka do githuba.

0

@Riddle weź już nie pisz

3

@Riddle każda skrajność jest zła. Ty z braku testów poszedłeś do jakiejś abstrakcji w drugą stronę. Co mam powiedziec szefowi ze nie bedzie zmian o ktore prosil bo poprawiam bugi w chrome driverze?
Testy powinny być takie zeby dac nam znac ze aplikacja dziala ok. Jak sa niestabilne to mozna ustawic rerun jeśli w zespole sobie ustalimy ze dla nas to jest ok.

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

Można sobie coś zamokować, obejść i puścić 1000 testów w kilka sekund. Ale e2e? Co w przypadku testowania integracji apki mikroserwisowej składającej się z x serwisów i kilku rabbitów / event hubów (albo kafek) / storydzy itp pomiędzy.

Trzeba kombinować, żeby to przyspieszyć. Albo podzielić na kawałki, albo usunąć niepotrzebne rzeczy, albo dodać cache, albo zastosować jeden z milionów tricków które się stosuje normalnie w developmencie.

Czyli tak na prawdę mockować część ścieżki, co może i będzie szybsze, ale zaburzy cały proces i może być false positive.

Riddle napisał(a):
ledi12 napisał(a):

A niech jeszcze wszystko jeszcze stoi na AKS albo innej kedzie. Wszystkie te toole same w sobie mają pewne czasowe ograniczenia i deleye i siłą rzeczy nie da się tego przyspieszyć.

No to trzeba przenieść jak najwięcej testów się da na lokalne środowisko, a na AWS zostawić tylko i wyłącznie absolutne minimum.

Jak wyżej. Jeżeli mam proces zależny od zasobów cloudowych i chce przetestować całą integrację z tym związaną to siłą rzeczy muszę polegać na cloudzie (Jednocześnie akceptując wszystkie opóźnienia z tym związane). Oczywiście mogę sobie wszystko imitować lokalnie i znowu to co wyżej -> duża szansa false positive.

[Riddle napisał(a)](/Forum/1952280
ledi12 napisał(a):

Możemy sobie zamokować część ścieżki w celu przyspieszenia, ale czy nadal to będzie pełno prawna "integracja"?

Integracje się testuje osobno, a zachowanie osobno. Miej jeden test integracyjny z prawdziwą ścieżką, a pozostałe niech testują zachowanie ze zmockowaną ścieżką.

ale czy nadal to będzie pełno prawna "integracja"? Bardzo prosto się możesz o tym przekonać. Zakomentuj w kodzie lub usuń jakiś fragment, który wymaga tej integracji. Testy failują? To jest "pełnoprawna integracja". Żaden test nie wykrył tego buga? Testy zepsute.

To przekonanie że "testy muszą być wolne" to jest jakaś zaraza w naszej branży. Jak masz wolne testy, to przestają Ci pomagać, i zaczynają przeszkadzać.

To nie kwestia przekonania. Są testy, które mogą być szybkie (Unity, logika sama w sobie) i są też testy e2e (end to end, integracja, zwał jak zwał) które powinny bazować w pełni na finalnych zasobach (cloud, kafki itp) a to wiąże się z konkretnym czasem egzekucji. Tylko wtedy mam pewność, że mój program działa w pełni. Kombinacje / mockowanie mi tej pewności nie dają.

0
Ziemiak napisał(a):

@Riddle każda skrajność jest zła. Ty z braku testów poszedłeś do jakiejś abstrakcji w drugą stronę. Co mam powiedziec szefowi ze nie bedzie zmian o ktore prosil bo poprawiam bugi w chrome driverze?

To mi pachnie złym symptomem, czyli robienie złych/słabych testów, przez pressure z góry. To jest bardzo zły symptom, świadczy o braku asertywności i w gruncie rzeczy braku profesjonalizmu. Ty jako programista masz wiedzieć co jest ważne żeby dostarczyć feature. I testy jaknajbardziej są ważne.

Poza tym, czemu miałbyś mu powiedzieć że nie będzie zmian? Powiedz mu "Dodanie tego feature wymaga żeby go odpowiednio zaprogramować", zaczynasz robić, robisz w małych krokach, i dostarczasz funkcje po kolei. I w "zaprogarmować" jest oczywiście "napisać kod" oraz "napisać testy". Testy to jest nieodzowna część developmentu.

To że myślisz o tym w odrębnych kategoriach, że jakoś napisanie testów to jest coś dodatkowego/opcjonalnego bardzo źle świadczy.

Ziemiak napisał(a):

Testy powinny być takie zeby dac nam znac ze aplikacja dziala ok. Jak sa niestabilne to mozna ustawic rerun jeśli w zespole sobie ustalimy ze dla nas to jest ok.

To jest bardzo słabe. Gratuluję pracy w takim stylu.

ledi12 napisał(a):

Czyli tak na prawdę mockować część ścieżki, co może i będzie szybsze, ale zaburzy cały proces i może być false positive.

Czemu miałoby zaburzać proces?

I jeśli może być false positive, to ten jeden test który ma prawdziwą, niezmockowaną ścieżką go złapie.

ledi12 napisał(a):

Jak wyżej. Jeżeli mam proces zależny od zasobów cloudowych i chce przetestować całą integrację z tym związaną to siłą rzeczy muszę polegać na cloudzie (Jednocześnie akceptując wszystkie opóźnienia z tym związane). Oczywiście mogę sobie wszystko imitować lokalnie i znowu to co wyżej -> duża szansa false positive.

Czyli mówisz, że jeśli Twój codebase jest poprawny, ale nie działa jakiś cloud sieciowy, to chcesz żeby Twoje testy lokalne sfailowały? Po co?

@ledi12 Ja nie mówię Ci jak masz robić te testy, możesz je pisać jak chcesz. To co Ci mogę powiedzieć na 100%, to to, że wolne testy po pierwsze bardzo przeszkadzają w pracy, a po trzecie w każdym jednym przypadku da się je przyspieszyć do sensownych prędkości, i absolutnie nie kupuję wiadomości że "nie da się", bo ja od wielu lat tak pracuję, też integruję się z wieloma systemami, i jakoś nigdy nie mam testów które długo trwają. Jak pisałem, nie jest łatwe to zrobić, ale da się.

ledi12 napisał(a):

To nie kwestia przekonania. Są testy, które mogą być szybkie (Unity, logika sama w sobie) i są też testy e2e (end to end, integracja, zwał jak zwał) które powinny bazować w pełni na finalnych zasobach (cloud, kafki itp) a to wiąże się z konkretnym czasem egzekucji. Tylko wtedy mam pewność, że mój program działa w pełni. Kombinacje / mockowanie mi tej pewności nie dają.

które powinny bazować w pełni na finalnych zasobach I tym finalnym zasobem jest coś Twojego, czy zewnętrznego? Jeśli Twojego, to masz kontrolę nad tym żeby to przyspieszyć do testów. Jeśli nie Twojego, to Twoje testy nie powinny failować jak to coś nie działa. Powinny sfailować tylko jak Twój program nie działa.

Tylko wtedy mam pewność, że mój program działa w pełni Twój program, czy zależności Twojego programu, nad którymi i tak nie masz kontroli?

Bo testy nie powinny failować jeśli jakaś zależność sieciowa zewnętrzna leży.

Jeśli piszesz program który korzysta z zewnętrznego serwisu (np stripe), to Ty nie masz nad nim kontroli. Jedyne co możesz zrobić, to obsłużyć w swojej aplikacji co Twoja aplikacja ma robić jak ta apka padnie, i pod to powinny być testy.

Dodatkowo - testy powinny przechodzić dla danego commita nie zależnie od daty. Jeśli piszę kod, odpalam testy, one przechodzą, robię commit, i teraz nagle stripe pada, to jak wrócę na mój commit, to testy mają mi dać dokładnie taki sam wynik jaki dały w momencie robienia tego commita.

To o czym mówisz, że Twoje testy miałyby zależeć od zewnętrznego providera, to jest dodanie tight-coupling na coś co po pierwsze jest mega wolne, a po drugie nie masz nad tym kontroli w ogóle. To jest bardzo zły pomysł. I robisz to wszystko w imię "sprawdzenia czy mój system działa", tylko że sprawdzić czy system działa da się dużo lepiej i szybciej, niż faktycznie strzelać do zewnętrznego serwisu.

2
Riddle napisał(a):

To mi pachnie złym symptomem, czyli robienie złych/słabych testów, przez pressure z góry. To jest bardzo zły symptom, świadczy o braku asertywności i w gruncie rzeczy braku profesjonalizmu. Ty jako programista masz wiedzieć co jest ważne żeby dostarczyć feature. I testy jaknajbardziej są ważne.

Poza tym, czemu miałbyś mu powiedzieć że nie będzie zmian? Powiedz mu "Dodanie tego feature wymaga żeby go odpowiednio zaprogramować", zaczynasz robić, robisz w małych krokach, i dostarczasz funkcje po kolei. I w "zaprogarmować" jest oczywiście "napisać kod" oraz "napisać testy". Testy to jest nieodzowna część developmentu.

To że myślisz o tym w odrębnych kategoriach, że jakoś napisanie testów to jest coś dodatkowego/opcjonalnego bardzo źle świadczy.

No to rozważmy dwie opcje. Jedno robie zmianę + dopisuje do niej testy. Wiem ze chrome driver ma swoje bolaczki wiec ustawiam mu rerun zeby losowy timeout (nie wynikajacym z moich kodow) nie wywalal mi testow. Zrobie to w tydzien i jest.
vs
Robie zmiane i dopisuje do niej testy. Testy sa losowe niestabilne. Siadam wiec do chrome drivera i zaczynam poprawiać bugi. Mineło pół roku... poprawiam te bugi dalej o ile mnie wcześniej nie zwolnią bo nie chce skończyć prostej zmiany na kilka dni bo ciagle te testy w 100% nie są stabilne plus biznes dostaje białej gorączki bo zmiany do których np. obliguje ich ustawa nie ma co powoduje ogromne straty. No przecież to jest niedorzeczne. Swiat nie jest idealny i trzeba w tym zachować jakiś balans.

0
Ziemiak napisał(a):

No to rozważmy dwie opcje. Jedno robie zmianę + dopisuje do niej testy. Wiem ze chrome driver ma swoje bolaczki wiec ustawiam mu rerun zeby losowy timeout (nie wynikajacym z moich kodow) nie wywalal mi testow. Zrobie to w tydzien i jest.
vs
Robie zmiane i dopisuje do niej testy. Testy sa losowe niestabilne. Siadam wiec do chrome drivera i zaczynam poprawiać bugi. Mineło pół roku... poprawiam te bugi dalej o ile mnie wcześniej nie zwolnią bo nie chce skończyć prostej zmiany na kilka dni bo ciagle te testy w 100% nie są stabilne plus biznes dostaje białej gorączki bo zmiany do których np. obliguje ich ustawa nie ma co powoduje ogromne straty. No przecież to jest niedorzeczne. Swiat nie jest idealny i trzeba w tym zachować jakiś balans.

Obie te dwie opcje są słabe.

Weźmy pierwszą - owszem, skończysz szybko. Jeszcze szybciej byś skończył gdybyś w ogóle nie pisał testów, prawda? Tylko co brak testów albo słabe testy (czyli takie które są wolne i failują randomowo) oznacza? Oznacza to że każda kolejna zmiana będzie mniej bezpieczna, będziesz zwiększał tech debt. Jeśli ten feature ma testy które failują randomowo, to prawdopodobnie wszystkie pozostałe feature'y też. Co jest więc tego wynikiem? Wynikiem jest to że masz kod z testami które są całkowicie niewiarygodne, a w rezultacie nie pomocne. Dlatego to podejście jest złe. I myślisz żę to nie wpłynie w żaden sposób na koniecznie innych feature'ów? Za rok, pół albo szybciej ten debt który zrobisz oszczędzając ten czas się na Tobie odbije i to znacznie - szybciej niż myślisz.

Druga opcja - oczywiście że fixowanie buga w zależności pół roku nie ma sensu - nic takiego nie sugerowałem. Ja sugerowałem, że jesli można poprawić łatwo buga w bibliotece, np w kilka godzin, max dzień., to można to zrobić i pisać dobre testy. Jeśli nie da się tego zrobić szybko, to znaczy że rozwiązanie po prostu nie nadaje się do pisania testów na skalę komercyjną, i należy znaleźć inny sposób na napisanie deterministycznych testów i tyle.

Korzystanie z zepsutego narzędzia to proszenie się o kłopoty.

Poza tym, ten rerun nie ma sensu. Rozważmy przykład:

  • Case jeden, nie ma buga w kodzie:
    • Odpalasz testy, failują randomowo przez buga w chrome driver, rerun, przechodzą (tak jak mają przejść)
  • Case drugi, jest bug w kodzie:
    • Odpalasz testy, failują (tak jak mają failować), rerun, przechodzą randomowo przez buga w chrome driverze

I skąd wiesz czy masz buga w kodzie czy nie? Testy mają Ci powiedzieć czy Twój program nadal działa tak jak działał. Jak możesz ufać testom, jak nie ufasz toolowi który je odpala?

0
Nofenak napisał(a):

Czego używacie w testach integracyjnych, MockMVC czy WebTestClienta? I czy w ogóle można używać w testach integracyjnych MockMVC, bo słyszałem już różne opinie.

To zależy. Jak chce mockować jakieś odpowiedzi z zewnętrznych serwisów to mockmvc, a tak to normalnie jakims klientem http np. restTemplate

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