diff --git a/src/Codeception/Module/Db.php b/src/Codeception/Module/Db.php index b78eb721..af5a677c 100644 --- a/src/Codeception/Module/Db.php +++ b/src/Codeception/Module/Db.php @@ -51,8 +51,8 @@ * * user *required* - username to access database * * password *required* - password * * dump - path to database dump - * * populate: false - whether the the dump should be loaded before the test suite is started - * * cleanup: false - whether the dump should be reloaded before each test + * * populate: false - whether the dump should be loaded before the test suite is started + * * repopulate: false - whether the dump should be reloaded before each test * * reconnect: false - whether the module should reconnect to the database before each test * * waitlock: 0 - wait lock (in seconds) that the database session should use for DDL statements * * ssl_key - path to the SSL key (MySQL specific, @see https://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-key) @@ -62,7 +62,8 @@ * * ssl_cipher - list of one or more permissible ciphers to use for SSL encryption (MySQL specific, @see https://php.net/manual/de/ref.pdo-mysql.php#pdo.constants.mysql-attr-cipher) * * databases - include more database configs and switch between them in tests. * * initial_queries - list of queries to be executed right after connection to the database has been initiated, i.e. creating the database if it does not exist or preparing the database collation - * * skip_cleanup_if_failed - Do not perform the cleanup if the tests failed. If this is used, manual cleanup might be required when re-running + * * cleanup: true - whether the rows, inserted during the test with `haveInDatabase()` method, should be cleaned up after the test + * * skip_cleanup_if_failed: false - do not perform the cleanup if the tests failed. If this is used, manual cleanup might be required when re-running * ## Example * * modules: @@ -73,7 +74,7 @@ * password: '' * dump: 'tests/_data/dump.sql' * populate: true - * cleanup: true + * repopulate: true * reconnect: true * waitlock: 10 * skip_cleanup_if_failed: true @@ -82,6 +83,8 @@ * ssl_ca: '/path/to/ca-cert.pem' * ssl_verify_server_cert: false * ssl_cipher: 'AES256-SHA' + * cleanup: true + * skip_cleanup_if_failed: true * initial_queries: * - 'CREATE DATABASE IF NOT EXISTS temp_db;' * - 'USE temp_db;' @@ -141,7 +144,7 @@ * password: '' * dump: 'tests/_data/dump.sql' * populate: true # run populator before all tests - * cleanup: true # run populator before each test + * repopulate: true # run populator before each test * populator: 'mysql -u $user -h $host $dbname < $dump' * ``` * @@ -156,7 +159,7 @@ * password: '' * dump: 'tests/_data/db_backup.dump' * populate: true # run populator before all tests - * cleanup: true # run populator before each test + * repopulate: true # run populator before each test * populator: 'pg_restore -u $user -h $host -D $dbname < $dump' * ``` * @@ -185,7 +188,7 @@ * user: 'root' * password: '' * populate: true # load dump before all tests - * cleanup: true # load dump for each test + * repopulate: true # load dump for each test * dump: 'tests/_data/dump.sql' * ``` * @@ -256,11 +259,12 @@ class Db extends Module implements DbInterface */ protected array $config = [ 'populate' => false, - 'cleanup' => false, + 'repopulate' => false, 'reconnect' => false, 'waitlock' => 0, 'dump' => null, 'populator' => null, + 'cleanup' => true, 'skip_cleanup_if_failed' => false, ]; @@ -300,11 +304,13 @@ protected function getDatabases(): array foreach ($this->config['databases'] as $databaseKey => $databaseConfig) { $databases[$databaseKey] = array_merge([ 'populate' => false, - 'cleanup' => false, + 'repopulate' => false, 'reconnect' => false, 'waitlock' => 0, 'dump' => null, 'populator' => null, + 'cleanup' => true, + 'skip_cleanup_if_failed' => false, ], $databaseConfig); } } @@ -319,10 +325,10 @@ protected function connectToDatabases(): void } } - protected function cleanUpDatabases(): void + protected function cleanUpSchemaForDatabases(): void { foreach ($this->getDatabases() as $databaseKey => $databaseConfig) { - $this->_cleanup($databaseKey, $databaseConfig); + $this->_cleanUpSchema($databaseKey, $databaseConfig); } } @@ -350,11 +356,13 @@ protected function readSqlForDatabases(): void } } - protected function removeInsertedForDatabases(): void + protected function cleanUpInsertedForDatabases(): void { - foreach (array_keys($this->getDatabases()) as $databaseKey) { - $this->amConnectedToDatabase($databaseKey); - $this->removeInserted($databaseKey); + foreach ($this->getDatabases() as $databaseKey => $databaseConfig) { + if ($databaseConfig['cleanup']) { + $this->amConnectedToDatabase($databaseKey); + $this->cleanUpInserted($databaseKey); + } } } @@ -494,7 +502,7 @@ public function _beforeSuite($settings = []): void { $this->readSqlForDatabases(); $this->connectToDatabases(); - $this->cleanUpDatabases(); + $this->cleanUpSchemaForDatabases(); $this->populateDatabases('populate'); } @@ -504,7 +512,7 @@ private function readSql($databaseKey = null, $databaseConfig = null): void return; } - if (!$databaseConfig['cleanup'] && !$databaseConfig['populate']) { + if (!$databaseConfig['repopulate'] && !$databaseConfig['populate']) { return; } @@ -643,9 +651,9 @@ public function _before(TestInterface $test): void $this->reconnectDatabases(); $this->amConnectedToDatabase(self::DEFAULT_DATABASE); - $this->cleanUpDatabases(); + $this->cleanUpSchemaForDatabases(); - $this->populateDatabases('cleanup'); + $this->populateDatabases('repopulate'); parent::_before($test); } @@ -653,7 +661,7 @@ public function _before(TestInterface $test): void public function _failed(TestInterface $test, $fail) { foreach ($this->getDatabases() as $databaseKey => $databaseConfig) { - if ($databaseConfig['skip_cleanup_if_failed'] ?? false) { + if ($databaseConfig['skip_cleanup_if_failed']) { $this->insertedRows[$databaseKey] = []; } } @@ -661,11 +669,11 @@ public function _failed(TestInterface $test, $fail) public function _after(TestInterface $test): void { - $this->removeInsertedForDatabases(); + $this->cleanUpInsertedForDatabases(); parent::_after($test); } - protected function removeInserted($databaseKey = null): void + protected function cleanUpInserted($databaseKey = null): void { $databaseKey = empty($databaseKey) ? self::DEFAULT_DATABASE : $databaseKey; @@ -684,7 +692,7 @@ protected function removeInserted($databaseKey = null): void $this->insertedRows[$databaseKey] = []; } - public function _cleanup(?string $databaseKey = null, ?array $databaseConfig = null): void + public function _cleanUpSchema(?string $databaseKey = null, ?array $databaseConfig = null): void { $databaseKey = empty($databaseKey) ? self::DEFAULT_DATABASE : $databaseKey; $databaseConfig = empty($databaseConfig) ? $this->config : $databaseConfig; @@ -693,7 +701,7 @@ public function _cleanup(?string $databaseKey = null, ?array $databaseConfig = n return; } - if (!$databaseConfig['cleanup']) { + if (!$databaseConfig['repopulate']) { return; } @@ -710,7 +718,7 @@ public function _cleanup(?string $databaseKey = null, ?array $databaseConfig = n } try { - if (!$this->shouldCleanup($databaseConfig, $databaseKey)) { + if (!$this->shouldCleanupSchema($databaseConfig, $databaseKey)) { return; } @@ -721,7 +729,7 @@ public function _cleanup(?string $databaseKey = null, ?array $databaseConfig = n } } - protected function shouldCleanup(array $databaseConfig, string $databaseKey): bool + protected function shouldCleanupSchema(array $databaseConfig, string $databaseKey): bool { // If using populator and it's not empty, clean up regardless if (!empty($databaseConfig['populator'])) { @@ -773,7 +781,7 @@ protected function loadDumpUsingDriver(string $databaseKey): void /** * Inserts an SQL record into a database. This record will be erased after the test, - * unless you've configured "skip_cleanup_if_failed", and the test fails. + * unless you've configured "cleanup" to false, or "skip_cleanup_if_failed" to true and the test fails. * * ```php * module->dontSeeInDatabase('empty_table'); } - public function testCleanupDatabase() + public function testCleanupSchema() { $this->module->seeInDatabase('users', ['name' => 'davert']); - $this->module->_cleanup(); + $this->module->_cleanUpSchema(); // Since table does not exist it should fail // TODO: Catch this exception at the driver level and re-throw a general one @@ -140,6 +140,34 @@ public function testCleanupDatabase() $this->module->dontSeeInDatabase('users', ['name' => 'davert']); } + public function testCleanupInserted() + { + $this->module->haveInDatabase('users', ['name' => 'john']); + + $this->module->_after(Stub::makeEmpty(TestInterface::class)); + + $this->module->dontSeeInDatabase('users', ['name' => 'john']); + } + + public function testDoesNotCleanupInserted() + { + $this->module->haveInDatabase('users', ['name' => 'john']); + $this->module->_reconfigure(['cleanup' => false]); + + $this->module->_after(Stub::makeEmpty(TestInterface::class)); + + $this->module->seeInDatabase('users', ['name' => 'john']); + } + + public function testSkipCleanupIfFailed() + { + $this->module->haveInDatabase('users', ['name' => 'john']); + + $this->module->_failed(Stub::makeEmpty(TestInterface::class), new Exception('test')); + + $this->module->seeInDatabase('users', ['name' => 'john']); + } + public function testHaveAndSeeInDatabase() { $userId = $this->module->haveInDatabase('users', ['name' => 'john', 'email' => 'john@jon.com']); @@ -163,7 +191,7 @@ public function testHaveInDatabaseWithCompositePrimaryKey() $testData = ['id' => 2, 'group_id' => 2, 'status' => 'test3']; $this->module->haveInDatabase('composite_pk', $testData); $this->module->seeInDatabase('composite_pk', $testData); - $this->module->_reconfigure(['cleanup' => false]); + $this->module->_reconfigure(['repopulate' => false]); $this->module->_after(Stub::makeEmpty(TestInterface::class)); $this->module->_before(Stub::makeEmpty(TestInterface::class)); @@ -201,7 +229,7 @@ public function testGrabNumRecords() public function testLoadWithPopulator() { - $this->module->_cleanup(); + $this->module->_cleanUpSchema(); $this->assertFalse($this->module->_isPopulated()); try { $this->module->seeInDatabase('users', ['name' => 'davert']); @@ -213,7 +241,7 @@ public function testLoadWithPopulator() [ 'populate' => true, 'populator' => $this->getPopulator(), - 'cleanup' => true, + 'repopulate' => true, ] ); $this->module->_loadDump(null, $this->getConfig()); @@ -239,7 +267,7 @@ public function testInsertInDatabase() $testData = ['status' => 'test']; $this->module->_insertInDatabase('no_pk', $testData); $this->module->seeInDatabase('no_pk', $testData); - $this->module->_reconfigure(['cleanup' => false]); + $this->module->_reconfigure(['repopulate' => false]); $this->module->_after(Stub::makeEmpty(TestInterface::class)); $this->module->_before(Stub::makeEmpty(TestInterface::class)); diff --git a/tests/unit/Codeception/Module/Db/MssqlDblibDbTest.php b/tests/unit/Codeception/Module/Db/MssqlDblibDbTest.php index 5b4a4ccd..a79c4cd2 100644 --- a/tests/unit/Codeception/Module/Db/MssqlDblibDbTest.php +++ b/tests/unit/Codeception/Module/Db/MssqlDblibDbTest.php @@ -25,7 +25,7 @@ public function getConfig(): array 'password' => $password, 'dump' => 'tests/data/dumps/mssql.sql', 'reconnect' => true, - 'cleanup' => true, + 'repopulate' => true, 'populate' => true, ]; } diff --git a/tests/unit/Codeception/Module/Db/MssqlSqlSrvDbTest.php b/tests/unit/Codeception/Module/Db/MssqlSqlSrvDbTest.php index b54641e8..11fd5bce 100644 --- a/tests/unit/Codeception/Module/Db/MssqlSqlSrvDbTest.php +++ b/tests/unit/Codeception/Module/Db/MssqlSqlSrvDbTest.php @@ -25,7 +25,7 @@ public function getConfig(): array 'password' => $password, 'dump' => 'tests/data/dumps/mssql.sql', 'reconnect' => true, - 'cleanup' => true, + 'repopulate' => true, 'populate' => true, ]; } diff --git a/tests/unit/Codeception/Module/Db/MySqlDbTest.php b/tests/unit/Codeception/Module/Db/MySqlDbTest.php index 8bc10015..76b8dafd 100644 --- a/tests/unit/Codeception/Module/Db/MySqlDbTest.php +++ b/tests/unit/Codeception/Module/Db/MySqlDbTest.php @@ -28,7 +28,7 @@ public function getConfig(): array 'password' => $password, 'dump' => 'tests/data/dumps/mysql.sql', 'reconnect' => true, - 'cleanup' => true, + 'repopulate' => true, 'populate' => true ]; } diff --git a/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php b/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php index 0f2c4900..9c65819c 100644 --- a/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php +++ b/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php @@ -29,7 +29,7 @@ public function getConfig(): array 'password' => $password, 'dump' => 'tests/data/dumps/postgres.sql', 'reconnect' => true, - 'cleanup' => true, + 'repopulate' => true, 'populate' => true ]; } diff --git a/tests/unit/Codeception/Module/Db/SqliteDbTest.php b/tests/unit/Codeception/Module/Db/SqliteDbTest.php index cdbeb97d..a0aee2a3 100644 --- a/tests/unit/Codeception/Module/Db/SqliteDbTest.php +++ b/tests/unit/Codeception/Module/Db/SqliteDbTest.php @@ -23,7 +23,7 @@ public function getConfig(): array 'password' => '', 'dump' => 'tests/data/dumps/sqlite.sql', 'reconnect' => true, - 'cleanup' => true, + 'repopulate' => true, 'populate' => true ]; } @@ -65,7 +65,7 @@ public function testMultiDatabase() { $config = array_merge($this->getConfig(), [ 'dsn' => 'sqlite:tests/data/sqlite1.db', - 'cleanup' => false + 'repopulate' => false ]); $this->module->_reconfigure( [ @@ -92,7 +92,7 @@ public function testDatabaseIsAlwaysDefaultBeforeTest() $config = array_merge($this->getConfig(), ['dsn' => 'sqlite:tests/data/sqlite1.db']); $this->module->_reconfigure( [ - 'cleanup' => false, + 'repopulate' => false, 'databases' => ['db2' => $config], ] ); @@ -124,7 +124,7 @@ public function testMultiDatabaseWithArray() { $config = array_merge($this->getConfig(), [ 'dsn' => 'sqlite:tests/data/sqlite1.db', - 'cleanup' => false + 'repopulate' => false ]); $this->module->_reconfigure( [ @@ -149,7 +149,7 @@ public function testMultiDatabaseWithActionSequence() { $config = array_merge($this->getConfig(), [ 'dsn' => 'sqlite:tests/data/sqlite1.db', - 'cleanup' => false + 'repopulate' => false ]); $this->module->_reconfigure( [ @@ -176,7 +176,7 @@ public function testMultiDatabaseWithAnonymousFunction() { $config = array_merge($this->getConfig(), [ 'dsn' => 'sqlite:tests/data/sqlite1.db', - 'cleanup' => false + 'repopulate' => false ]); $this->module->_reconfigure( [ @@ -209,7 +209,7 @@ public function testMultiDatabaseWithRemoveInserted() $testCase2 = Stub::makeEmpty(TestInterface::class); $config = array_merge($this->getConfig(), [ 'dsn' => 'sqlite:tests/data/sqlite1.db', - 'cleanup' => false + 'repopulate' => false ]); $this->module->_reconfigure( [