Robusní testovaní řadiču v nette
- Ondris
- Člen | 37
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.
- Petr Parolek
- Člen | 455
používám velmi dlouho https://github.com/…ik/testbench a naprostá spokojenost
- Ondris
- Člen | 37
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.
- h4kuna
- Backer | 740
@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í a 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
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í.