Wątek przeniesiony 2017-09-25 22:08 z C# i .NET przez somekind.

Granica między testami integracyjnymi a jednostkowymi

0

Czy mogę zaliczyć test używający SQLite w pamięci jako Stub do testów jednostkowych?.

Dla przykładu test paginacji strony:
Za jednostkę uznaję "paginację" pobranie odpowiedniej liczby wierszów na stronę ale w rzeczywistości testuje zapytanie do sql generowane przez Nhibernatora.

3

Nie, bo test wykracza poza jednostkę Twojego kodu i wymaga zintegrowania z SQLite.

0

Ale przecież ja nie testuje integracji z bazą danych która jest tworem sztucznym żyjącym w zakresie testów, nie testuje też rzeczywistą bazę danych wykorzystywaną w kodzie produkcyjnym.

Dane są przechowywane w pamięci i żyją w zakresie testu, więc test działa wyłącznie w pamięci.
Baza danych oraz przechowywane w niej dane są tworzone przez test więc test ma pełną kontrole nad bazą. Celem tego jest izolacja jednostki.

Poza tym test wykonuje się szybko oraz jego składnia jest prosta.
Ja nie testuję integracji z sqlite gdzie jest on wyłącznie provaiderem usługi bazodanowej. (Jak bym tego wcześniej nie zrobił to bym nie mógł wykonać tego testu a zakresem tego testu było sprawdzenie czy connectionString.InMemory zwróci true).

W moim odczuciu to tak jak byś powiedział mi ,że jak używam automock albo fakeItEasy to wykonuje test integracyjny.

0

Hmmm... No więc ?
https://stackoverflow.com/questions/38020225/testing-with-an-in-memory-database-unit-test-or-integration-test

If your method is simply using a db Connectionobject to retrieve rows from in - memory db instead of real db and no other public services being called or being mocked ( if called ) then you are doing a unit test ( which does seem the case to me even though you have not shared code of CustomerRepository.GetAllCustomers ) .

Jeśli masz The Art Of Unit Testing. To otwórz na stronie 31

4

Czyli Twoim zdaniem test jednostkowy od integracyjnego różni się prędkością wykonywania i miejscem składowania danych, a nie tym, co jest testowane? :D

MrBean Bean napisał(a):

Hmmm... No więc ?
https://stackoverflow.com/questions/38020225/testing-with-an-in-memory-database-unit-test-or-integration-test

If your method is simply using a db Connectionobject to retrieve rows from in - memory db instead of real db and no other public services being called or being mocked ( if called ) then you are doing a unit test ( which does seem the case to me even though you have not shared code of CustomerRepository.GetAllCustomers ) .

To tylko potwierdza moje słowa. Jeśli Hindus coś pisze na StackOverflow, to znaczy, że prawda jest zupełnie odwrotna.

0

Z tego co wynika to dla ciebie jednostka pracy oraz dostęp do danych to samo. :D

0
somekind napisał(a):

Czyli Twoim zdaniem test jednostkowy od integracyjnego różni się prędkością wykonywania i miejscem składowania danych, a nie tym, co jest testowane? :D

MrBean Bean napisał(a):

Hmmm... No więc ?
https://stackoverflow.com/questions/38020225/testing-with-an-in-memory-database-unit-test-or-integration-test

If your method is simply using a db Connectionobject to retrieve rows from in - memory db instead of real db and no other public services being called or being mocked ( if called ) then you are doing a unit test ( which does seem the case to me even though you have not shared code of CustomerRepository.GetAllCustomers ) .

To tylko potwierdza moje słowa. Jeśli Hindus coś pisze na StackOverflow, to znaczy, że prawda jest zupełnie odwrotna.

No ale tak pisze też w książce

0

Weź nie atakuj szanowanego ziomka na forum. To nie jest Twój nauczyciel - autorytet. Już Tobie powiedział co o tym myśli.

0

Ale ja też go szanuje, jak najbardziej. Przepraszam sam poczułem się jak bym był atakowany ;)

1

Czyli test wykorzystujący SQLite z zapisem do pliku już nie byłby jednostkowy? ;-)

A test, który 50/50 zapisywałby do pliku bądź bazy byłby testem Schrödingera?

