From 956a23492061bcdb12b5c33c78b7b00e2a6d058c Mon Sep 17 00:00:00 2001 From: Tomasz Strojny Date: Sun, 31 Mar 2019 14:28:24 +0200 Subject: [PATCH] Add ability to specify the connection used for running tests (#4159) Credit to @czerwonyd --- config/database.php | 16 ++++++++++ modules/system/console/OctoberEnv.php | 9 ++++-- tests/PluginTestCase.php | 34 ++++++++++++++------ tests/README.md | 46 +++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 15 deletions(-) diff --git a/config/database.php b/config/database.php index e8d04bab8..0b33b461f 100644 --- a/config/database.php +++ b/config/database.php @@ -125,4 +125,20 @@ return [ ], + /* + |-------------------------------------------------------------------------- + | Use DB configuration for testing + |-------------------------------------------------------------------------- + | + | When running plugin tests OctoberCMS by default uses SQLite in memory. + | You can override this behavior by setting `useConfigForTesting` to true. + | + | After that OctoberCMS will take DB parameters from the config. + | If file `/config/testing/database.php` exists, config will be read from it, + | but remember that when not specified it will use parameters specified in + | `/config/database.php`. + | + */ + + 'useConfigForTesting' => false, ]; diff --git a/modules/system/console/OctoberEnv.php b/modules/system/console/OctoberEnv.php index 6e87ff908..5d8a43949 100644 --- a/modules/system/console/OctoberEnv.php +++ b/modules/system/console/OctoberEnv.php @@ -125,6 +125,7 @@ class OctoberEnv extends Command { foreach ($keys as $envKey => $configKey) { $pattern = $this->buildPattern($configKey); + $callback = $this->buildCallback($envKey, $configKey); if (preg_match($pattern, $line)) { @@ -142,7 +143,6 @@ class OctoberEnv extends Command private function replaceDbConfigLine($line) { if ($this->config == 'database') { - foreach ($this->dbConfig() as $connection => $settings) { $this->setCurrentConnection($line, $connection); @@ -183,7 +183,6 @@ class OctoberEnv extends Command private function buildCallback($envKey, $configKey) { return function ($matches) use ($envKey, $configKey) { - $value = $this->envValue($configKey); $this->saveEnvSettings($envKey, $value); @@ -249,6 +248,10 @@ class OctoberEnv extends Command return config('database.default'); } + if ($configKey == 'useConfigForTesting') { + return config('database.useConfigForTesting'); + } + if ($this->connection == 'redis') { return config("database.redis.default.$configKey"); } @@ -345,6 +348,7 @@ class OctoberEnv extends Command ], 'database' => [ 'DB_CONNECTION' => 'default', + 'DB_USE_CONFIG_FOR_TESTING' => 'useConfigForTesting', ], 'cache' => [ 'CACHE_DRIVER' => 'default', @@ -402,5 +406,4 @@ class OctoberEnv extends Command ], ]; } - } diff --git a/tests/PluginTestCase.php b/tests/PluginTestCase.php index 2ae756ddd..9689c8790 100644 --- a/tests/PluginTestCase.php +++ b/tests/PluginTestCase.php @@ -25,14 +25,25 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase $app->setLocale('en'); /* - * Store database in memory + * Store database in memory by default, if not specified otherwise */ - $app['config']->set('database.default', 'sqlite'); - $app['config']->set('database.connections.sqlite', [ + $dbConnection = 'sqlite'; + + $dbConnections = []; + $dbConnections['sqlite'] = [ 'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '' - ]); + ]; + + if (env('APP_ENV') === 'testing' && Config::get('database.useConfigForTesting', false)) { + $dbConnection = Config::get('database.default', 'sqlite'); + + $dbConnections[$dbConnection] = Config::get('database.connections' . $dbConnection, $dbConnections['sqlite']); + } + + $app['config']->set('database.default', $dbConnection); + $app['config']->set('database.connections.' . $dbConnection, $dbConnections[$dbConnection]); /* * Modify the plugin path away from the test context @@ -53,7 +64,7 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase */ PluginManager::forgetInstance(); UpdateManager::forgetInstance(); - + /* * Create application instance */ @@ -109,7 +120,9 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase protected function runPluginRefreshCommand($code, $throwException = true) { if (!preg_match('/^[\w+]*\.[\w+]*$/', $code)) { - if (!$throwException) return; + if (!$throwException) { + return; + } throw new Exception(sprintf('Invalid plugin code: "%s"', $code)); } @@ -124,7 +137,9 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase $path = array_get($manager->getPluginNamespaces(), $namespace); if (!$path) { - if (!$throwException) return; + if (!$throwException) { + return; + } throw new Exception(sprintf('Unable to find plugin with code: "%s"', $code)); } @@ -138,8 +153,9 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase if (!empty($plugin->require)) { foreach ((array) $plugin->require as $dependency) { - - if (isset($this->pluginTestCaseLoadedPlugins[$dependency])) continue; + if (isset($this->pluginTestCaseLoadedPlugins[$dependency])) { + continue; + } $this->runPluginRefreshCommand($dependency); } diff --git a/tests/README.md b/tests/README.md index f04d5fb2b..a9e7b78b5 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,7 +4,7 @@ Plugin unit tests can be performed by running `phpunit` in the base plugin direc ### Creating plugin tests -Plugins can be tested by creating a creating a file called `phpunit.xml` in the base directory with the following content, for example, in a file **/plugins/acme/blog/phpunit.xml**: +Plugins can be tested by creating a file called `phpunit.xml` in the base directory with the following content, for example, in a file **/plugins/acme/blog/phpunit.xml**: , ...] -# System testing +> **Note:** If your plugin uses [configuration files](../plugin/settings#file-configuration), then you will need to run `System\Classes\PluginManager::instance()->registerAll(true);` in the `setUp` method of your tests. Below is an example of a base test case class that should be used if you need to test your plugin working with other plugins instead of in isolation. + + use System\Classes\PluginManager; + + class BaseTestCase extends PluginTestCase + { + public function setUp() + { + parent::setUp(); + + // Get the plugin manager + $pluginManager = PluginManager::instance(); + + // Register the plugins to make features like file configuration available + $pluginManager->registerAll(true); + + // Boot all the plugins to test with dependencies of this plugin + $pluginManager->bootAll(true); + } + + public function tearDown() + { + parent::tearDown(); + + // Get the plugin manager + $pluginManager = PluginManager::instance(); + + // Ensure that plugins are registered again for the next test + $pluginManager->unregisterAll(); + } + } + +#### Changing database engine for plugins tests + +By default OctoberCMS uses SQLite stored in memory for the plugin testing environment. If you want to override the default behavior set the `useConfigForTesting` config to `true` in your `/config/database.php` file. When the `APP_ENV` is `testing` and the `useConfigForTesting` is `true` database parameters will be taken from `/config/database.php`. + +You can override the `/config/database.php` file by creating `/config/testing/database.php`. In this case variables from the latter file will be taken. + +## System testing + +To perform unit testing on the core October files, you should download a development copy using composer or cloning the git repo. This will ensure you have the `tests/` directory. ### Unit tests