Testy laravel, a system DBMS SQL

Testy laravel, a system DBMS SQL
T0
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 210
0

Mam pytanie dopiero zaczynam robić testy w laravelu, a w laravelu programuje już od 8 lat, jakoś nifgdy nie przymierzałem się do robierania testów, ale musze w SPACJA końcu zacząć je robić.
Słyaszałewm, że laravel domyslnie dla testów używa bazy danych SQLLite zupełnie nie wiem dlaczego czy można wymusić na laravelu używanie np. mysql/mariadb ?
Jak pogodzić testowanie na bazie danych SQLLite jak w laravelu używa się mysql przecież nie każdą bazę danych da się skonwertować z mysql na SQLLite

KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5656
3

nigdy nie napisałem linii kodu w php ale mogę koncepcyjnie powiedzieć czemu sqlite warto używać do testów bo w javie mamy h2 jako odpowiedni. Otóż nie trzeba startować serwera bazy danych przed testami a wyczyszczenie takiej bazy to chwila. h2 np jest tylko bazą pamięciową, dla sqlite to uzycie innego pliku, chociaż coś mi się w głowie kołacze że chyba też ma tryb in memory bez pliku? dawno się nim bawiłem

jurek1980
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3623
2

Wynika to z konfiguracji phpunit.
Możesz oczywiście stworzyć sobie jakiś .env_test lub phpunit.xml i uruchamiać testy z własną konfiguracją.
Jeśli nie używasz niczego specyficznego dla bazy to korzystaj z tego sqllite. Jeśli masz jakieś specjalne zapytania, zależne od dialektu SQL to niestety musisz zrezygnować z bazy in memory.

Idzi
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Nowa Sól
  • Postów: 12
2

W pliku phpunit.xml zamiast tego:

Kopiuj
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_URL" value=""/>

dodaj to:

Kopiuj
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_HOST" value="127.0.0.1"/>
<env name="DB_PORT" value="3306"/>
<env name="DB_DATABASE" value="test_base"/>
<env name="DB_USERNAME" value="root"/>
<env name="DB_PASSWORD" value="1234"/>
SL
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1132
3
tomixtomi0001 napisał(a):

Słyaszałewm, że laravel domyslnie dla testów używa bazy danych SQLLite zupełnie nie wiem dlaczego czy można wymusić na laravelu używanie np. mysql/mariadb ?
Jak pogodzić testowanie na bazie danych SQLLite jak w laravelu używa się mysql przecież nie każdą bazę danych da się skonwertować z mysql na SQLLite

Można tak testować, ale jest szansa, że trafisz na inne zachowanie tego co masz na produkcji (MySQL) vs baza w testach (SQLite) albo w najgorszym wypadku query nie będą w ogóle działać, bo każda baza ma jakieś swoje dziwactwa. Oczywiście można tak robić, bo wszystko jest kompromisem (SQLite będzie lżejszy do postawienia i szybszy w testach). Ja sam wole testować na bazie takiej samej jak na produkcji, bo testy mają mi dawać jakąś pewność, że wszystko działa jak należy a złe użycie bazy przez aplikację lub błednie skonfigurowana baza to częste źródło problemów

Co do testowanie na rzeczywistej bazie danych to temat rzeka, bo każda opcja ssie w inny sposób. Generalnie są dwa główne podejścia:

  • stawiasz bazę samemu np. za pomocą jakiegoś skryptu uruchamiającego bazę w dockerze. W testach łączysz się do tej bazy.
  • używasz jakiejś biblioteki, która robi to samo tylko w teście. Popularne są testcontainers dostępne w wielu językach. PHP ma coś takiego https://github.com/testcontainers/testcontainers-php

W obu wypadkach docker jest zalecany, bo ułatwia uruchamianie zarówno lokalnie jak i w CI

Oczywiście jest dużo problemów z tym związanych:

  • działa ok dla testów sekwencyjnych, ale takie są wolne. Trzeba ogarnąć jakąś dobrą strategię np. osobny proces bazy dla każdego testu, jakieś uruchamianie w transakcji czy mądre użycie jednej bazy (np. poprzez klonowanie bazy dla każdego testu, bo klonowanie jest generalnie szybsze niż odpalanie procesu za każdym razem)
  • działa wolno. Niektóre bazy potrafią wstawać kilka sekund i ciężko to przeskoczyć. Tutaj trzeba dużo wiedzy, żeby wszystko dobrze zoptymalizować
  • rzeczywisty proces to zawsze jakieś problemy

Generalnie polecam ci pobawić się jakimś agentem AI. Niech wygeneruje ci testy dla każdego wariantu po czym możesz sobie porównać jak działa każdy wariant i który ci najbardziej pasuje. Zawsze nauczysz się czegoś nowego

Kupony Janusza
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 4
0

Cześć! Też przez to przechodziłem. SQLite w pamięci (:memory:) jest super szybki, ale ma jedną ogromną wadę: nie wspiera wszystkich funkcji MySQL (np. specyficzne typy kolumn, procedury czy choćby niektóre operacje na kluczach obcych). Jeśli Twój projekt rośnie, SQLite w testach zacznie Cię ograniczać.

Skoro hostujesz własne rzeczy na Ubuntu, to masz u siebie idealne warunki, żeby testować na identycznym silniku, co na produkcji.

Moje podejście (Infrastrukturalne):
Osobna baza do testów:
Zamiast mieszać w pliku .env, stwórz w MySQL/MariaDB dedykowaną bazę, np. laravel_test. W pliku phpunit.xml odkomentuj i ustaw parametry tak, jak pokazał @Idzi. Dzięki temu testy zawsze będą walić do tej "czystej" bazy.

DatabaseTransactions:
W testach Laravela używaj traita RefreshDatabase lub DatabaseTransactions. Ten drugi jest genialny – Laravel otwiera transakcję przed każdym testem i robi rollback po jego zakończeniu. Baza zostaje w nienaruszonym stanie, a Ty nie musisz jej czyścić ręcznie.

Optymalizacja na własnym serwerze (Ubuntu):
Jeśli Twoje testy na MySQL zaczną mulić w porównaniu do SQLite, możesz na swoim serwerze Ubuntu wrzucić bazę testową na RAMDisk (tmpfs).

Wystarczy podmontować folder danych MySQL pod RAM:
mount -t tmpfs -o size=512M tmpfs /var/lib/mysql_test_ram

To daje prędkość zbliżoną do SQLite :memory:, zachowując przy tym 100% kompatybilności z MySQL.

Werdykt:
Jeśli planujesz poważnie rozwijać te projekty przez kolejne lata, odpuść SQLite teraz. Skonfiguruj sobie środowisko testowe na MySQL, żeby uniknąć sytuacji, gdzie "u mnie w testach (SQLite) działa, a na serwerze (MySQL) wywala błąd składni".

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.