Skip to content

Latest commit

 

History

History
326 lines (214 loc) · 13.3 KB

File metadata and controls

326 lines (214 loc) · 13.3 KB
layout title
doc
08-Customization - Codeception - Documentation

Customization

In this chapter we will explain how you can extend and customize file structure and test execution routines.

One Runner for Multiple Applications

In case your project consists of several applications (frontend, admin, api) or you use Symfony framework with its bundles, you may be interested in having all tests for all applications (bundles) to be executed in one runner. In this case you will get one report that covers the whole project.

Place codeception.yml file into root folder of your project and specify paths to other codeception.yml configs you want to include.

{% highlight yaml %}

include:

  • frontend/src/*Bundle
  • admin
  • api/rest paths: log: log settings: colors: false

{% endhighlight %}

You should also specify path to log directory, where the reports and logs will be stored.

Wildcards (*) can be used to specify multiple directories at once.

Namespaces

To avoid naming conflicts between Actor classes and Helper classes, they should be added into namespaces. To create test suites with namespaces you can add --namespace option to bootstrap command.

{% highlight bash %}

php codecept bootstrap --namespace frontend

{% endhighlight %}

This will bootstrap a new project with namespace: frontend parameter in codeception.yml file. Helpers will be in frontend\Codeception\Module namespace and Actor classes will be in frontend namespace. Thus, newly generated tests will look like this:

{% highlight 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) {} } {% endhighlight %} By implementing event handling methods you can listen to event and even update passed objects. Extensions have some basic methods you can use: * `write` - prints to screen * `writeln` - prints to screen with line end char at the end * `getModule` - allows you to access a module * `hasModule` - checks if module is enabled * `getModuleNames` - list all enabled modules * `_reconfigure` - can be implemented instead of overriding constructor. ### Enabling Extension Once you've implemented a simple extension class, you can require it in `tests/_bootstrap.php`, load with Composer's autoloader defined in `composer.json`, or store class inside `tests/_support`dir. Then you can enable it in `codeception.yml`: {% highlight yaml %} extensions: enabled: [MyCustomExtension] {% endhighlight %} ### Configuring Extension In extension you can access currently passed options via `options` property. You also can access global config via `\Codeception\Configuration::config()` method. But if you want to have custom options for your extension, you can pass them in `codeception.yml` file: {% highlight yaml %} extensions: enabled: [MyCustomExtension] config: MyCustomExtension: param: value {% endhighlight %} Passed configuration is accessible via `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` {% highlight yaml %} extensions: commands: [Project\Command\MyCustomCommand] {% endhighlight %} If you want to activate the Command globally, because you use more then one {% highlight yaml %} codeception.yml {% endhighlight %} file, then you have to register your command in {% highlight yaml %} codeception.dist.yml {% endhighlight %} 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 to events of a tests belonging to a specific group. When a test is added to a group: {% highlight php %} group('admin'); $I = new AcceptanceTester($scenario); {% endhighlight %} This test will trigger 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 to these events. It is pretty useful when additional setup is required for some of your tests. Let's say you want to load fixtures for tests that belong to `admin` group: {% highlight 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...'); // ... } } {% endhighlight %} A group class can be created with `php codecept generate:group groupname` command. Group class will be stored in `tests/_support/Group` directory. A group class can be enabled just like you enable extension class. In file `codeception.yml`: {% highlight yaml %} extensions: enabled: [Group\Admin] {% endhighlight %} Now Admin group class will listen to all events of tests that belong to the `admin` group. ## Custom Reporters In order to customize output you can use Extensions, as it is done in [SimpleOutput Extension](https://github.com/Codeception/Codeception/blob/master/ext%2FSimpleOutput.php). But what if you need to change output format of XML or JSON results triggered with `--xml` or `--json` options? Codeception uses printers from PHPUnit and overrides some of them. If you need to customize one of standard reporters you can override them too. If you are thinking on implementing your own reporter you should add `reporters` section to `codeception.yml` and override one of standard printer classes to your own: {% highlight yaml %} reporters: xml: Codeception\PHPUnit\Log\JUnit html: Codeception\PHPUnit\ResultPrinter\HTML tap: PHPUnit_Util_Log_TAP json: PHPUnit_Util_Log_JSON report: Codeception\PHPUnit\ResultPrinter\Report {% endhighlight %} All reporters implement [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 original reporter before overriding it. ## Conclusion Each feature mentioned above may dramatically help when using Codeception to automate 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. * **Next Chapter: [Data >](/docs/09-Data)** * **Previous Chapter: [< BDD](/docs/07-BDD)**