Add ability to specify the connection used for running tests (#4159)
Credit to @czerwonyd
This commit is contained in:
parent
8280047d30
commit
956a234920
|
|
@ -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,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ class OctoberEnv extends Command
|
||||||
{
|
{
|
||||||
foreach ($keys as $envKey => $configKey) {
|
foreach ($keys as $envKey => $configKey) {
|
||||||
$pattern = $this->buildPattern($configKey);
|
$pattern = $this->buildPattern($configKey);
|
||||||
|
|
||||||
$callback = $this->buildCallback($envKey, $configKey);
|
$callback = $this->buildCallback($envKey, $configKey);
|
||||||
|
|
||||||
if (preg_match($pattern, $line)) {
|
if (preg_match($pattern, $line)) {
|
||||||
|
|
@ -142,7 +143,6 @@ class OctoberEnv extends Command
|
||||||
private function replaceDbConfigLine($line)
|
private function replaceDbConfigLine($line)
|
||||||
{
|
{
|
||||||
if ($this->config == 'database') {
|
if ($this->config == 'database') {
|
||||||
|
|
||||||
foreach ($this->dbConfig() as $connection => $settings) {
|
foreach ($this->dbConfig() as $connection => $settings) {
|
||||||
$this->setCurrentConnection($line, $connection);
|
$this->setCurrentConnection($line, $connection);
|
||||||
|
|
||||||
|
|
@ -183,7 +183,6 @@ class OctoberEnv extends Command
|
||||||
private function buildCallback($envKey, $configKey)
|
private function buildCallback($envKey, $configKey)
|
||||||
{
|
{
|
||||||
return function ($matches) use ($envKey, $configKey) {
|
return function ($matches) use ($envKey, $configKey) {
|
||||||
|
|
||||||
$value = $this->envValue($configKey);
|
$value = $this->envValue($configKey);
|
||||||
|
|
||||||
$this->saveEnvSettings($envKey, $value);
|
$this->saveEnvSettings($envKey, $value);
|
||||||
|
|
@ -249,6 +248,10 @@ class OctoberEnv extends Command
|
||||||
return config('database.default');
|
return config('database.default');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($configKey == 'useConfigForTesting') {
|
||||||
|
return config('database.useConfigForTesting');
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->connection == 'redis') {
|
if ($this->connection == 'redis') {
|
||||||
return config("database.redis.default.$configKey");
|
return config("database.redis.default.$configKey");
|
||||||
}
|
}
|
||||||
|
|
@ -345,6 +348,7 @@ class OctoberEnv extends Command
|
||||||
],
|
],
|
||||||
'database' => [
|
'database' => [
|
||||||
'DB_CONNECTION' => 'default',
|
'DB_CONNECTION' => 'default',
|
||||||
|
'DB_USE_CONFIG_FOR_TESTING' => 'useConfigForTesting',
|
||||||
],
|
],
|
||||||
'cache' => [
|
'cache' => [
|
||||||
'CACHE_DRIVER' => 'default',
|
'CACHE_DRIVER' => 'default',
|
||||||
|
|
@ -402,5 +406,4 @@ class OctoberEnv extends Command
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,25 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase
|
||||||
$app->setLocale('en');
|
$app->setLocale('en');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store database in memory
|
* Store database in memory by default, if not specified otherwise
|
||||||
*/
|
*/
|
||||||
$app['config']->set('database.default', 'sqlite');
|
$dbConnection = 'sqlite';
|
||||||
$app['config']->set('database.connections.sqlite', [
|
|
||||||
|
$dbConnections = [];
|
||||||
|
$dbConnections['sqlite'] = [
|
||||||
'driver' => 'sqlite',
|
'driver' => 'sqlite',
|
||||||
'database' => ':memory:',
|
'database' => ':memory:',
|
||||||
'prefix' => ''
|
'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
|
* Modify the plugin path away from the test context
|
||||||
|
|
@ -53,7 +64,7 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase
|
||||||
*/
|
*/
|
||||||
PluginManager::forgetInstance();
|
PluginManager::forgetInstance();
|
||||||
UpdateManager::forgetInstance();
|
UpdateManager::forgetInstance();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create application instance
|
* Create application instance
|
||||||
*/
|
*/
|
||||||
|
|
@ -109,7 +120,9 @@ abstract class PluginTestCase extends Illuminate\Foundation\Testing\TestCase
|
||||||
protected function runPluginRefreshCommand($code, $throwException = true)
|
protected function runPluginRefreshCommand($code, $throwException = true)
|
||||||
{
|
{
|
||||||
if (!preg_match('/^[\w+]*\.[\w+]*$/', $code)) {
|
if (!preg_match('/^[\w+]*\.[\w+]*$/', $code)) {
|
||||||
if (!$throwException) return;
|
if (!$throwException) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
throw new Exception(sprintf('Invalid plugin code: "%s"', $code));
|
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);
|
$path = array_get($manager->getPluginNamespaces(), $namespace);
|
||||||
|
|
||||||
if (!$path) {
|
if (!$path) {
|
||||||
if (!$throwException) return;
|
if (!$throwException) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
throw new Exception(sprintf('Unable to find plugin with code: "%s"', $code));
|
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)) {
|
if (!empty($plugin->require)) {
|
||||||
foreach ((array) $plugin->require as $dependency) {
|
foreach ((array) $plugin->require as $dependency) {
|
||||||
|
if (isset($this->pluginTestCaseLoadedPlugins[$dependency])) {
|
||||||
if (isset($this->pluginTestCaseLoadedPlugins[$dependency])) continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$this->runPluginRefreshCommand($dependency);
|
$this->runPluginRefreshCommand($dependency);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ Plugin unit tests can be performed by running `phpunit` in the base plugin direc
|
||||||
|
|
||||||
### Creating plugin tests
|
### 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**:
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit backupGlobals="false"
|
<phpunit backupGlobals="false"
|
||||||
|
|
@ -46,13 +46,53 @@ Then a **tests/** directory can be created to contain the test classes. The file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
The test class should extend the base class `PluginTestCase` and this is a special class that will set up the October database stored in memory, as part of the `setUp()` method. It will also refresh the plugin being testing, along with any of the defined dependencies in the plugin registration file. This is the equivalent of running the following before each test:
|
The test class should extend the base class `PluginTestCase` and this is a special class that will set up the October database stored in memory, as part of the `setUp` method. It will also refresh the plugin being tested, along with any of the defined dependencies in the plugin registration file. This is the equivalent of running the following before each test:
|
||||||
|
|
||||||
php artisan october:up
|
php artisan october:up
|
||||||
php artisan plugin:refresh Acme.Blog
|
php artisan plugin:refresh Acme.Blog
|
||||||
[php artisan plugin:refresh <dependency>, ...]
|
[php artisan plugin:refresh <dependency>, ...]
|
||||||
|
|
||||||
# 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
|
### Unit tests
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue