CakePHP 3 Codeception Module
, (*1)
:warning: This repository is archived and is no longer maintained., (*2)
A codeception module to test your CakePHP 3 powered application. Using Codeception with CakePHP opens up a whole new set of testing capabilities., (*3)
Front-end testing
(i.e. browser-based workflow tests), (*4)
Back-end testing
(i.e. direct, internal method tests), (*5)
Usage
From a CakePHP application, run the following from the command-line:, (*6)
$ composer require --dev cakephp/codeception:dev-master && composer run-script post-install-cmd
If you are developing a plugin, add the post-install script to your composer.json
first:, (*7)
{
"scripts": {
"post-install-cmd": "Cake\\Codeception\\Console\\Installer::customizeCodeceptionBinary"
}
}
Once installed, you can now run bootstrap
which will create all the codeception required files
in your application:, (*8)
$ vendor/bin/codecept bootstrap
This creates the following files/folders in your app
directory:, (*9)
โโโ codeception.yml
โโโ src
โย ย โโโ TestSuite
โย ย ย ย โโโ Codeception
| โโโ AcceptanceTester.php
| โโโ FunctionalTester.php
| โโโ UnitTester.php
| โโโ Helper
โย ย ย ย โ โโโ Acceptance.php
โย ย ย ย โ โโโ Functional.php
โย ย ย ย โ โโโ Unit.php
| โโโ _generated
| โโโ .gitignore
โโโ tests
ย ย โโโ Acceptance.suite.yml
ย ย โโโ Functional.suite.yml
ย ย โโโ Unit.suite.yml
ย ย โโโ Acceptance
ย ย โย ย โโโ bootstrap.php
ย ย โโโ Fixture
ย ย โย ย โโโ dump.sql
ย ย โโโ Functional
ย ย โย ย โโโ bootstrap.php
ย ย โโโ Unit
ย ย ย ย โโโ bootstrap.php
As you might have noticed, the CakePHP implementation differs in a couple things:, (*10)
- uses CamelCase suite names (
Functional
vs. functional
)
- uses
bootstrap.php
, no underscore prefix (vs. _bootstrap.php
)
- uses
src/TestSuite/Codeception
for custom modules (helpers) (vs. tests/_helpers
)
- uses
tmp/tests
to store logs (vs. tests/_logs
)
- uses
tests/Fixture
to fixture data (vs. tests/_data
)
- uses
tests/Envs
to fixture data (vs. tests/_envs
)
- adds a
.gitignore
to never track auto-generated files
- adds custom templates for various generated files using the
codecept
binary
To better understand how Codeception tests work, please check the official documentation., (*11)
Example Cept
<?php
$I = new FunctionalTester($scenario);
$I->wantTo('ensure that adding a bookmark works');
$I->amOnPage('/bookmarks/add');
$I->see('Submit');
$I->submitForm('#add', [
'title' => 'First bookmark',
]);
$I->seeInSession([
'Flash'
]);
Actions
Auth
..., (*12)
Config
Assert config key(/value) with seeInConfig($key, $value = null)
$I->seeInConfig('App.name'); // checks only that the key exists
$I->seeInConfig('App.name', 'CakePHP');
$I->seeInConfig(['App.name' => 'CakePHP']);
Assert no config key(/value) with dontSeeInConfig($key, $value = null)
$I->dontSeeInConfig('App.name'); // checks only that the key does not exist
$I->dontSeeInConfig('App.name', 'CakePHP');
$I->dontSeeInConfig(['App.name' => 'CakePHP']);
Db
Insert record with haveRecord($model, $data = [])
This is useful when you need a record for just one test (temporary fixture). It
does not assert anything and returns the inserted record's ID., (*13)
$I->haveRecord('users', ['email' => 'jadb@cakephp.org', 'username' => 'jadb']);
Retrieve record with grabRecord($model, $conditions = [])
This is a wrapper around the Cake\ORM\Table::find('first')
method., (*14)
$I->grabRecord('users', ['id' => '1']);
Assert record exists with seeRecord($model, $conditions = [])
This checks that the requested record does exist in the database., (*15)
$I->seeRecord('users', ['username' => 'jadb']);
Assert record does not exist with dontSeeRecord($model, $conditions = [])
This checks that the request record does not exist in the database., (*16)
$I->dontSeeRecord('users', ['email' => 'jadb@cakephp.org']);
Dispatcher
..., (*17)
Miscellaneous
Load fixtures
In your Cest
test case, write $fixutures
property:, (*18)
class AwesomeCest
{
public $fixtures = [
'app.users',
'app.posts',
];
// ...
}
You can use $autoFixtures
, $dropTables
property, and loadFixtures()
method:, (*19)
class AwesomeCest
{
public $autoFixtures = false;
public $dropTables = false;
public $fixtures = [
'app.users',
'app.posts',
];
public function tryYourSenario($I)
{
// load fixtures manually
$I->loadFixtures('Users', 'Posts');
// or load all fixtures
$I->loadFixtures();
// ...
}
}
In your Cept
test case, use $I->useFixtures()
and $I->loadFixtures()
:, (*20)
$I = new FunctionalTester($scenario);
// You should call `useFixtures` before `loadFixtures`
$I->useFixtures('app.users', 'app.posts');
// Then load fixtures manually
$I->loadFixtures('Users', 'Posts');
// or load all fixtures
$I->loadFixtures();
Assert CakePHP version with expectedCakePHPVersion($ver, $operator = 'ge')
$I->expectedCakePHPVersion('3.0.4');
Router
Open page by route with amOnRoute($route, $params = [])
All the below forms are equivalent:, (*21)
$I->amOnRoute(['controller' => 'Posts', 'action' => 'add']);
$I->amOnRoute('addPost'); // assuming there is a route named `addPost`
Open page by action with amOnAction($action, $params = [])
All the below forms are equivalent:, (*22)
$I->amOnAction('Posts@add');
$I->amOnAction('Posts.add');
$I->amOnAction('PostsController@add');
$I->amOnAction('PostsController.add');
$I->amOnAction('posts@add');
$I->amOnAction('posts.add');
Assert URL matches route with seeCurrentRouteIs($route, $params = [])
All the below forms are equivalent:, (*23)
$I->seeCurrentRouteIs(['controller' => 'Posts', 'action' => 'add']);
$I->seeCurrentRouteIs('addPost'); // assuming there is a route named `addPost`
Assert URL matches action with seeCurrentActionIs($action, $params = [])
All the below forms are equivalent:, (*24)
$I->seeCurrentActionIs('Posts@add');
$I->seeCurrentActionIs('Posts.add');
$I->seeCurrentActionIs('PostsController@add');
$I->seeCurrentActionIs('PostsController.add');
$I->seeCurrentActionIs('posts@add');
$I->seeCurrentActionIs('posts.add');
Session
Insert key/value(s) in session with haveInSession($key, $value = null)
$I->haveInSession('redirect', Router::url(['_name' => 'dashboard']));
$I->haveInSession(['redirect' => Router::url(['_name' => 'dashboard'])]);
Assert key(/value) in session with seeInSession($key, $value = null)
$I->seeInSession('redirect'); // only checks the key exists.
$I->seeInSession('redirect', Router::url(['_name' => 'dashboard']));
$I->seeInSession(['redirect', Router::url(['_name' => 'dashboard'])]);
Assert key(/value) not in session with dontSeeInSession($key, $value = null)
$I->dontSeeInSession('redirect'); // only checks the key does not exist.
$I->dontSeeInSession('redirect', Router::url(['_name' => 'dashboard']));
$I->dontSeeInSession(['redirect', Router::url(['_name' => 'dashboard'])]);
View
..., (*25)