A jeśli miałbyś test wykorzystujący SQLite z zapisem do pliku, lecz SQLite buforowałoby wszystkie dane w pamięci, tak naprawdę nigdy ich nie zapisując na dysk?

(...)

Wykorzystujesz odrębny komponent, który nie jest częścią Twojego kodu, przez co właśnie tracisz jednostkowość, a zaczynasz testować funkcjonalnie/integracyjnie/whatever. Nie ma znaczenia co ten komponent robi i w jaki sposób.

0

A ja myślałem że jednostka to funkcjonalność w systemie a nie kawałek kodu ani komponent. A test integracyjny testuje zestawie wielu jednostek. Możesz mi powiedzieć gdzie to wyczytałeś?. Nie żebym się czepiał czy atakował ale chciał bym dowiedzieć się więcej na ten temat :)

0

autorze, jednostka to jest funkcja.
Czasami jezeli masz w klasie funkcje prywatne (ktore naleza do klasy i nie mozna ich wyodrebnic) wtedy funkcja korzystajaca z innych fukncji z obrebie tej samej klasy!

Ale jezeli ktorekolwiek odwoluje sie do innej klasy to taka zaleznosc trzeba zmockowac (no i pamietajmy nie testujemy frameworkow)

jezeli laczysz sie z baza danych jest to test integracyjny, jezeli chcesz jednostkowy to mockujesz baze danych

0

Ty nie odróżniacie mock od stub czy fakeObject. Mówisz mi o jakiś definicjach z wikipedi typu jednostka to funkcja w klasie. Nie chcę mi się już o tym gadać...

fasadin napisał(a):

autorze, jednostka to jest funkcja.
Czasami jezeli masz w klasie funkcje prywatne (ktore naleza do klasy i nie mozna ich wyodrebnic) wtedy funkcja korzystajaca z innych fukncji z obrebie tej samej klasy!

Ale jezeli ktorekolwiek odwoluje sie do innej klasy to taka zaleznosc trzeba zmockowac (no i pamietajmy nie testujemy frameworkow)

jezeli laczysz sie z baza danych jest to test integracyjny, jezeli chcesz jednostkowy to mockujesz baze danych

1
MrBean Bean napisał(a):

Z tego co wynika to dla ciebie jednostka pracy oraz dostęp do danych to samo. :D

Absolutnie nie. A dostępu do danych z bazy nie ma nawet sensu testować jednostkowo, trzeba integracyjnie na prawidłowym silniku.

MrBean Bean napisał(a):

A test integracyjny testuje zestawie wielu jednostek.

Test integracyjny testuje komunikację kodu aplikacji z zewnętrznymi modułami. Mogą to być moduły tej samej bazy, a mogą być pliki, strumienie sieciowe, bazy danych (tak jak w Twoim przypadku).

fasadin napisał(a):

Ale jezeli ktorekolwiek odwoluje sie do innej klasy to taka zaleznosc trzeba zmockowac (no i pamietajmy nie testujemy frameworkow)

Nie trzeba mockować, często nie ma sensu mockować ani nawet nie da się mockować. Jednostka nie musi być jedną klasą, może być wieloma.

jezeli laczysz sie z baza danych jest to test integracyjny, jezeli chcesz jednostkowy to mockujesz baze danych

Tylko taki test jest zupełnie bezużyteczny, bo niczego nie testuje, nie dowodzi, ani nie wykrywa żadnych błędów.

0

Test integracyjny testuje komunikację kodu aplikacji z zewnętrznymi modułami. Mogą to być moduły tej samej bazy, a mogą być pliki, strumienie sieciowe, bazy danych (tak jak w Twoim przypadku).

"Rzeczywistej BazyDanych, rzeczywistych zależności"! wyciąłeś sobie to z ogólnej definicji. Dla własnej wygody, żeby się kłócić :)

Test integracyjny testuje komunikację kodu aplikacji z zewnętrznymi modułami. Mogą to być moduły tej samej bazy

To stwierdzenie jest jak najbardziej poprawne. ale dalej już obracasz kota ogonem.

Baza danych która została stworzona na potrzeby testu i żyje tylko w zakresie testu jest tworem sztucznym.
I nie ma nic wspólnego z bazą systemową.

