mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-11-24 03:42:32 +01:00
Merge pull request #3751 from BookStackApp/parallel_testing
Parallel Testing Support
This commit is contained in:
commit
67d7534d4f
@ -44,6 +44,7 @@
|
||||
"ssddanbrown/htmldiff": "^1.0.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "^6.6",
|
||||
"fakerphp/faker": "^1.16",
|
||||
"itsgoingd/clockwork": "^5.1",
|
||||
"mockery/mockery": "^1.4",
|
||||
@ -73,6 +74,8 @@
|
||||
"format": "phpcbf",
|
||||
"lint": "phpcs",
|
||||
"test": "phpunit",
|
||||
"t": "@php artisan test --parallel",
|
||||
"t-reset": "@php artisan test --recreate-databases",
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
|
@ -108,14 +108,9 @@ npm run dev
|
||||
|
||||
BookStack has many integration tests that use Laravel's built-in testing capabilities which makes use of PHPUnit. There is a `mysql_testing` database defined within the app config which is what is used by PHPUnit. This database is set with the database name, user name and password all defined as `bookstack-test`. You will have to create that database and that set of credentials before testing.
|
||||
|
||||
The testing database will also need migrating and seeding beforehand. This can be done with the following commands:
|
||||
The testing database will also need migrating and seeding beforehand. This can be done by running `composer refresh-test-database`.
|
||||
|
||||
``` bash
|
||||
php artisan migrate --database=mysql_testing
|
||||
php artisan db:seed --class=DummyContentSeeder --database=mysql_testing
|
||||
```
|
||||
|
||||
Once done you can run `composer test` in the application root directory to run all tests.
|
||||
Once done you can run `composer test` in the application root directory to run all tests. Tests can be ran in parallel by running them via `composer t`. This will use Laravel's built-in parallel testing functionality, and attempt to create and seed a database instance for each testing thread. If required these parallel testing instances can be reset, before testing again, by running `composer t-reset`.
|
||||
|
||||
### 📜 Code Standards
|
||||
|
||||
|
@ -22,10 +22,12 @@ use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Handler\MockHandler;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\Middleware;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Env;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Testing\Assert as PHPUnit;
|
||||
use Monolog\Handler\TestHandler;
|
||||
@ -47,6 +49,21 @@ abstract class TestCase extends BaseTestCase
|
||||
*/
|
||||
protected string $baseUrl = 'http://localhost';
|
||||
|
||||
/**
|
||||
* Creates the application.
|
||||
*
|
||||
* @return \Illuminate\Foundation\Application
|
||||
*/
|
||||
public function createApplication()
|
||||
{
|
||||
/** @var \Illuminate\Foundation\Application $app */
|
||||
$app = require __DIR__ . '/../bootstrap/app.php';
|
||||
$app->register(TestServiceProvider::class);
|
||||
$app->make(Kernel::class)->bootstrap();
|
||||
|
||||
return $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current user context to be an admin.
|
||||
*/
|
||||
@ -299,6 +316,8 @@ abstract class TestCase extends BaseTestCase
|
||||
/**
|
||||
* Run a set test with the given env variable.
|
||||
* Remembers the original and resets the value after test.
|
||||
* Database config is juggled so the value can be restored when
|
||||
* parallel testing are used, where multiple databases exist.
|
||||
*/
|
||||
protected function runWithEnv(string $name, $value, callable $callback)
|
||||
{
|
||||
@ -311,7 +330,12 @@ abstract class TestCase extends BaseTestCase
|
||||
$_SERVER[$name] = $value;
|
||||
}
|
||||
|
||||
$database = config('database.connections.mysql_testing.database');
|
||||
$this->refreshApplication();
|
||||
|
||||
DB::purge();
|
||||
config()->set('database.connections.mysql_testing.database', $database);
|
||||
|
||||
$callback();
|
||||
|
||||
if (is_null($originalVal)) {
|
||||
|
26
tests/TestServiceProvider.php
Normal file
26
tests/TestServiceProvider.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\ParallelTesting;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class TestServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
// Tell Laravel's parallel testing functionality to seed the test
|
||||
// databases with the DummyContentSeeder upon creation.
|
||||
// This is only done for initial database creation. Seeding
|
||||
// won't occur on every run.
|
||||
ParallelTesting::setUpTestDatabase(function ($database, $token) {
|
||||
Artisan::call('db:seed --class=DummyContentSeeder');
|
||||
});
|
||||
}
|
||||
}
|
@ -322,8 +322,8 @@ class ThemeTest extends TestCase
|
||||
|
||||
public function test_export_body_start_and_end_template_files_can_be_used()
|
||||
{
|
||||
$bodyStartStr = 'barry-fought-against-the-panther';
|
||||
$bodyEndStr = 'barry-lost-his-fight-with-grace';
|
||||
$bodyStartStr = 'garry-fought-against-the-panther';
|
||||
$bodyEndStr = 'garry-lost-his-fight-with-grace';
|
||||
/** @var Page $page */
|
||||
$page = Page::query()->first();
|
||||
|
||||
@ -342,18 +342,18 @@ class ThemeTest extends TestCase
|
||||
protected function usingThemeFolder(callable $callback)
|
||||
{
|
||||
// Create a folder and configure a theme
|
||||
$themeFolderName = 'testing_theme_' . rtrim(base64_encode(time()), '=');
|
||||
$themeFolderName = 'testing_theme_' . str_shuffle(rtrim(base64_encode(time()), '='));
|
||||
config()->set('view.theme', $themeFolderName);
|
||||
$themeFolderPath = theme_path('');
|
||||
|
||||
// Create theme folder and clean it up on application tear-down
|
||||
File::makeDirectory($themeFolderPath);
|
||||
$this->beforeApplicationDestroyed(fn() => File::deleteDirectory($themeFolderPath));
|
||||
|
||||
// Run provided callback with theme env option set
|
||||
$this->runWithEnv('APP_THEME', $themeFolderName, function () use ($callback, $themeFolderName) {
|
||||
call_user_func($callback, $themeFolderName);
|
||||
});
|
||||
|
||||
// Cleanup the custom theme folder we created
|
||||
File::deleteDirectory($themeFolderPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user