Testování databáze (Kdyby/Doctrine) – Connection Mock

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
greeny
Člen | 405
+
0
-

Ahoj,

začal jsem testovat modelovou vrstvu (Kdyby/Doctrine). Současný stav testů:

  • na začátku se přes setup soubor provedou migrace testovací databáze na aktuální verzi (po smazání předchozí verze)
  • před každým testem se v setUp naimportujou testovací data (CSV)
  • každý databázový test si na začátku vyžádá lock, aby nikdy dva testy nepracovaly s databází zaráz
  • testuji metody (např. jestli getById($id) skutečně vrátí entitu s daným IDčkem).

Není to ideální řešení a testy běží pomalu, protože většina testů čeká na lock. Proto jsem se snažil vymyslet postup, jakým to vylepšit.

  1. použít např. SQLite místo MySQL, vyrobit X různých SQLite databází a tím umožnit více testům běžet zaráz. Problémem jsou migrace, které jsou generované pro MySQL. (lze nějak jednoduše konvertovat MySQL zápis do SQLite?)
  2. namockovat nějak Doctrine Connection / EntityManager / … tak aby pracovali např. s testovacíma datama v paměti – opět tím umožnit více testům běžet současně (a zároveň zrychlit testy).

Ani s jedním způsobem nemám žádné zkušenosti (vlastně i samotné testování modelových tříd pracujících s DB je pro mě nové) a tak se ptám, jestli někdo nemá tip to, jak to zrychlit a zefektivnit.

P.S.: také jsem někde slyšel, že tím, že to testuju i s DB už to nejsou Unit testy, je to pravda?

jiri.pudil
Nette Blogger | 1029
+
+2
-

Ad 1. Přijde mi smysluplné testovat oproti stejné databázi, na jaké ti běží produkční prostředí.

Ad 2. a P.S. Namockovat si databázi je určitě řešení, po kterém bys měl sáhnout právě u jednotkových testů. Pokud chceš napsat nějaké integrační, už chceš pracovat se skutečnou databází.

Co takhle:

3. vyrobit za běhu pro každý test vlastní MySQL databázi. Testy ti pak budou moct běžet paralelně, nebudou na sebe čekat, ale pořád budou jeden od druhého stoprocentně izolované. Inspirovat se můžeš třeba v Kdyby

greeny
Člen | 405
+
0
-

@jiri.pudil děkuji za připomníky

  1. ano, to mi je jasné :) byl to jen způsob zrychlení testů, první co mě napadlo
  2. namockovat databázi myslíš jako PHP mock, nebo nějaký mock na úrovni systému?
  3. tohle už mě taky napadlo. Kdyby/TesterExtras jsem neznal a nejsem si jistý, jestli na to půjdou napojit migrace, protože ty samozřejmě berou DB připojení z configu (používám normální Doctrine migrace přes extension od Zenify). Pokud to chápu dobře, tak to… volá znovu konstruktor na danou Connection? Nemáš nějaký jednoduchý příklad použití? (nemá to k sobě dokumentaci)
Jan Endel
Člen | 1016
+
0
-

Btw pokud chceš zrychlit databázové testy – databáze nemusí brát data jenom z disku, když si to přepíšeš na ramku tak zrychlení bude násobné.

jiri.pudil
Nette Blogger | 1029
+
0
-

@greeny migrace sice berou připojení z configu, ale právě tomu připojení z configu pod rukama přepínáš databázi na tu čerstvě vytvořenou, takže se pak migrace spouští pro ni. Můžeš na to vyzrát třeba takhle:

use Zenify\DoctrineMigrations\Configuration\Configuration as MigrationsConfiguration;

private function runMigrations(Connection $db)
{
	$container = $this->getContainer();

	/** @var MigrationsConfiguration $migrationsConfig */
	$migrationsConfig = $container->getByType(MigrationsConfiguration::class);
	$migrationsConfig->__construct($container, $db);
	$migrationsConfig->registerMigrationsFromDirectory($migrationsConfig->getMigrationsDirectory());
	$migration = new Migration($migrationsConfig);

	$migration->migrate($migrationsConfig->getLatestVersion());
}

To volání konstruktoru tady není nutné, ale je docela vhodné ho zavolat a nepředat třetí argument (outputWriter), aby to nevypisovalo průběh migrací.

Editoval jiri.pudil (19. 11. 2015 23:43)

greeny
Člen | 405
+
0
-

@jiri.pudil
Děkuji za odpověď. Vyzkouším tohle řešení, třeba bude fungovat.

Na ten outputWriter už jsem taky narazil

jiri.pudil
Nette Blogger | 1029
+
0
-

@greeny já děkuju za nakopnutí, už jsem si rozepsal článeček na blog, kam zkusím dát a popsat nějakou komplexnější ukázku :)

Filip Procházka
Moderator | 4668
+
0
-

Já bych jen doplnil, že Kdyby/TesterExtras je určeno k inspiraci, nikoliv k instalaci :)