I am making a base test class that bootstraps database Test cases
namespace Tests
use App\DB\DBFactory;
use Phinx\Config\Config;
use Phinx\Migration\Manager;
use PHPUnit\Framework\TestCase;
class DatabaseTestCase extends TestCase
{
private PDO $pdo;
private $migrationManager;
public function setUp(): void
{
parent::setUp();
error_reporting(E_ALL);
/**
* For robustness we place the configuration here
* We avoid using phinx.php cause I want to have fixed settings for db
*/
$migration_config = [
'paths' => [
'migrations' => __DIR__.'/../db/migrations',
'seeds' => __DIR__.'/../db/seeds'
],
'environments' => [
'default_migration_table' => 'phinxlog',
'default_environment' => 'testing',
'testing' => [
'adapter' => 'mysql',
'host' => $_ENV['MYSQL_HOST'],
'name' => $_ENV['MYSQL_DATABASE'],
'user' => $_ENV['MYSQL_USER'],
'pass' => $_ENV['MYSQL_PASSWORD'],
'port' => $_ENV['DB_PORT']??'3306',
'charset' => 'utf8',
],
],
'version_order' => 'creation'
];
// Configs need to be the same for both application and tests.
$pdo = self::createTestDb($migration_config,$new_config);
$config = new Config($new_config);
$manager = new Manager($config, new StringInput(' '), new NullOutput());
$this->migrationManager = $manager;
$this->migrationManager->migrate('testing');
// You can change default fetch mode after the seeding
$this->pdo = $pdo;
}
public function tearDown():void
{
try{
$testDbName = $this->pdo->query('select database()')->fetchColumn();
$this->pdo->query("DROP DATABASE `" . str_replace('`', '``', $testDbName) . "`");
}catch (\Exception $e){
}
parent::tearDown();
}
}
I create the PDO connection as:
namespace App\DB;
class DBFactory
{
/**
* Setups a New Db service from config
* @return \PDO
*/
public static function createDbConnectionInstance(array $config):\PDO
{
$connectionString = 'mysql:host=%s;port=%s;dbname=%s';
$dbPort = !empty($config['port'])?$config['port']:3306;
$dsn = sprintf($connectionString,$config['host'],$dbPort,$config['name']);
$pdo = new \PDO($dsn,$config['user'],$config['pass']);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return $pdo;
}
}
The idea to use it is just extend the DatabaseTestCase
In case that some of my tests require a DB Connection and a Database:
namespace Tests;
use Tests\DatabaseTestCase;
class DummyTest extends DatabaseTestCase
{
public function testDump()
{
//
$this->assertTrue(true);
}
}
And upon each test a new Db is created. The reason why I implemented this is because I need to parallelize my tests and some of them require Db connection (for example to ensure that records are properly written or modified upon DB).
But what the downsides in this approach? Is this a good approach?
createTestDb
I give the existing config and I update the config with the new databaseName. The$new_config
is the new configuration. Ommited for simplicity. \$\endgroup\$