Tak na logikę kowboja jak to Vernon pisze :) Jeśli to test integracyjny to jak system blogowy ma działać z zintegrowaną bazą która żyje w pamięci tymczasowej.?

6

Niczego z definicji nie wycinałem, bo nie operuję żadnymi definicjami, jestem pragmatykiem. Testy jednostkowe testują kod, nie potrzebują niczego więcej żeby się uruchomić. A testy integracyjne potrzebują czegoś więcej, np. bazy. Wszystko jedno czy to baza taka jak produkcyjna, czy jakaś in-memory, bo zarówno jedna jak i druga jest zewnętrznym komponentem z punktu widzenia kodu aplikacji.
I o ile czasami takie testy z bazą in-memory mają sens (chociaż to niekoniecznie dobrze świadczy o architekturze), to w przypadku, gdy chcemy przetestować generowany SQL/wyniki zwracane z bazy, takie testy są zupełnie bezwartościowe - bo rzeczywista baza może działać inaczej i zwracać inne dane niż ta w pamięci.

A dla własnej wygody, żeby się kłócić, to chyba Ty tu przyszedłeś, bo najpierw niby zadałeś pytanie, a potem masz żal, że pojawiły się odpowiedzi nie pasujące do Twojej teorii.

1

Czy mogę zaliczyć test używający SQLite w pamięci jako Stub do testów jednostkowych?.

Wymyśliłeś sztuczny problem, w którym masz dwa zbiory: zbiór testów jednostkowych oraz zbiór testów integracyjnych.

Masz na wejściu test używający SQLite i próbujesz znaleźć zbiór do którego będzie on pasował.

Nie posiadasz jednak spójnej definicji, zasady logicznej, więc założyłeś cały wątek w którym próbujesz razem z innymi odnaleźć warunek, który pozwoli przypisać test do zbioru testów jednostkowych.

Czasem takie rozważania się przydają, i można dojść do ciekawych wniosków, ale jak dla mnie ten wątek póki co jest jakiś mdły i ma nikłą wartość praktyczną.

Czy mogę zaliczyć test używający SQLite w pamięci jako Stub do testów jednostkowych?.

Z perspektywy praktycznej wypadałoby zmienić pytanie raczej na:

Czy powinienem testować ficzer za pomocą SQLite w pamięci czy może innymi metodami?

(gdzie za powinienem/nie powinienem powinny stać jakieś konkretne korzyści/wady).

0

I o ile czasami takie testy z bazą in-memory mają sens (chociaż to niekoniecznie dobrze świadczy o architekturze), to w przypadku, gdy chcemy przetestować generowany SQL/wyniki zwracane z bazy, takie testy są zupełnie bezwartościowe - bo rzeczywista baza może działać inaczej i zwracać inne dane niż ta w pamięci.

Podaj mi przykład.

1
MrBean Bean napisał(a):

I o ile czasami takie testy z bazą in-memory mają sens (chociaż to niekoniecznie dobrze świadczy o architekturze), to w przypadku, gdy chcemy przetestować generowany SQL/wyniki zwracane z bazy, takie testy są zupełnie bezwartościowe - bo rzeczywista baza może działać inaczej i zwracać inne dane niż ta w pamięci.

Podaj mi przykład.

Podam Ci nawet bardziej dosadny, smutny przykład.
Był test integracyjny, ale taki prawdziwy, nie używający nawet in-memory i przechodził na komputerze lokalnym, czy nawet na serwerze CI. Jednak podczas testów manualnych, dla takich samych danych wejściowych, kod się wysypał. Co było powodem? Test był skonfigurowany z innym dialektem SQL niż sama aplikacja.

0

W moim przypadku jak jest to możliwe jeśli to ORM generuje zapytanie a konfigurację ORM wstrzykuje podczas testu.?

Moja aplikacja rozmawia z ORM a nie bezpośrednio z silnikiem zapytań wiec to ORM powinien zapewnić integrację pomiędzy dialektami.

mstl napisał(a):
MrBean Bean napisał(a):

