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.
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:
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.
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:
This will bootstrap a new project with the
namespace: frontend parameter in the
Helpers will be in the
frontend\Codeception\Module namespace and Actor classes will be in the
The newly generated tests will look like this:
Once each of your applications (bundles) has its own namespace and different Helper or Actor classes,
you can execute all the tests in a single runner. Run the Codeception tests as usual, using the meta-config we created earlier:
This will launch the test suites for all three applications and merge the reports from all of them.
This is very useful when you run your tests on a Continuous Integration server
and you want to get a single report in JUnit and HTML format. The code coverage report will be merged too.
If you want to run a specific suite from the application you can execute:
unit is the name of suite and the
-c option specifies the path to the
codeception.yml configuration file to use.
In this example we will assume that there is
frontend/codeception.yml configuration file
and that we will execute the unit tests for only that app.
Codeception has limited capabilities to extend its core features.
Extensions are not supposed to override current functionality,
but can be useful if you are an experienced developer and you want to hook into the testing flow.
By default, one
RunFailed Extension is already enabled in your global
It allows you to rerun failed tests by using the
-g failed option:
Codeception comes with bundled extensions located in
For instance, you can enable the Logger extension to log the test execution with Monolog:
But what are extensions, anyway? Basically speaking, extensions are nothing more than event listeners
based on the Symfony Event Dispatcher component.
Here are the events and event classes. The events are listed in the order in which they happen during execution.
Each event has a corresponding class, which is passed to a listener, and contains specific objects.
|Before suite is executed
|Before test is executed
|At the very beginning of test execution
|After failed step
|After failed test
|After test ended with error
|After executing incomplete test
|After executing skipped test
|After executing successful test
|At the end of test execution
|After test execution
|After suite was executed
||Suite, Result, Settings
|When test fails are printed
|After result was printed
There may be some confusion between
The start and end events are triggered by PHPUnit, but the before and after events are triggered by Codeception.
Thus, when you are using classical PHPUnit tests (extended from
the before/after events won’t be triggered for them. During the
test.before event you can mark a test
as skipped or incomplete, which is not possible in
test.start. You can learn more from
Codeception internal event listeners.
The extension class itself is inherited from
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
Once you’ve implemented a simple extension class, you can require it in
load it with Composer’s autoloader defined in
composer.json, or store the class inside
You can then enable it in
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
Provide a class name as a parameter:
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:
In the extension, you can access the currently passed options via the
You also can access the global configuration via the
If you want to have custom options for your extension, you can pass them in the
The passed in configuration is accessible via the
Check out a very basic extension Notifier.
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
If you want to activate the Command globally, because you are using more then one
you have to register your command in the
codeception.dist.yml in the root folder of your project.
Please see a complete example
Group Objects are extensions listening for the events of tests belonging to a specific group.
When a test is added to a group:
This test will trigger the following events:
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
A group class can be created with
php codecept generate:group groupname command.
Group classes will be stored in the
A group class can be enabled just like you enable an extension class. In the file
Now the Admin group class will listen for all events of tests that belong to the
Alternative reporters can be implemented as extension.
There are DotReporter and 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
If you want to use it as default reporter enable it in
But what if you need to change the output format of the XML or JSON results triggered with the
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
and override one of the standard printer classes with one of your own:
All PHPUnit printers implement the
interface. It is recommended to read the code of the original reporter before overriding it.
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
They can be executed with
To init tests in specific folder use
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 class and implement
- Template class should be placed in
Codeception\Template namespace so Codeception could locate them by class name
- Use methods like
ask, to interact with a user.
createEmptyDirectory methods to create directories
createActor methods to create helpers and actors.
- Use Codeception generators to create other support classes.
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.