Skip to content

Commit b4d38fe

Browse files
committed
Setup paratest for unit and integration tests parallelization
1 parent a03befe commit b4d38fe

5 files changed

Lines changed: 97 additions & 8 deletions

File tree

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ jobs:
148148
run: ./vendor/bin/testbench-dusk package:discover
149149

150150
- name: Execute all tests
151-
run: vendor/bin/phpunit --stop-on-error
151+
run: vendor/bin/paratest --testsuite Unit,Integration --stop-on-error && vendor/bin/phpunit --testsuite Browser --stop-on-error
152152
env:
153153
DB_PORT: ${{ job.services.mysql.ports['3306'] }}
154154

composer.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
},
4747
"require-dev": {
4848
"area17/phptorch": "dev-main",
49+
"brianium/paratest": "^7.8",
4950
"chillerlan/php-qrcode": "~4.0",
5051
"friendsofphp/php-cs-fixer": "^3.0",
5152
"larastan/larastan": "^2.9 | ^3.0",
@@ -74,12 +75,14 @@
7475
}
7576
},
7677
"scripts": {
77-
"test:phpunit": "vendor/bin/phpunit",
78+
"test:phpunit": "vendor/bin/paratest --testsuite Unit,Integration --stop-on-error --no-coverage",
79+
"test:browser": "vendor/bin/phpunit --testsuite Browser --stop-on-error --no-coverage",
7880
"test:analyse": "php -d memory_limit=-1 vendor/bin/phpstan analyse",
7981
"test:syntax": "vendor/bin/php-cs-fixer --dry-run fix src",
8082
"test": [
8183
"@test:syntax",
82-
"@test:phpunit"
84+
"@test:phpunit",
85+
"@test:browser"
8386
],
8487
"post-autoload-dump": [
8588
"@php ./vendor/bin/testbench package:discover --ansi"

phpunit-legacy.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
</testsuite>
2323
<testsuite name="Unit">
2424
<directory>tests/unit</directory>
25+
</testsuite>
26+
<testsuite name="Integration">
2527
<directory>tests/integration</directory>
2628
</testsuite>
2729
</testsuites>

phpunit.xml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="tests/bootstrap.php" colors="true" processIsolation="false" stopOnError="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.1/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
displayDetailsOnPhpunitDeprecations="true"
4+
displayDetailsOnTestsThatTriggerWarnings="true"
5+
backupGlobals="false"
6+
bootstrap="tests/bootstrap.php"
7+
colors="true"
8+
processIsolation="false"
9+
stopOnError="true"
10+
stopOnFailure="true"
11+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.1/phpunit.xsd"
12+
cacheDirectory=".phpunit.cache"
13+
backupStaticProperties="false"
14+
>
315
<coverage>
416
<report>
517
<clover outputFile="./.github/clover.xml"/>
@@ -12,6 +24,8 @@
1224
</testsuite>
1325
<testsuite name="Unit">
1426
<directory>tests/unit</directory>
27+
</testsuite>
28+
<testsuite name="Integration">
1529
<directory>tests/integration</directory>
1630
</testsuite>
1731
</testsuites>
@@ -27,6 +41,7 @@
2741
<env name="CACHE_STORE" value="array"/>
2842
<env name="SESSION_DRIVER" value="array"/>
2943
<env name="QUEUE_DRIVER" value="sync"/>
44+
<env name="QUEUE_CONNECTION" value="sync"/>
3045
<env name="MAIL_DRIVER" value="array"/>
3146
<env name="DB_CONNECTION" value="mysql"/>
3247
<env name="DB_DATABASE" value="twill_testing_3x"/>

tests/integration/TestCase.php

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public function createApplication(): Application
6969

7070
public static function setUpBeforeClass(): void
7171
{
72+
self::prepareParallelTestbenchApplication();
73+
self::configureParallelDatabase();
7274
cleanupTestState(self::applicationBasePath());
7375
parent::setUpBeforeClass();
7476
}
@@ -101,12 +103,13 @@ public function setUp(): void
101103
}
102104

103105
$loader = new ClassLoader();
104-
$loader->addPsr4('App\\', 'vendor/orchestra/testbench-core/laravel/app');
106+
$loader->addPsr4('App\\', $this->getBasePath() . '/app');
105107
$loader->register();
106108

107109
// Enforce the url for testing to be 'http://twill.test' for certain assertions.
108110
// This is different from the one in phpunit.xml because that one is used for laravel dusk.
109-
$_ENV['APP_URL'] = 'http://twill.test';
111+
$_ENV['APP_URL'] = $_SERVER['APP_URL'] = 'http://twill.test';
112+
putenv('APP_URL=http://twill.test');
110113
$_ENV['MEDIA_LIBRARY_LOCAL_PATH'] = "media-library";
111114
$_ENV["FILE_LIBRARY_LOCAL_PATH"] = "file-library";
112115
$_ENV["FILE_LIBRARY_ENDPOINT_TYPE"] = "local";
@@ -149,6 +152,7 @@ public function setUp(): void
149152
*/
150153
public function configTwill($app): void
151154
{
155+
$app['config']->set('app.url', 'http://twill.test');
152156
$app['config']->set('twill.admin_app_url', '');
153157
$app['config']->set('twill.admin_app_path', 'twill');
154158
$app['config']->set('twill.auth_login_redirect_path', '/twill');
@@ -556,7 +560,13 @@ public function loadConfig()
556560

557561
protected static function getBasePathStatic(): string
558562
{
559-
return __DIR__ . '/../../vendor/orchestra/testbench-core/laravel';
563+
$basePath = __DIR__ . '/../../vendor/orchestra/testbench-core/laravel';
564+
565+
if ($token = self::parallelTestingToken()) {
566+
return $basePath . '_' . $token;
567+
}
568+
569+
return $basePath;
560570
}
561571

562572
public static function applicationBasePath(): string
@@ -566,6 +576,65 @@ public static function applicationBasePath(): string
566576

567577
protected function getBasePath(): string
568578
{
569-
return __DIR__ . '/../../vendor/orchestra/testbench-core/laravel';
579+
return self::getBasePathStatic();
580+
}
581+
582+
protected static function parallelTestingToken(): ?string
583+
{
584+
return $_SERVER['TEST_TOKEN'] ?? $_ENV['TEST_TOKEN'] ?? null;
585+
}
586+
587+
protected static function prepareParallelTestbenchApplication(): void
588+
{
589+
if (! self::parallelTestingToken()) {
590+
return;
591+
}
592+
593+
$source = __DIR__ . '/../../vendor/orchestra/testbench-core/laravel';
594+
$target = self::getBasePathStatic();
595+
596+
if (! is_dir($target)) {
597+
self::copyDirectory($source, $target);
598+
}
599+
}
600+
601+
protected static function configureParallelDatabase(): void
602+
{
603+
if (! self::parallelTestingToken() || ($_ENV['DB_CONNECTION'] ?? null) !== 'mysql') {
604+
return;
605+
}
606+
607+
$database = preg_replace('/_\d+$/', '', $_ENV['DB_DATABASE']) . '_' . self::parallelTestingToken();
608+
$_ENV['DB_DATABASE'] = $_SERVER['DB_DATABASE'] = $database;
609+
putenv("DB_DATABASE={$database}");
610+
611+
$host = $_ENV['DB_HOST'] ?? '127.0.0.1';
612+
$port = $_ENV['DB_PORT'] ?? '3306';
613+
$username = $_ENV['DB_USERNAME'] ?? 'root';
614+
$password = $_ENV['DB_PASSWORD'] ?? '';
615+
616+
$pdo = new \PDO("mysql:host={$host};port={$port}", $username, $password);
617+
$pdo->exec("DROP DATABASE IF EXISTS `{$database}`");
618+
$pdo->exec("CREATE DATABASE `{$database}`");
619+
}
620+
621+
protected static function copyDirectory(string $source, string $target): void
622+
{
623+
mkdir($target, 0777, true);
624+
625+
foreach (scandir($source) as $item) {
626+
if ($item === '.' || $item === '..') {
627+
continue;
628+
}
629+
630+
$sourcePath = $source . DIRECTORY_SEPARATOR . $item;
631+
$targetPath = $target . DIRECTORY_SEPARATOR . $item;
632+
633+
if (is_dir($sourcePath) && ! is_link($sourcePath)) {
634+
self::copyDirectory($sourcePath, $targetPath);
635+
} else {
636+
copy($sourcePath, $targetPath);
637+
}
638+
}
570639
}
571640
}

0 commit comments

Comments
 (0)