I o ile czasami takie testy z bazą in-memory mają sens (chociaż to niekoniecznie dobrze świadczy o architekturze), to w przypadku, gdy chcemy przetestować generowany SQL/wyniki zwracane z bazy, takie testy są zupełnie bezwartościowe - bo rzeczywista baza może działać inaczej i zwracać inne dane niż ta w pamięci.

Podaj mi przykład.

Podam Ci nawet bardziej dosadny, smutny przykład.
Był test integracyjny, ale taki prawdziwy, nie używający nawet in-memory przechodził na komputerze lokalnym. Jednak podczas testów manualnych, dla takich samych danych wejściowych, kod się wysypał. Co było powodem? Test był skonfigurowany z innym dialektem SQL niż sama aplikacja.

1

Tutaj również był ORM, który miał skonfigurowany błędny dialekt w testach. Przykład miał na celu pokazanie, że pisanie dobrych testów integracyjnych, nawet w zbliżonych środowiskach nie jest banalne. Jeżeli faktycznie potrzebujemy wyniki zwracane z bazy to moim zdaniem, pisanie testów z wykorzystaniem in-memory może służyć tylko po to, by uspokoić sumienie, że napisało się jakiekolwiek testy ;)

0

Nie rozumiem. Ty chcesz mi powiedzieć że źle skonfigurowałeś ORM. Czy że 2 ORM'y które używają innego silnika czy dialektu dadzą dwa inne wyniku tego samego zapytania które kieruje do ORM dialektem abstrakcyjnym?

0

pisanie testów z wykorzystaniem in-memory może służyć tylko po to, by uspokoić sumienie, że napisało się jakiekolwiek testy ;)

To chyba zależy od gustu, jak to czy to jest test integracyjny czy jednostkowy ;)

2

To może wracając do tematu: "Czy mogę zaliczyć test używający SQLite w pamięci jako Stub do testów jednostkowych?."

Może to też pragmatyczne podejście, bo nie wiem jak to się ma z teorią, ale testy jednostkowe operują na logice systemu.
Logika systemu nie powinna być w żaden sposób powiązana z miejscem składowania danych.

Jeśli masz logikę z bazie, procedury składowane, to i tak masz wtedy testy integracyjne pomiędzy dwoma modułami.
I tu bym chciał zakończyć dyskusją.

0

Uważam że ORM jest abstrakcją pośredniczącą pomiędzy miejscem składowania bazy danych i jest jak najbardziej częścią systemu. Nie potrzebuje żadnej nakładki w postaci repozytorium z którego i tak wszyscy robią DAO aby go odseparować bo jaki to ma sens?. Czyli Twoim zdaniem każdy test na ORM to test integracyjny?

Czyli żeby to był test jednostkowy musiał bym stworzyć makietę silniku Bazodanowego.
Aby zasymulować to samo co daje mi sztuczna baza??.

1

Co testuje ten twój test ?

5

Jeżeli testujesz zapis czy odczyt z bazy, to robienie tego jednostkowo na jakichś mockach nie ma sensu. Nie ma też sensu robienia tego na innej bazie niż docelowa, bo wyniki mogą być różne. Na przykład w sytuacji, gdy docelowa baza ma inną dokładność przechowywania liczb albo dat, więc to co odczytasz nie jest tym, co zapisujesz i czego się spodziewasz.

Jeśli chcesz przetestować jakąś logikę, której częścią jest trzymanie danych w bazie i użyjesz w tym celu SQLite, to to nadal będzie to test integracyjny. A jeśli musisz to robić i nie jesteś w stanie przetestować logiki bez źródła danych, to źle to świadczy o architekturze.

0

Ja uznałem że w tym kontekście sztuczny obiekt jako kod oraz sztuczny obiekt jako baza danych to to samo. Skoro wynik testu będzie taki sam. Przecież silnik bazodanowy nie potrzebuje testów. ORM w kontekście integracji z silnikiem bazo danowym też nie potrzebuje testów, ale to czy ja go dobrze używam ORM już wymaga weryfikacji.

0
MrBean Bean napisał(a):

Przecież silnik bazodanowy nie potrzebuje testów. ORM w kontekście integracji z silnikiem bazo danowym też nie potrzebuje testów

Uważasz, że silniki baz danych i ORMy nie mają błędów?

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