Codeception is a testing framework that allows testing at multiple levels: acceptance, functional, and unit. It provides bundled actions and assertions to make testing easier. Codeception tests can be run with PHPBrowser, which uses a PHP scraper, or Selenium WebDriver to test in a real browser. Modules in Codeception encapsulate common testing actions and reduce the need to rewrite test code.
3. Why use codeception if I already know phpunit and
behat?
● fast, as each functional/integration test is wrapped into transaction using
Doctrine ORM
● scenario-driven, it means that tests are linear, described in easy to get PHP
● can be used for testing complex interactions inside functional tests.
● easy to write, as Codeception already provides bundled actions and
assertions for most popular use cases.
● combine all testing levels (acceptance, functional, unit) in one tool.
8. Installing and setup
composer require --dev "codeception/codeception:~2.1"
- the unit and functional tests will reside inside the bundles, so we will have
only the acceptance tests placed globally
php bin/codecept bootstrap --empty
- after running this command, we will have the “tests” folder, and the
“codeception.yml” config file, at the app folder level;
php bin/codecept g:suite acceptance
Generate setup for unit and functional tests:
php bin/codecept bootstrap --empty -c src/AppBundle --namespace AppBundle
then, generate the test suites:
php bin/codecept g:suite functional -c src/AppBundle
php bin/codecept g:suite unit -c src/AppBundle
11. Acceptance Testing
- acceptance testing can be performed by a non-technical person
- if you are developing a web-application the tester needs nothing more than a
web browser to check that your site works correctly
- you can reproduce an AcceptanceTester's actions in scenarios and run them
automatically after each site change
- you will be sure that site features work after the last changes were made
- there’s no need to manually test a long or cumbersome functionality or user
scenario over and over again
- this scenario can probably be read by non-technical people or Codeception
can even 'naturalize' this scenario, converting it into plain English
12. PHP Browser
- is the fastest way to run acceptance tests, since it doesn't require running an
actual browser
- it uses a PHP web scraper, which acts like a browser: it sends a request, then
receives and parses the response
- note that you can't test actual visibility of elements, or javascript interactions.
- the good thing about PhpBrowser is that it can be run in any environment with
just PHP and cURL required
- you can click only on links with valid urls or form submit buttons
- you can't fill fields that are not inside a form
- you can't work with JavaScript interactions: modal windows, datepickers, etc.
13. Selenium WebDriver
- a nice feature of Codeception is that most scenarios can be easily ported
between the testing backends
- the PhpBrowser tests can be executed inside a real browser (or PhantomJS)
with Selenium WebDriver
- the only thing we need to change is to reconfigure and rebuild the
AcceptanceTester class, to use WebDriver instead of PhpBrowser, by
modifying the yml configuration file
- you run acceptance tests with Selenium, Firefox will be started and all actions
will be performed step by step using browser engine
14. Modules
- test classes use Actors to perform actions and act as a dummy user
- actor classes are not written but generated from suite configuration
- methods of actor classes are generally taken from Codeception Modules
- each module provides predefined actions for different testing purposes, and
they can be combined to fit the testing environment
- Codeception tries to solve 90% of possible testing issues in its modules, so
you don't have reinvent the wheel
15. Asserts Module
assertContains
Checks that haystack contains needle
● param $needle
● param $haystack
● param string $message
assertEmpty
Checks that variable is empty.
● param $actual
● param string $message
assertEquals
Checks that two variables are equal.
● param $expected
● param $actual
● param string $message
assertFileExists
Checks if file exists
● param string $filename
● param string $message
assertSame
Checks that two variables are same
● param $expected
● param $actual
● param string $message
assertTrue
Checks that condition is positive.
● param $condition
● param string $message
16. Doctrine2 Module
Using the Symfony2 module:
modules:
enabled:
- Symfony2
- Doctrine2:
depends: Symfony2
-dontSeeInRepository
Flushes changes to database and performs ->findOneBy() call for current repository.
● param $entity
● param array $params
flushToDatabase
Performs $em->flush();
grabFromRepository
Selects field value from repository. It builds query based on array of parameters. You can use entity associations to
build complex queries.
Without using the Symfony2 module:
modules:
enabled:
- Doctrine2:
connection_callback: ['MyDb',
'createEntityManager']
17. PHP Browser Module
amOnPage
Opens the page for the given relative URI.
<?php
// opens /register page
$I->amOnPage('/register');
click
- if a fuzzy locator is given, the page will be searched for
a button, link, or image matching the locator string
- the second parameter is a context (CSS or XPath
locator) to narrow the search
<?php
// button of form
$I->click('Submit');
// CSS button
$I->click('#form input[type=submit]');
// link in context
$I->click('Logout', '#nav');
see
- checks that the current page contains the given string.
Specify a locator as the second parameter to match a
specific region
<?php
$I->see('Logout'); // I can suppose user is logged in
$I->see('Sign Up','h1'); // I can suppose it's a signup
page
seeResponseCodeIs
- checks that response code is equal to value provided.
● param $code
submitForm
- submits the given form on the page, optionally with the
given form values as an array
$I->submitForm('#login', [
'login' => 'davert',
'password' => '123456'
],
'submitButtonName');
18. REST Module
seeResponseContainsJson
Checks whether the last JSON response contains
provided array. The response is converted to array with
json_decode($response, true)
<?php
// response: {name: john, email: john@gmail.com}
$I->seeResponseContainsJson(array('name' => 'john'));
seeHttpHeader
Checks over the given HTTP header and (optionally) its
value, asserting that are there
● param $name
● param $value @part json
● Part: xml
seeResponseCodeIs
Checks response code equals to provided value.
@part json @part xml * param $code
sendPOST
Sends a POST request to given uri.
Parameters and files (as array of filenames) can be
provided.
● param $url
● param array|JsonSerializable $params
● param array $files @part json
sendPUT
Sends PUT request to given uri.
● param $url
● param array $params
● param array $files @part json
sendGET
Sends a GET request to given uri.
● param $url
● param array $params @part json