# Customization
In this chapter we will explain how you can extend and customize the file structure and test execution routines.
## One Runner for Multiple Applications
If your project consists of several applications (frontend, admin, api) or you are using the Symfony framework
with its bundles, you may be interested in having all tests for all applications (bundles) executed in one runner.
In this case you will get one report that covers the whole project.
Place the `codeception.yml` file into the root folder of your project
and specify the paths to the other `codeception.yml` configurations that you want to include:
```yaml
include:
- frontend/src/*Bundle
- admin
- api/rest
paths:
output: _output
settings:
colors: false
```
You should also specify the path to the `log` directory, where the reports and logs will be saved.
Wildcards (*) can be used to specify multiple directories at once.
### Namespaces
To avoid naming conflicts between Actor classes and Helper classes, they should be separated into namespaces.
To create test suites with namespaces you can add `--namespace` option to the bootstrap command:
```bash
php codecept bootstrap --namespace frontend
```
This will bootstrap a new project with the `namespace: frontend` parameter in the `codeception.yml` file.
Helpers will be in the `frontend\Codeception\Module` namespace and Actor classes will be in the `frontend` namespace.
The newly generated tests will look like this:
```php
'afterSuite',
'test.before' => 'beforeTest',
'step.before' => 'beforeStep',
'test.fail' => 'testFailed',
'result.print.after' => 'print',
);
// methods that handle events
public function afterSuite(\Codeception\Event\SuiteEvent $e) {}
public function beforeTest(\Codeception\Event\TestEvent $e) {}
public function beforeStep(\Codeception\Event\StepEvent $e) {}
public function testFailed(\Codeception\Event\FailEvent $e) {}
public function print(\Codeception\Event\PrintResultEvent $e) {}
}
```
By implementing event handling methods you can listen for events and even update passed objects.
Extensions have some basic methods you can use:
* `write` - prints to the screen
* `writeln` - prints to the screen with a new-line character at the end
* `getModule` - allows you to access a module
* `hasModule` - checks if a module is enabled
* `getModuleNames` - list all enabled modules
* `_reconfigure` - can be implemented instead of overriding the constructor
### Enabling Extension
Once you've implemented a simple extension class, you can require it in `tests/_bootstrap.php`,
load it with Composer's autoloader defined in `composer.json`, or store the class inside `tests/_support`dir.
You can then enable it in `codeception.yml`
```yaml
extensions:
enabled: [MyCustomExtension]
```
Extensions can also be enabled per suite inside suite configs (like `acceptance.suite.yml`) and for a specific environment.
To enable extension dynamically, execute the `run` command with `--ext` option.
Provide a class name as a parameter:
```bash
codecept run --ext MyCustomExtension
codecept run --ext "\My\Extension"
```
If a class is in a `Codeception\Extension` namespace you can skip it and provide only a shortname.
So Recorder extension can be started like this:
```bash
codecept run --ext Recorder
```
### Configuring Extension
In the extension, you can access the currently passed options via the `options` property.
You also can access the global configuration via the `\Codeception\Configuration::config()` method.
If you want to have custom options for your extension, you can pass them in the `codeception.yml` file:
```yaml
extensions:
enabled: [MyCustomExtension]
config:
MyCustomExtension:
param: value
```
The passed in configuration is accessible via the `config` property: `$this->config['param']`.
Check out a very basic extension [Notifier](https://github.com/Codeception/Notifier).
### Custom Commands
You can add your own commands to Codeception.
Your custom commands have to implement the interface Codeception\CustomCommandInterface,
because there has to be a function to get the name of the command.
You have to register your command in the file `codeception.yml`:
```yaml
extensions:
commands: [Project\Command\MyCustomCommand]
```
If you want to activate the Command globally, because you are using more then one `codeception.yml` file,
you have to register your command in the `codeception.dist.yml` in the root folder of your project.
Please see a [complete example](https://gist.github.com/sd-tm/37d5f9bca871c72648cb)
## Group Objects
Group Objects are extensions listening for the events of tests belonging to a specific group.
When a test is added to a group:
```php
group('admin');
$I = new AcceptanceTester($scenario);
```
This test will trigger the following events:
* `test.before.admin`
* `step.before.admin`
* `step.after.admin`
* `test.success.admin`
* `test.fail.admin`
* `test.after.admin`
A group object is built to listen for these events. It is useful when an additional setup is required
for some of your tests. Let's say you want to load fixtures for tests that belong to the `admin` group:
```php
writeln('inserting additional admin users...');
$db = $this->getModule('Db');
$db->haveInDatabase('users', array('name' => 'bill', 'role' => 'admin'));
$db->haveInDatabase('users', array('name' => 'john', 'role' => 'admin'));
$db->haveInDatabase('users', array('name' => 'mark', 'role' => 'banned'));
}
public function _after(\Codeception\Event\TestEvent $e)
{
$this->writeln('cleaning up admin users...');
// ...
}
}
```
A group class can be created with `php codecept generate:group groupname` command.
Group classes will be stored in the `tests/_support/Group` directory.
A group class can be enabled just like you enable an extension class. In the file `codeception.yml`:
``` yaml
extensions:
enabled: [Group\Admin]
```
Now the Admin group class will listen for all events of tests that belong to the `admin` group.
## Custom Reporters
Alternative reporters can be implemented as extension.
There are [DotReporter](http://codeception.com/extensions#DotReporter) and [SimpleReporter](http://codeception.com/extensions#SimpleReporter) extensions included.
Use them to change output or use them as an example to build your own reporter. They can be easily enabled with `--ext` option
```bash
codecept run --ext DotReporter
```

If you want to use it as default reporter enable it in `codeception.yml`.
But what if you need to change the output format of the XML or JSON results triggered with the `--xml` or `--json` options?
Codeception uses PHPUnit printers and overrides them. If you need to customize one of the standard reporters you can override them too.
If you are thinking on implementing your own reporter you should add a `reporters` section to `codeception.yml`
and override one of the standard printer classes with one of your own:
```yaml
reporters:
xml: Codeception\PHPUnit\Log\JUnit
html: Codeception\PHPUnit\ResultPrinter\HTML
report: Codeception\PHPUnit\ResultPrinter\Report
```
All PHPUnit printers implement the
[PHPUnit_Framework_TestListener](https://phpunit.de/manual/current/en/extending-phpunit.html#extending-phpunit.PHPUnit_Framework_TestListener)
interface. It is recommended to read the code of the original reporter before overriding it.
## Installation Templates
Codeception setup can be customized for the needs of your application.
If you build a distributable application and you have a personalized configuration you can build an
Installation template which will help your users to start testing on their projects.
Codeception has built-in installation templates for
* [Acceptance tests](https://github.com/Codeception/Codeception/blob/2.3/src/Codeception/Template/Acceptance.php)
* [Unit tests](https://github.com/Codeception/Codeception/blob/2.3/src/Codeception/Template/Unit.php)
* [REST API tests](https://github.com/Codeception/Codeception/blob/2.3/src/Codeception/Template/Api.php)
They can be executed with `init` command:
```bash
codecept init Acceptance
```
To init tests in specific folder use `--path` option:
```bash
codecept init Acceptance --path acceptance_tests
```
You will be asked several questions and then config files will be generated and all necessary directories will be created.
Learn from the examples above to build a custom Installation Template. Here are the basic rules you should follow:
* Templates should be inherited from [`Codeception\InitTemplate`](http://codeception.com/docs/reference/InitTemplate) class and implement `setup` method.
* Template class should be placed in `Codeception\Template` namespace so Codeception could locate them by class name
* Use methods like `say`, `saySuccess`, `sayWarning`, `sayError`, `ask`, to interact with a user.
* Use `createDirectoryFor`, `createEmptyDirectory` methods to create directories
* Use `createHelper`, `createActor` methods to create helpers and actors.
* Use [Codeception generators](https://github.com/Codeception/Codeception/tree/2.3/src/Codeception/Lib/Generator) to create other support classes.
## Conclusion
Each feature mentioned above may help dramatically when using Codeception to automate the testing of large projects,
although some features may require advanced knowledge of PHP. There is no "best practice" or "use cases"
when we talk about groups, extensions, or other powerful features of Codeception.
If you see you have a problem that can be solved using these extensions, then give them a try.