Testy integracyje

0

Witam,
mam pytanie jak w waszych firmach wygladaja testy integracyjne. Np stawiacie bazke, zapelniacie ja danymi, uruchamiacie serwer wrzucacie ear i tak pyszczacie testy.

Jakich narzędzii używacie

0

Pierwsze co mi przychodzi do glowy jak slysze slowo "testy" to TestNG. Do testowania aplikacji webowych Selenium. Testowanie backendu - Mockito, no i odpowiedni napisany kod aby bylo mozna podstawiac mocki i testowac wywolania metod na nich.
Aktualnie tworzymy aplikacje EE 6 ktorej sercem jest CDI (jst 299) do dependency injection. Uzywamy JPA2, EJB 3.1. Poki co mamy integracje TestNG z DbUnit i JPA2, do tego testy moga miec wstrzykiwane zaleznosci dzieki kolejnemu punktowi integracji TestNG z Weld SE (Weld to referencyjna implementacja CDI, SE to rozszerzenie ktore pozwala uzywac w javie SE). Dzieki temu mozemy w latwy sposob wstrzykiwac sobie rozne obiekty do testow, ktore maja rowniez rozne obiekty wstrzykiwane, i mozemy sterowac czy te obiekty to prawdziwe uslugi czy mocki, no i testujemy. Testy EJB za pomoca Glassfish 3 embeddable - transakcje JTA, session beany, wstrzykiwanie zasobow itp w srodowisku Java SE (TestNG).
Tak to wydlada w tej chwili (projekt nowka sztuka, w poczatkowej w sumie jeszcze fazie, i zaczynamy kazdy modul / warstwe od specyfikacji i zbudowania srodowiska testowego.
W sumie i tak wszystkiego sie tak chyba nie da przetestowac - w sensie automatycznie. W poprzednich firmach mielismy testerow - dostawali release do testow co jakis czas, np co tydzien, i testowali z palca za pomoca test casow ktore ktostam / oni sami pisali. Bardzo mi sie podobala wspolpraca z testerami.

0

Super dzieki za odpowiedz. Chyba środowisko które próbujecie sobie tworzycie pewnie pochłania wiele pracy.
Mam pytanie o DBunit ponieważ , kogo nie spytam lub co nie czytam wszyscy prawie używają dbunita ..szczerze powiem mi sie nie spodobał. Jeżeli mam inicjalizować dane w bazie na starcie, to wole np stworzyc sobie pare obiektów encji i je utrwalic na starcie niz bawić sie w te xml.

Pozdrawiam

0

Wlasnie cale to srodowisko jest dosc proste. Np integracja TestNG z CDI aby dzialalo wstrzykiwanie do testow to raptem 1 metoda @BeforeClass. Poza tym cale to 'srodowisko' jest napisane w taki sposob ze mozna uzyc w innych projektach i myslimy zeby to gdzies opublikowac. Raz ze sprawia mi to frajde, a 2 ze sie naprawde przydaje, juz widzimy ze dzieki temu testy piszemy super szybko.
Co do DbUnit - po pierwsze XML to tylko 1 z wielu IDataSetow ktore moga byc uzywane do wstawienia do bazy. Po drugie, jak masz 1 test to spoko, wstaw w @BeforeClass te pare encji. Jednak my mamy w tej chwili setki testow, z ktorych kazdy testuje nieco inny obszar (czasami sie nieco nakladaja, czasami nie), wiec w kazdej klasie testowej / dla kazdej metody musialbyc robic takie wstawianei encji. Wydaje mi sie to kupe pracy ;d A tak mamy klase bazowa ktora a ma pare specjalnych metod, i mozemy w latwy sposob konfigurowac czy setup bazy jest dla metody, czy dla calej klasy, czy chemy dane usuwac po kazdej metodzie czy po calej klasie, rozne kombinacje. Do tego kazda metoda moze zwracac swojego providera IDataSetow, ktory moze byc specjalny tylko dla niej, wspoldzielony dla calej grupy itp, bez szczegolnie wysokiej hierarchii klas testowych jesli chcemy uzywac te same dane.
No nie wiem, wydaje mi sie to kwestia gustu, ale my akurat uzywamy DbUnit, jednak tylko do wstawiania i wywalania z bazy - nie uzywamy ich asercji zeby sprawdzic czy to co ma byc w bazie faktycznie tam jest - tego nie testujemy, uzywamy JPA2 wiec zakladamy ze to byloby testowanie prowidera, a tego nie chcemy / powinnismy robic.
Mamy tez takie scenariusze - w tabelce tysiac wierszy, i sposrod nich jakies tak wyszukiwanie itp. Takie load testy. Dana tabelka zawiera glownie dane tekstowe, tworzony jest indeks do wyszukiwania pelnotekstowego (z pewnych wzgledow korzystami z silnikow dostepnych w bazie, moze to ulegnie zmianie jak nie zda egzaminu?) i uzywamy generatora tekstu lorem ipsum dla javy. Mamy IDataSet ktory generuje nam jakies bzdurne slowa i wstawia do bazy. Wez napisz i zapisz tyle encji...
No to tak pokrotce nasze podejscie. W sumie jak juz tyle napisalem to sam chetnie wyslucham (konstruktywnej) krytyki, co tylko pomoze nam miec lepsze testy.

0

Ciekawi mnie jeszcze jedna sprawa, a jak z wydajnością skoro teoretycznie dajecie możliwość inicjacji bazy danych przed każdym testem (różnymi danymi) czy takie CLEAN_INSERT'y przed wiekszoscia testow nie wpływają znacząco na na czas ich wykonywania.

0

Jesli nie chcesz aby dany test inicjalizowal baze, to jest taka opcja. Mozesz dowolnie konfigurowac kiedy i jakie operacje sa robione, i z jakimi IDataSetami - oczywiscie sa jakies defaulty. Mozna tez ustawic aby cos bylo robione przed klasa czy metoda, czy przed obiema, oraz czy ma cos byc robione po. Dowolne kombinacje, i kazda operacja jest tez dowolna - wcale przed testem nie musi byc CLEAN_INSERT, moze byc np REFRESH DELETA_ALL, a nawet cos co sam zakodujesz - to dzieki DbUnit.
Oczywiscie jesli nie chesz miec testow z baza, to po prosty nie dziedziczysz po klasach ktore na taka integracje pozwolaja i tyle. Jesli jednak testujesz z baza, i test oczekuje jakichs danych, to i tak nie masz wyboru - musisz cos wstawic - i pytanie o wydajnosc schodzi na 2. plan. Zapisywanie encji za pomoca EntityManager.persist() i tak byloby wolniejsze (tak mi sie wydaje przynajmniej) i nie tak elastyczne.
Jak to powiedzial nasz szef - poki nie mamy problemu ze testy sie nie zdaza wykonac przez noc, jest spoko :d

0

A czy sama inicjalizacja danych (dbunitem) oraz testy na tych danych przeprowadzacie w jednej transakcji która rollback'ujecie czy moze inaczej?

0

DbUnit ma swoja transakcja (wlasciwie, jesli sie przyjrzysz, np taki CLEAN_INSERT domyslnie jest w trybie auto commit, ale masz wrapper DatabaseOperation.TRANSACTION() ktory my uzywamy jako default), a testy maja swoje. Tak po prostu dziala DbUnit, i uwazam ze jest to dobre zachowanie. Gdy uzywamy JPA to zapisywanie do bazy uzywa EntityTransaction, ktory jest abstrakcja nad transakcje JDBC. Czytanie z bazy najczesciej nie uzywamy transakcji, roznica jest taka ze wtedy zwrocone encje sa od razu w stanie 'detached'.
Dlaczego pytasz, jakie to ma znaczenie?

0

Myślałem ze każdy testy wykonujecie w jednej transakcji którą na końcu rollbackujecie takie zachowanie jest dobre bo nie trzeba sprzątać po każdym tescie bo po prostu na bazie danych nie ma śladu.

0

Nie zastanawialem sie nad tym, ale nie jestem pewien czy to by dzialalo tak jak chcemy. (Pomysle nad tym jak znajde chwile.)
Co do tego czy nie ma sladu - mylisz sie. Np wezmy tabelke ktorej klucz podstawowy jest auto wstawiany z sekwencji. Zaczynamy transakcje, wstawiamy cos, pobierana jest wartosc z sekwencji, lastVal sekwencji zmienia sie o +1. Robimy rollback, ale pobranie numeru sekwencji nie jest cofane o 1. Slad jest. Na dowod cytaty
(IBM Infomix: http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?topic=/com.ibm.sqls.doc/sqls1016.htm):
"Except for the case of multiple occurrences within the same statement, every sequence.NEXTVAL expression increments the sequence, regardless of whether you subsequently commit or roll back the current transaction."
(Oracle: http://rnyb2.blogspot.com/2006/02/potential-pitfall-with-oracle-sequence.html):
"The squence number may "jump", that is 1,2,3,5,6,8,... with number 4 and 7 missing. One reason is if you do a transaction with NEXTVAL and then rollback, the sequence doesn't roll back to where you started."
(Wzialem pierwsze lepsze linki ktore zwrocilo google.

Wiem, czepiam sie, ale jak widzisz pomyliles sie. Nie jestem specem od baz, i jestem prawie na bank pewien ze sa i inne takie 'slady', i wolalbym uniknac szukania takiego buga w testach :D

0

Jeśli chodzi o sekwencje to masz racje nie pomyślałem o tym, lecz ten argument mnie nie przekonje bo przesuwanie sekwencji zdarza sie i w produkcj.(jak np podczas inserta leci constraintviolationexception).

Przedstawiłem Ci taki pomysł ponieważ sobie nie wyobrażam jak można wyczyścić bazę po tescie tzn przywrócić jej stan z przed testu.
U nas w aplikacji wykonanie metody insert pewnego serwisu wywołuje wpisy w 10 tabelach w bazie danych. Jak mam posprzątać po czymś takim

0

Wykorzystujesz DbUnit: mozesz np w operacji przed testem (jesli test to cala klasa, to w @BeforeClass, a jesli metoda, to w @BeforeMethod) zrobic taki snapshot pewnych tabelek za pomoca http://www.dbunit.org/apidocs/org/dbunit/database/IDatabaseConnection.html#createDataSet(java.lang.String[]), zapisac go gdzies np w ITestContext czy nawet jako pole klasy testowej, a po tescie zrobic DatabaseOperation.CLEAN_INSERT z tym wlasnie IDataSetem - DbUnit ograniczy delety tylko do tabelek ktore sie znajduja w data secie, wiec tylko tych Twoich 10, a pozniej wstawi dane. I juz masz stan sprzed testu w danych tabelkach. W ten sposob nawet wartosci kluczy podstawowych moga sie zgadzac.
To tylko przyklad, mozliwe ze za pomoca REFRESH czy UPDATE daloby sie zrobic to efektywniej. No i zakladam ze uzywasz TestNG. Jesli sie martwisz performancem testu, no to coz, jak juz wspomnialem - jesli test ma takie wymaganie, to i tak nie masz wyboru. Poza tym, jesli sie tym naprawde martwisz, to dla danego testu mozesz przeciez zrobic takiego rollbacka sam jak Ci sie podoba, nikt Cie nie zmusza zeby wykorzystywac DbUnit do wszystkich testow. Natomiast to ze sie przydaje (przynajmniej nam) to nie ma zadnych watpliwosci.
Chyba z glownego watku zeszlismy juz dawno. Temat nie byl o DbUnit, tylko o tym jak testujemy.

0

Powyzszy link powinien byc:
http://www.dbunit.org/apidocs/org/dbunit/database/IDatabaseConnection.html#createDataSet(java.lang.String[])
IDatabaseConection masz dostepne np w IDatabaseTester dla danego testu.

0

Fak.
http://www.dbunit.org/apidocs/org/dbunit/database/IDatabaseConnection.html#createDataSet(java.lang.String[])
Teraz powinno byc dobrze. Jelsi mozna to prosze moderatora o sklejenie tych postow. I przepraszam za swoje lamerstwo.

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