Robusní testovaní řadiču v nette

Ondris
Člen | 37
+
0
-

Ahoj,

začínám psát testy na jednu větší aplikaci v nette. Nechci spát jednotlivý testy jednotek, ale celkový testy řadičů. To znamená, že test by měl odeslat celý formulář a pak zkontrolovat, jestli se provedli všechny navazující úkony. Tuhle kontrolu bych rád prováděl v databázi. Slyšel jsem o http://docs.mockery.io/…example.html , ale radši bych se mu vyhnul, protože chci mít testy co „nejblíž reálnému použití“. Mám s tím, ale dva problémy:

<?php

declare(strict_types=1);

namespace App\Tests;

use Nette;
use Tester;
use Tester\Assert;

$container = require __DIR__ . '/../../../../../app/bootstrap.php';

/** @testCase */
class IssueWorkflowPresenterTest extends Tester\TestCase
{
    /** @var \Nette\Database\Context */
    private $database;

    private $presenterFactory;

    public function __construct(Nette\DI\Container $container)
    {
        $this->database = $container->getByType('\Nette\Database\Context');
        $this->presenterFactory = $container->getByType('Nette\Application\IPresenterFactory');
    }

    public function setUp() {
        $this->database->beginTransaction();
    }

    public function testSomething() {
        Assert::true(true);
    }

    public function tearDown() {
        $this->database->rollBack();

        parent::tearDown();
    }

}

$test = new IssueWorkflowPresenterTest($container);
$test->run();

Tento kód mi vyhodí chybu:
Nette\Database\ConnectionException
could not find driver

2. Zajímalo by mě, pokud při testování pracujete s databází, jak to řešíte? Zatím mám představu, že udělám bootstrap pro testy, v něm nastavím jiný config a tam bude jiná databáze. V ní bude připojená jiná databáze. Problémy ale jsou, že budu muset migrace spouštět na 2 databázemi. Pak ještě se bude muset vytvořit nějaká výchozí sada dat. Teď když to píšu, tak to nezní jak tolik práce, ale přece jen by mě zajímali vaše zkušenosti.

chemix
Nette Core | 1304
+
0
-

Na tohle ma David Matejka nekolik povidani. V mangowebu udelali mangotester ktery prave ulehcuje tyto integracni testu a resi si databazi (chces ji mit pro kazdy test “cistou”)

Co pouzivas za db driver? Orm?
Jakou databazi pouzivas?

h4kuna
Backer | 740
+
+3
-

Během následujícího týdne vývojáři z čsfd vydají balíček/nástroj na tento případ testování.

Editoval h4kuna (11. 5. 2019 18:13)

Petr Parolek
Člen | 455
+
-1
-

používám velmi dlouho https://github.com/…ik/testbench a naprostá spokojenost

Ondris
Člen | 37
+
0
-

Používáme databází mysql + doctrinu, občas když je někde problém s výkonností, tak použijeme nette database.

Jinak díky v pondělí vyzkouším tyto dva balíčky:
https://github.com/…ik/testbench
https://github.com/…mango-tester

@h4kuna Pokud jsem po vydání toho balíčku hodíš odkaz, tak budu rád.

Ondris
Člen | 37
+
0
-

Pořád i s těmi knihovnami mi to skončí na chybě:

Nette\Database\ConnectionException
could not find driver

Přitom stránky jako takový normálně fungují. config zatím používám stejný pro web i testy. Nevíte někdo v čem může být chyba?

h4kuna
Backer | 740
+
0
-

@Ondris Tak je to venku DatabaseReplicator

Cílem tohoto nástroje je připravit kopii databáze pro test. Není potřeba používat zámky a transakce. Opravdu ta kopie je jen pro jeden test. Použití v testech je je jednoduché a vyžaduje dvě volání. Na začátku testu nebo v metodě setUp() je potřeba zavolat $database->create() co ti vrátí instanci tvého connection ukazující na novou databázi a na konci testu $database->drop(). Více v readme. Nástroj je rok v interním provozu.

Vnitřní fungování je následující, vytvoří se zdrojová databáze ze souboru/ů na disku, nadále je jen pro čtení. Ze souboru/ů se dělá md5 hash a tím se poznává zda je zdrojová databáze aktuální. A při každém požádání se z ní udělá kopie.

Bacha zajímavost v čsfd během testů se vyrobí cca 250 databází. Postgres to umí kopírovat během mžiku.

Rozšíření pro nette je tady

Celkově to má pár ale:

  • není implementovaná žádná veřejná databázová vrstva, protože v čsfd je unikátní, klidně pošli PR, v readme je postup jak toho docílit, bude to vyžadovat vlastní tvorbu
  • v praxi není otestovaná podpora pro mysql, protože v čsfd je postgres
  • testnul jsem to pro nette 3, nicméně zatím primární podpora je pro nette 2.4

Jak to nainstalovat, předpokládám že budeš chtít nette rozšířenímysql

composer require --dev pmgdev/database-replicator-nette

Pro mysql je větev, kde testy prochází nicméně to opravdu není otestovaný v provozu.
V composer.json pod řádek "pmgdev/database-replicator-nette": "^0.1.0" přidej "pmgdev/database-replicator": "dev-mysql as 0.1.x-dev" a spusť composer update pmgdev/database-replicator

V neonu bude potřeba ještě podstrčit službě databaseReplicator.command třídu PmgDev\DatabaseReplicator\Database\Mysql\Command

services:
	- PmgDev\DatabaseReplicator\Database\Mysql\CommandFactory
	databaseReplicator.command:
		create: @PmgDev\DatabaseReplicator\Database\Mysql\CommandFactory::create(@databaseReplicator.admin)

Bude ti hlásit, aby jsi doplnil cestu na svůj sql soubor, kde je zapsaný schéma databáze.

Otestovat si to můžeš vytažením přes container

$database = $container->getService('databaseReplicator.test_db.database'); // test_db v názvu je vzato z readme rozšíření
$database->create();

Snad jsem na nic nezapomněl.

Editoval h4kuna (20. 5. 2019 10:05)

Mysteria
Člen | 797
+
0
-

Osobně používám taky přístup pro každý test vlastní databáze. Nepoužívám tedy žádné rozšíření, protože si myslím, že na těch asi 25 řádků to opravdu není potřeba, ale v setUp metodě vygeneruju náhodný název databáze, z SQL skriptu ji vytvořím a vložím testovací data a EntityManageru přes ReflectionObject změním název databáze. V tearDown pak jenom databázi smažu. Výhodou je, že díky tomu mohou testy běžet paralerně, takže není problém s rychlostí.