From aba4f86abaa539e9f03ec9b74bfa397debe8a724 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Fri, 18 Sep 2020 15:57:27 +0200 Subject: [PATCH 1/3] Added Behat integration --- README.md | 65 ++++++------------- composer.json | 4 ++ .../Behat/BehatListener.php | 44 +++++++++++++ .../ServiceContainer/DoctrineExtension.php | 37 +++++++++++ 4 files changed, 105 insertions(+), 45 deletions(-) create mode 100644 src/DAMA/DoctrineTestBundle/Behat/BehatListener.php create mode 100644 src/DAMA/DoctrineTestBundle/Behat/ServiceContainer/DoctrineExtension.php diff --git a/README.md b/README.md index a1fe9fa..cae1212 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ It also includes a `StaticArrayCache` that will be automatically configured as m Note: if you are using symfony flex and you are allowing contrib recipes (`extra.symfony.allow-contrib=true`) then the bundle will be automatically enabled for the `'test'` environment. See https://github.com/symfony/recipes-contrib/tree/master/dama/doctrine-test-bundle -3. For PHPUnit version >= 7.5 add the extension in your xml config (e.g. `app/phpunit.xml`) +#### Using the Bundle with PHPUnit + +1. For PHPUnit version >= 7.5 add the extension in your xml config (e.g. `app/phpunit.xml`) ```xml @@ -59,11 +61,26 @@ It also includes a `StaticArrayCache` that will be automatically configured as m ``` -4. Make sure you also have `phpunit/phpunit` available as a `dev` dependency (**versions 7, 8 and 9 are supported with the built in listener/extension**) to run your tests. +2. Make sure you also have `phpunit/phpunit` available as a `dev` dependency (**versions 7, 8 and 9 are supported with the built in listener/extension**) to run your tests. Alternatively this bundle is also compatible with `symfony/phpunit-bridge` and its `simple-phpunit` script. (Note: you may need to make sure the phpunit-bridge requires the correct PHPUnit 7+ Version using the environment variable `SYMFONY_PHPUNIT_VERSION`). -5. That's it! From now on whatever changes you do to the database within each single testcase (be it a `WebTestCase` or a `KernelTestCase` or any custom test) are automatically rolled back for you :blush: +3. That's it! From now on whatever changes you do to the database within each single testcase (be it a `WebTestCase` or a `KernelTestCase` or any custom test) are automatically rolled back for you :blush: + +#### Using the Bundle with Behat + +Enable the extension in your Behat config (e.g. `behat.yml`) + +```yaml +default: + # ... + extensions: + DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension: ~ +``` + +That's it! From now on whatever changes you do to the database within each scenario are automatically rolled back for you. + +Please note that this is only works if the tests are executed in the same process as Behat. This means it cannot work when using e.g. Selenium to call your application. ### Configuration @@ -109,48 +126,6 @@ public function testMyTestCaseThatINeedToDebug() } ``` -### Behat - -It is possible to use this bundle in a Behat test suite if scenarios are executed in the same process as Behat. This will not work if the Behat tests invoke the application via HTTP requests. - -To use the bundle follow the installation instructions and add the following methods to your `FeatureContext` class: - -```php - /** - * @BeforeSuite - */ - public static function beforeSuite() - { - StaticDriver::setKeepStaticConnections(true); - } - - /** - * @BeforeScenario - */ - public function beforeScenario() - { - StaticDriver::beginTransaction(); - } - - /** - * @AfterScenario - */ - public function afterScenario() - { - StaticDriver::rollBack(); - } - - /** - * @AfterSuite - */ - public static function afterSuite() - { - StaticDriver::setKeepStaticConnections(false); - } -``` - -See [dmaicher/symfony-flex-behat-test](https://github.com/dmaicher/symfony-flex-behat-test) for a complete example. - ### Troubleshooting In case you are running (maybe without knowing it) queries during your tests that are implicitly committing any open transaction diff --git a/composer.json b/composer.json index c12d2d8..625e3ad 100644 --- a/composer.json +++ b/composer.json @@ -17,11 +17,15 @@ "doctrine/doctrine-bundle": "^1.11 || ^2.0" }, "require-dev": { + "behat/behat": "^3.0", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "symfony/yaml": "^3.4 || ^4.4 || ^5.1", "symfony/phpunit-bridge": "^5.1", "phpstan/phpstan": "^0.12" }, + "conflict": { + "behat/behat": "<3.0" + }, "autoload": { "psr-4": { "DAMA\\DoctrineTestBundle\\": "src/DAMA/DoctrineTestBundle" diff --git a/src/DAMA/DoctrineTestBundle/Behat/BehatListener.php b/src/DAMA/DoctrineTestBundle/Behat/BehatListener.php new file mode 100644 index 0000000..e54d14b --- /dev/null +++ b/src/DAMA/DoctrineTestBundle/Behat/BehatListener.php @@ -0,0 +1,44 @@ + 'enableStaticConnection', + ExerciseCompleted::AFTER => 'disableStaticConnection', + ScenarioTested::BEFORE => ['beginTransaction', 255], + ExampleTested::BEFORE => ['beginTransaction', 255], + ScenarioTested::AFTER => ['rollBack', -255], + ExampleTested::AFTER => ['rollBack', -255], + ]; + } + + public function enableStaticConnection(): void + { + StaticDriver::setKeepStaticConnections(true); + } + + public function disableStaticConnection(): void + { + StaticDriver::setKeepStaticConnections(false); + } + + public function beginTransaction(): void + { + StaticDriver::beginTransaction(); + } + + public function rollBack(): void + { + StaticDriver::rollBack(); + } +} diff --git a/src/DAMA/DoctrineTestBundle/Behat/ServiceContainer/DoctrineExtension.php b/src/DAMA/DoctrineTestBundle/Behat/ServiceContainer/DoctrineExtension.php new file mode 100644 index 0000000..8cc409f --- /dev/null +++ b/src/DAMA/DoctrineTestBundle/Behat/ServiceContainer/DoctrineExtension.php @@ -0,0 +1,37 @@ +register('dama_doctrine_test.listener', BehatListener::class) + ->addTag(EventDispatcherExtension::SUBSCRIBER_TAG) + ; + } + + public function process(ContainerBuilder $container): void + { + } +} From 46fb3052b1ef0d9ddf60a7b5c01f1edf3e54af1e Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 4 Oct 2020 16:25:48 +0200 Subject: [PATCH 2/3] Added Behat tests --- .travis.yml | 3 +- composer.json | 4 +- tests/Functional/FunctionalTestTrait.php | 98 +++++++++++++++++++ .../{FunctionalTest.php => PhpunitTest.php} | 59 ++++------- tests/Functional/{ => app}/AppKernel.php | 2 +- tests/Functional/{ => app}/config.yml | 0 .../parameters.yml} | 0 tests/Functional/app/parameters.yml.dist | 5 + .../features/behat_integration.feature | 31 ++++++ .../features/bootstrap/FeatureContext.php | 22 +++++ tests/behat.yml | 10 ++ .../{phpunit.bootstrap.php => bootstrap.php} | 2 +- tests/phpunit.xml | 2 +- tests/phpunit7.xml | 2 +- 14 files changed, 190 insertions(+), 50 deletions(-) create mode 100644 tests/Functional/FunctionalTestTrait.php rename tests/Functional/{FunctionalTest.php => PhpunitTest.php} (59%) rename tests/Functional/{ => app}/AppKernel.php (94%) rename tests/Functional/{ => app}/config.yml (100%) rename tests/Functional/{parameters.yml.dist => app/parameters.yml} (100%) create mode 100644 tests/Functional/app/parameters.yml.dist create mode 100644 tests/Functional/features/behat_integration.feature create mode 100644 tests/Functional/features/bootstrap/FeatureContext.php create mode 100644 tests/behat.yml rename tests/{phpunit.bootstrap.php => bootstrap.php} (92%) diff --git a/.travis.yml b/.travis.yml index 17f03db..8da86ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,7 +46,7 @@ install: - composer require phpunit/phpunit:${PHPUNIT_VERSION:-"8.*"} --update-with-all-dependencies script: - - cp tests/Functional/parameters.yml.dist tests/Functional/parameters.yml + - cp tests/Functional/app/parameters.yml.dist tests/Functional/app/parameters.yml - rm -rf tests/Functional/cache - if [[ ${SKIP_CS_FIXER} != "1" ]]; then make php_cs_fixer_check; fi - make phpstan @@ -55,6 +55,7 @@ script: elif [[ ${PHPUNIT_VERSION} == "7.*" ]]; then vendor/bin/phpunit -c tests/phpunit7.xml tests/; else vendor/bin/phpunit -c tests/ tests/; fi + - vendor/bin/behat -c tests/behat.yml -fprogress after_success: - if [[ ${TEST_COVERAGE} ]]; then wget https://scrutinizer-ci.com/ocular.phar; fi diff --git a/composer.json b/composer.json index 625e3ad..f0391eb 100644 --- a/composer.json +++ b/composer.json @@ -21,11 +21,9 @@ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "symfony/yaml": "^3.4 || ^4.4 || ^5.1", "symfony/phpunit-bridge": "^5.1", + "symfony/process": "^3.4 || ^4.3 || ^5.1", "phpstan/phpstan": "^0.12" }, - "conflict": { - "behat/behat": "<3.0" - }, "autoload": { "psr-4": { "DAMA\\DoctrineTestBundle\\": "src/DAMA/DoctrineTestBundle" diff --git a/tests/Functional/FunctionalTestTrait.php b/tests/Functional/FunctionalTestTrait.php new file mode 100644 index 0000000..9016867 --- /dev/null +++ b/tests/Functional/FunctionalTestTrait.php @@ -0,0 +1,98 @@ +kernel = new AppKernel('test', true); + $this->kernel->boot(); + $this->connection = $this->kernel->getContainer()->get('doctrine.dbal.default_connection'); + } + + /** + * @AfterScenario + */ + public function tearDown(): void + { + $this->kernel->shutdown(); + } + + /** + * @Then there are :count rows + * @Then there is :count row + */ + public function assertRowCount($count): void + { + Assert::assertEquals($count, $this->connection->fetchColumn('SELECT COUNT(*) FROM test')); + } + + /** + * @When I insert a new row + */ + public function insertRow(): void + { + $this->connection->insert('test', [ + 'test' => 'foo', + ]); + } + + /** + * @When I begin a transaction + */ + public function beginTransaction(): void + { + $this->connection->beginTransaction(); + } + + /** + * @When I rollback the transaction + */ + public function rollbackTransaction(): void + { + $this->connection->rollBack(); + } + + /** + * @When I commit the transaction + */ + public function commitTransaction(): void + { + $this->connection->commit(); + } + + /** + * @When I create a savepoint named :name + */ + public function createSavepoint(string $name): void + { + $this->connection->createSavepoint($name); + } + + /** + * @When I rollback the savepoint named :name + */ + public function rollbackSavepoint(string $name): void + { + $this->connection->rollbackSavepoint($name); + } +} diff --git a/tests/Functional/FunctionalTest.php b/tests/Functional/PhpunitTest.php similarity index 59% rename from tests/Functional/FunctionalTest.php rename to tests/Functional/PhpunitTest.php index 881193c..009f7bf 100644 --- a/tests/Functional/FunctionalTest.php +++ b/tests/Functional/PhpunitTest.php @@ -2,46 +2,12 @@ namespace Tests\Functional; -use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception\TableNotFoundException; use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpKernel\KernelInterface; -class FunctionalTest extends TestCase +class PhpunitTest extends TestCase { - /** - * @var KernelInterface - */ - private $kernel; - - /** - * @var Connection - */ - private $connection; - - protected function setUp(): void - { - $this->kernel = new AppKernel('test', true); - $this->kernel->boot(); - $this->connection = $this->kernel->getContainer()->get('doctrine.dbal.default_connection'); - } - - protected function tearDown(): void - { - $this->kernel->shutdown(); - } - - private function assertRowCount($count): void - { - $this->assertEquals($count, $this->connection->fetchColumn('SELECT COUNT(*) FROM test')); - } - - private function insertRow(): void - { - $this->connection->insert('test', [ - 'test' => 'foo', - ]); - } + use FunctionalTestTrait; public function testChangeDbState(): void { @@ -50,6 +16,9 @@ public function testChangeDbState(): void $this->assertRowCount(1); } + /** + * @depends testChangeDbState + */ public function testPreviousChangesAreRolledBack(): void { $this->assertRowCount(0); @@ -59,18 +28,21 @@ public function testChangeDbStateWithinTransaction(): void { $this->assertRowCount(0); - $this->connection->beginTransaction(); + $this->beginTransaction(); $this->insertRow(); $this->assertRowCount(1); - $this->connection->rollBack(); + $this->rollbackTransaction(); $this->assertRowCount(0); - $this->connection->beginTransaction(); + $this->beginTransaction(); $this->insertRow(); - $this->connection->commit(); + $this->commitTransaction(); $this->assertRowCount(1); } + /** + * @depends testChangeDbStateWithinTransaction + */ public function testPreviousChangesAreRolledBackAfterTransaction(): void { $this->assertRowCount(0); @@ -79,14 +51,17 @@ public function testPreviousChangesAreRolledBackAfterTransaction(): void public function testChangeDbStateWithSavePoint(): void { $this->assertRowCount(0); - $this->connection->createSavepoint('foo'); + $this->createSavepoint('foo'); $this->insertRow(); $this->assertRowCount(1); - $this->connection->rollbackSavepoint('foo'); + $this->rollbackSavepoint('foo'); $this->assertRowCount(0); $this->insertRow(); } + /** + * @depends testChangeDbStateWithSavePoint + */ public function testPreviousChangesAreRolledBackAfterUsingSavePoint(): void { $this->assertRowCount(0); diff --git a/tests/Functional/AppKernel.php b/tests/Functional/app/AppKernel.php similarity index 94% rename from tests/Functional/AppKernel.php rename to tests/Functional/app/AppKernel.php index b893515..b003b83 100644 --- a/tests/Functional/AppKernel.php +++ b/tests/Functional/app/AppKernel.php @@ -1,6 +1,6 @@ find(false); + + (new Process([$php, __DIR__.'/../../../bootstrap.php']))->mustRun(); + } +} diff --git a/tests/behat.yml b/tests/behat.yml new file mode 100644 index 0000000..28039e1 --- /dev/null +++ b/tests/behat.yml @@ -0,0 +1,10 @@ +default: + autoload: + '': '%paths.base%/Functional/features/bootstrap' + + suites: + functional: + paths: ['%paths.base%/Functional/features'] + + extensions: + DAMA\DoctrineTestBundle\Behat\ServiceContainer\DoctrineExtension: ~ diff --git a/tests/phpunit.bootstrap.php b/tests/bootstrap.php similarity index 92% rename from tests/phpunit.bootstrap.php rename to tests/bootstrap.php index fab2210..c508a43 100644 --- a/tests/phpunit.bootstrap.php +++ b/tests/bootstrap.php @@ -4,7 +4,7 @@ function bootstrap(): void { - $kernel = new \Tests\Functional\AppKernel('test', true); + $kernel = new \Tests\Functional\app\AppKernel('test', true); $kernel->boot(); $application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel); diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 8c3bd5e..068d46e 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -9,7 +9,7 @@ convertWarningsToExceptions="true" processIsolation="false" stderr="true" - bootstrap="./phpunit.bootstrap.php" + bootstrap="./bootstrap.php" > diff --git a/tests/phpunit7.xml b/tests/phpunit7.xml index ce4c33f..1c748ae 100644 --- a/tests/phpunit7.xml +++ b/tests/phpunit7.xml @@ -9,7 +9,7 @@ convertWarningsToExceptions="true" processIsolation="false" stderr="true" - bootstrap="./phpunit.bootstrap.php" + bootstrap="./bootstrap.php" > From 2abba1032117bfe76a76480dbbd65b06932f30f6 Mon Sep 17 00:00:00 2001 From: David Maicher Date: Fri, 30 Oct 2020 11:01:36 +0100 Subject: [PATCH 3/3] don't support Symfony 4.3 anymore --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f0391eb..e5b313e 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "symfony/yaml": "^3.4 || ^4.4 || ^5.1", "symfony/phpunit-bridge": "^5.1", - "symfony/process": "^3.4 || ^4.3 || ^5.1", + "symfony/process": "^3.4 || ^4.4 || ^5.1", "phpstan/phpstan": "^0.12" }, "autoload": {