tbaronnat / functional-test-bundle
Simple functional test bundle system with Symfony integration
v1.0.10
2024-03-18 11:08 UTC
Requires
- php: >=8.1
- ext-dom: *
- fakerphp/faker: ^1.5
- symfony/console: ^6.0|^7.0
- symfony/dependency-injection: ^6.0|^7.0
- symfony/framework-bundle: ^6.0|^7.0
- symfony/security-bundle: ^6.0|^7.0
Requires (Dev)
- phpunit/phpunit: ^9.5
- symfony/test-pack: ^1.1
README
Definition
This bundle calls all routes defined in configuration.
It tests actions "delete", "create", "update" and "index" for this routes.
- "index" action will go to the defined route, and check if is accessible.
- "create" action will fill form type with valid values, and submit the form to your route, and check if all is successful.
- "update" action will update existing form type with valid value, and submit the form to your route, and check if all is successful.
- "delete" action call your DELETE route, un check if all is successful.
How to use
1. Create a controller class int "tests" directory, which extends from AbstractControllerTest
2. Example configuration to test
tbaronnat_functional_test:
configs:
conf_admin:
userRepository: 'app.repository.admin_user'
firewall: 'admin'
userId: 1
conf_user:
userRepository: 'app.repository.user'
firewall: 'main'
userId: 1
options: #Any additional options that you want
option1: 'value1'
option2: 'value2'
params:
dashboard:
config: 'conf_user'
action: 'index'
controller: 'App/Controller/DefaultControllerTest' #The controller used to execute test
method: 'GET'
route: 'dashboard'
finalRoute: 'dashboard'
locale: 'fr_FR' #Used for example in form fill generator for phone number in selected country locale (default: en_US)
options: #Any additional options that you want
option1: 'value1'
option2: 'value2'
admin_dashboard:
config: 'conf_admin'
action: 'index'
controller: 'App/Controller/DefaultControllerTest'
method: 'GET'
route: 'admin_dashboard'
finalRoute: 'admin_dashboard'
admin_user_index:
config: 'conf_admin'
action: 'index'
controller: 'App/Controller/DefaultControllerTest'
method: 'GET'
route: 'admin_user_index'
finalRoute: 'admin_user_index'
admin_user_update:
config: 'conf_admin'
action: 'update'
controller: 'App/Controller/DefaultControllerTest'
method: 'POST'
route: 'admin_user_update'
routeParams:
id: 1
finalRoute: 'admin_user_update'
finalRouteParams:
id: 1
admin_user_delete:
config: 'conf_admin'
action: 'delete'
controller: 'App/Controller/DefaultControllerTest'
method: 'DELETE'
route: 'admin_user_delete'
routeParams:
id: 1
finalRoute: 'admin_user_index'
csrfProtection: false #important if you want that your "DELETE" tests works, disable csrf protections for forms
admin_user_create:
config: 'conf_admin'
action: 'create'
controller: 'App/Controller/DefaultControllerTest'
method: 'POST'
route: 'admin_user_create'
finalRoute: 'admin_user_index'
followRedirects: true
3. Add options to your configuration to override some logic
In your test controller, add some logic and replace params for method makeRequest to retrieve existing object on DB and replace "id" with dynamic value.
Like this, you can don"t specify the id of object you wants to test
For example (I create RouteParamsTestRepositoryTrait for that if you want to use it):
// Test configuration in tbaronnat_functional_test.yaml
// for route params "id" or "userId", put any value
config:
userRepository: 'app.repository.user'
firewall: 'main'
userId: 0
options:
repositoryMethod: 'findOneEnabledUser'
params:
admin_user_update:
config: 'conf_admin'
action: 'update'
controller: 'App/Controller/DefaultControllerTest'
method: 'POST'
route: 'admin_user_update'
routeParams:
id: '-'
finalRoute: 'admin_user_update'
finalRouteParams:
id: '-'
options:
repository: 'admin.repository.user'
admin_user_delete:
config: 'conf_admin'
action: 'delete'
controller: 'App/Controller/DefaultControllerTest'
method: 'DELETE'
route: 'admin_user_delete'
routeParams:
id: 1
finalRoute: 'admin_user_index'
csrfProtection: false
options:
repository: 'admin.repository.user'
repositoryMethod: 'findOneEnabledUser'
// ControllerTest:
use TBaronnat\FunctionalTestBundle\Traits\RouteParamsTestRepositoryTrait;
use TBaronnat\FunctionalTestBundle\Traits\UserConfigTestRepositoryTrait;
class DefaultControllerTest extends AbstractControllerTest
{
use RouteParamsTestRepositoryTrait;
use UserConfigTestRepositoryTrait;
protected function getTestParams(string $name, array $params): TestParamsInterface
{
$parameters = parent::getTestParams($name, $params);
$this->replaceIdRouteParams($parameters, 'id');
return $parameters;
}
protected function getTestConfig(string $configName): TestConfigInterface
{
$config = parent::getTestConfig($configName);
$this->replaceConfigUserId($config);
return $config;
}
}
4. Use dama/doctrine-test-bundle in your project to roll back all DB updates after each tests
Example phpunit configuration with dama
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="tests/bootstrap.php">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<php>
<ini name="error_reporting" value="-1"/>
<server name="APP_ENV" value="test" force="true"/>
<server name="SHELL_VERBOSITY" value="-1"/>
<server name="SYMFONY_PHPUNIT_REMOVE" value=""/>
<server name="SYMFONY_PHPUNIT_VERSION" value="8.5"/>
<env name="SYMFONY_DEPRECATIONS_HELPER" value="disabled" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener"/>
</listeners>
<!-- Run `composer require symfony/panther` before enabling this extension -->
<extensions>
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
<!-- <extension class="Symfony\Component\Panther\ServerExtension" />-->
</extensions>
</phpunit>