imatic/testing

Library to make testing of Symfony bundles easier

v6.0.4 2023-03-27 14:01 UTC

README

Build Status

License: MIT

Testing

This library makes it easy to setup tests including testing project for reusable bundles. It will create all required files so that you can start writing your tests and visualise components of your bundle without necessity of including it into some application (as this library creates such application in testing namespace of your bundle).

Content

Initialize testing project

  • Add phpunit.xml.dist to your repository to configure phpunit
  • Set KERNEL_DIR server variable so that phpunit finds symfony kernel (example value nees to be modified based on bundle name)

xml

<!-- phpunit.xml.dist --> <phpunit> <php> <server name="KERNEL_DIR" value="ImaticBundleTestsTemplateBundleTestsFixturesTestProjectTestKernel"/> </php> </phpunit>

  • Add imatic-testing into your dev dependencies

bash

$ composer require --dev 'imatic/testing'

  • Create required files in your bundle

bash

$ ./vendor/bin/testingbundle-init

  • Command above should create directory structure similar to

text

Tests
Fixtures
TestProject
config

config.yml routing.yml

XYZBundle (same name as tested bundle)

AppXYZBundle.php

web

app.php

console TestKernel.php WebTestCase.php

Functional Integration Unit bootstrap.php

  • Directory structure above is created based on template in TestsTemplate directory

PHPUnit

Additional constraints

All additinal constraints usable in symfony functional tests are included in our WebTestCase automatically. If you have your own WebTestCase implementation, you can use our trait WebTestCaseExtension to include our additional constraints in your WebTestCase.

ResponseHasCode

This constraint can be used to assert status codes in symfony functional tests. Usage:

php

<?php

use ImaticTestingTestWebTestCase;

class ExampleTestCase extends WebTestCase { public function testHomepageReturnsOk() { $client = static::createClient(); $client->request('GET', '/');

$this->assertResponseHasCode(200, $client->getResponse());

}

}

  • advantage in comparison with asserting 200 with $client->getResponse()->getStatusCode() is that the special assert gives you information about what went wrong instead of giving you just wrong code of the response (e.g. 500)

Usage

Now if you have all configured, you can start writing tests or check your testing project in browser. In order to check your testing project in browser.

Checking your testing project in browser

  • go to the testing project root and run web server

Using PHP's bult-in web server

bash

$ cd Tests/Fixtures/TestProject/ $ ./console server:run --docroot=web

  • now open your browser at url reported by the last command (probably "http://127.0.0.1:8000/app.php")
  • you will see exception now probably because you didn't configure any routes for your project yet
  • you can find more details on the command in symfony documentation

Using other web servers

Using symfony console

  • as you may or may not notice when we talked about testing project directory structure, you have also available symfony console - so that you can run all commands that your bundle or bundles your testing project uses provide
  • see symfony documentation on how to work with console command (note that in our case, the executable running console is called console and is placed in root of the testing project

Writing tests working with database

  • if you use our WebTestCase as parent of your tests, then each test will run in transaction so all your modifications to db are lost (so you have db in state before the test run)
  • see commented test below on how it works

php

<?php

namespace ImaticBundleDataBundleTestsIntegrationDataCommand;

use DoctrineORMEntityManager; use DoctrineORMEntityRepository; use ImaticBundleDataBundleDataCommandCommand; use ImaticBundleDataBundleDataCommandCommandExecutor; use ImaticBundleDataBundleTestsFixturesTestProjectImaticDataBundleEntityUser; use ImaticBundleDataBundleTestsFixturesTestProjectWebTestCase;

// this is our test class wich extends WebTestCase which ensures // that each test runs in the same environment (has predictable db state) class CommandExecutorTest extends WebTestCase { public function testGivenCommandShouldBeSuccessfullyExecuted() { /* @var $user User */ $user = $this->getUserRepository()->findOneByName('Adam');

// here we make sure that the user is not activated // so that we can test activating functionality $this->assertTrue($user->isActivated());

$command = new Command('user.deactivate', ['id' => $user->getId()]); // here we execute command which activates the user // and stores the information into database $result = $this->getCommandExecutor()->execute($command); $this->assertTrue($result->isSuccessful());

// here we check that user was activated $this->assertFalse($user->isActivated());

// after this test finishes, user is deactivated because the transaction // is rollbacked

}

/**

* @return EntityRepository */

public function getUserRepository() { return $this->getEntityManager()->getRepository('AppImaticDataBundle:User'); }

/**

* @return EntityManager */

public function getEntityManager() { return $this->container->get('doctrine.orm.entity_manager'); }

/**

* @return CommandExecutor */

private function getCommandExecutor() { return $this->container->get('imatic_data.command_executor'); }

}

  • note that because of doctrine connection wrapper we use - you can write symfony funcional tests and after each test, transaction will still be rollbacked (which is not possible without using the wrapper

yaml

doctrine:
dbal:
connections:
default:

wrapper_class: "Imatic\Testing\Doctrine\DBAL\PersistedConnection"

  • if you want to load any fixtures, you need to require DoctrineFixturesBundle and specify any fixture. Our WebTestCase load fixtures automatically when DoctrineFixturesBundle is enabled.
  • before running tests database and fixtures is reloaded, if you want to disable this behavior, change env variable TESTING_DATA_INIT in your test configuration

xml

<!-- phpunit.xml.dist --> <phpunit> <php> <env name="TESTING_DATA_INIT" value="0" /> </php> </phpunit>

Testing project configuration

  • if you need to make changes to the configuration, just edit generated config file which you can find in config/config.yml (relative to the testing project roor)