Ambiente de testeo
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.4/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
bootstrap="test.bootstrap.php"
|
||||
cacheDirectory="/code/cache/tests"
|
||||
executionOrder="depends,defects"
|
||||
requireCoverageMetadata="false"
|
||||
@ -34,10 +34,10 @@
|
||||
<php outputFile="/code/public/coverage/coverage.php"/>
|
||||
</report>
|
||||
</coverage>
|
||||
<!--<logging>
|
||||
<logging>
|
||||
<junit outputFile="/code/cache/tests/junit.xml"/>
|
||||
<teamcity outputFile="/code/cache/tests/teamcity.txt"/>
|
||||
<testdoxHtml outputFile="/code/cache/tests/testdox.html"/>
|
||||
<testdoxText outputFile="/code/cache/tests/testdox.txt"/>
|
||||
</logging>-->
|
||||
</logging>
|
||||
</phpunit>
|
||||
|
@ -5,42 +5,149 @@ require_once implode(DIRECTORY_SEPARATOR, [
|
||||
'autoload.php'
|
||||
]);
|
||||
|
||||
function setupDatabase(string $schemaFilename): void {
|
||||
printf("Loading database schema from %s", $schemaFilename);
|
||||
$start = microtime(true);
|
||||
|
||||
$dsn = "mysql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_DATABASE']}";
|
||||
$pdo = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASSWORD']);
|
||||
|
||||
$sql = file_get_contents($schemaFilename);
|
||||
$pdo->exec($sql);
|
||||
|
||||
$end = microtime(true);
|
||||
printf(" in %.2f seconds\n", $end - $start);
|
||||
}
|
||||
function truncateTables(): void {
|
||||
printf("Truncating tables");
|
||||
$start = microtime(true);
|
||||
|
||||
$dsn = "mysql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_DATABASE']}";
|
||||
$pdo = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASSWORD']);
|
||||
|
||||
$pdo->exec("SET FOREIGN_KEY_CHECKS=0");
|
||||
$statement = $pdo->query('SHOW TABLES');
|
||||
$tables = array_map(function(array $row) {
|
||||
return $row["Tables_in_{$_ENV['DB_DATABASE']}"];
|
||||
}, $statement->fetchAll(PDO::FETCH_ASSOC));
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$pdo->exec("TRUNCATE TABLE `$table`");
|
||||
class Benchmark
|
||||
{
|
||||
protected static array $queue = [];
|
||||
public static function print(): void
|
||||
{
|
||||
if (empty(self::$queue)) {
|
||||
return;
|
||||
}
|
||||
echo implode(PHP_EOL, self::$queue), PHP_EOL;
|
||||
self::$queue = [];
|
||||
}
|
||||
|
||||
public static function execute(callable $callback, ?array $args = null, ?string $description = null): mixed
|
||||
{
|
||||
if (null === $description) {
|
||||
$description = self::getCallableName($callback);
|
||||
}
|
||||
$i = count(self::$queue);
|
||||
self::$queue[$i] = "Executing $description";
|
||||
$start = microtime(true);
|
||||
|
||||
if (null === $args) {
|
||||
$result = call_user_func($callback);
|
||||
} else {
|
||||
$result = call_user_func_array($callback, $args);
|
||||
}
|
||||
$pdo->exec("SET FOREIGN_KEY_CHECKS=1");
|
||||
|
||||
$end = microtime(true);
|
||||
printf(" in %.2f seconds\n", $end - $start);
|
||||
self::$queue[$i] .= sprintf(" in %.2f seconds", $end - $start);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getCallableName(callable $callable): string
|
||||
{
|
||||
return match (true) {
|
||||
is_string($callable) && strpos($callable, '::') => '[static] ' . $callable,
|
||||
is_string($callable) => '[function] ' . $callable,
|
||||
is_array($callable) && is_object($callable[0]) => '[method] ' . get_class($callable[0]) . '->' . $callable[1],
|
||||
is_array($callable) => '[static] ' . $callable[0] . '::' . $callable[1],
|
||||
$callable instanceof Closure => '[closure]',
|
||||
is_object($callable) => '[invokable] ' . get_class($callable),
|
||||
default => '[unknown]',
|
||||
};
|
||||
}
|
||||
}
|
||||
$schemaFilename = implode(DIRECTORY_SEPARATOR, [__DIR__, 'resources', 'database', 'schema.sql']);
|
||||
setupDatabase($schemaFilename);
|
||||
register_shutdown_function(function() {
|
||||
truncateTables();
|
||||
class TestBootstrap
|
||||
{
|
||||
public function __construct(protected array $configuration) {}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
if (Benchmark::execute([$this, 'isMigrated'])) {
|
||||
Benchmark::execute([$this, 'resetDatabase']);
|
||||
}
|
||||
Benchmark::execute([$this, 'migrate']);
|
||||
}
|
||||
|
||||
protected string $baseCommand = "bin/phinx";
|
||||
public function isMigrated(): bool
|
||||
{
|
||||
$cmd = "{$this->baseCommand} status -e testing -f json --no-info";
|
||||
$output = shell_exec($cmd);
|
||||
$status = json_decode($output, true);
|
||||
|
||||
return $status['missing_count'] > 0;
|
||||
}
|
||||
public function migrate(): void
|
||||
{
|
||||
$cmd = "{$this->baseCommand} migrate -e testing";
|
||||
shell_exec($cmd);
|
||||
}
|
||||
|
||||
public function resetDatabase(): void
|
||||
{
|
||||
$tables = $this->getTables();
|
||||
if ($this->connect()->beginTransaction()) {
|
||||
try {
|
||||
$this->connect()->query("SET FOREIGN_KEY_CHECKS=0;");
|
||||
foreach ($tables as $table) {
|
||||
$this->connect()->query("DROP TABLE IF EXISTS `{$table}`");
|
||||
}
|
||||
$this->connect()->query("SET FOREIGN_KEY_CHECKS=1;");
|
||||
if ($this->connect()->inTransaction()) {
|
||||
$this->connect()->commit();
|
||||
}
|
||||
} catch (PDOException $exception) {
|
||||
if ($this->connect()->inTransaction()) {
|
||||
$this->connect()->rollBack();
|
||||
}
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function truncateTables(): void
|
||||
{
|
||||
$tables = $this->getTables();
|
||||
if ($this->connect()->beginTransaction()) {
|
||||
try {
|
||||
$this->connect()->query("SET FOREIGN_KEY_CHECKS=0;");
|
||||
foreach ($tables as $table) {
|
||||
$this->connect()->query("TRUNCATE TABLE `{$table}`");
|
||||
}
|
||||
$this->connect()->query("SET FOREIGN_KEY_CHECKS=1;");
|
||||
if ($this->connect()->inTransaction()) {
|
||||
$this->connect()->commit();
|
||||
}
|
||||
} catch (PDOException $exception) {
|
||||
if ($this->connect()->inTransaction()) {
|
||||
$this->connect()->rollBack();
|
||||
}
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected PDO $connection;
|
||||
protected function connect(): PDO
|
||||
{
|
||||
if (!isset($this->connection)) {
|
||||
$dsn = "mysql:host={$this->configuration['DB_HOST']};dbname={$this->configuration['DB_DATABASE']}";
|
||||
$this->connection = new PDO(
|
||||
$dsn,
|
||||
$this->configuration['DB_USER'],
|
||||
$this->configuration['DB_PASSWORD']
|
||||
);
|
||||
}
|
||||
return $this->connection;
|
||||
}
|
||||
protected array $tables;
|
||||
protected function getTables(): array
|
||||
{
|
||||
if (!isset($this->tables)) {
|
||||
$this->tables = $this->connect()->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
|
||||
}
|
||||
return $this->tables;
|
||||
}
|
||||
}
|
||||
|
||||
$bootstrap = new TestBootstrap($_ENV);
|
||||
Benchmark::execute([$bootstrap, 'run']);
|
||||
Benchmark::print();
|
||||
|
||||
register_shutdown_function(function() use ($bootstrap) {
|
||||
Benchmark::execute([$bootstrap, 'truncateTables']);
|
||||
Benchmark::print();
|
||||
});
|
||||
|
@ -84,20 +84,6 @@ services:
|
||||
- ${CLI_PATH:-.}:/code
|
||||
- ./logs/cli:/logs
|
||||
|
||||
testing:
|
||||
profiles:
|
||||
- testing
|
||||
container_name: incoviba_tests
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- ${APP_PATH:-.}/.env
|
||||
- ./.key.env
|
||||
volumes:
|
||||
- ${APP_PATH:-.}/:/code
|
||||
- ./logs/test:/logs
|
||||
command: [ '/code/bin/phpunit-watcher', 'watch' ]
|
||||
|
||||
volumes:
|
||||
dbdata: {}
|
||||
incoviba_redis: {}
|
||||
|
@ -2,34 +2,32 @@ services:
|
||||
testing:
|
||||
profiles:
|
||||
- testing
|
||||
container_name: incoviba_tests
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
container_name: incoviba_tests
|
||||
env_file:
|
||||
- ${APP_PATH:-.}/.test.env
|
||||
- ./.key.env
|
||||
volumes:
|
||||
- ${APP_PATH:-.}/:/code
|
||||
- ./logs/test:/logs
|
||||
command: [ '/code/bin/phpunit-watcher', 'watch' ]
|
||||
networks:
|
||||
- testing
|
||||
depends_on:
|
||||
- test-db
|
||||
|
||||
test-db:
|
||||
profiles:
|
||||
- testing
|
||||
image: mysql:5.7
|
||||
image: mariadb:latest
|
||||
container_name: incoviba_test_db
|
||||
restart: unless-stopped
|
||||
env_file: ${APP_PATH:-.}/.test.db.env
|
||||
volumes:
|
||||
- test-db:/var/lib/mysql
|
||||
networks:
|
||||
- default
|
||||
- adminer_network
|
||||
- testing
|
||||
|
||||
volumes:
|
||||
test-db: {}
|
||||
|
||||
networks:
|
||||
adminer_network: {}
|
||||
testing: {}
|
||||
|
Reference in New Issue
Block a user