CodeCeption

Test types

  • Acceptance Tests are for non-technical people
  • Acceptance Tests should use Selenium2 module for javascript interactions, that cannot be covered by functional (PhpBrowser) tests
  • Functional Tests don't require a web server
  • Functional Tests should use PhpBrowser module
  • Functional Tests can use the Laravel module

*Any config changes in yaml files need a codecept build

Definition http://phptest.club/

Installing

Download

wget http://codeception.com/codecept.phar

Setup environment

php codecept.phar bootstrap

Create a test

php codecept.phar generate:cept acceptance Welcome

Acceptance testing

Create a test file ( a cept)

php codecept.phar generate:cept acceptance Welcome

Write it

<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('ensure that frontpage works');
$I->amOnPage('/'); 
$I->see('Home');
?>

a longer example:

<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('sign in');
$I->amOnPage('/login');
$I->fillField('username', 'davert');
$I->fillField('password', 'qwerty');
$I->click('LOGIN');
$I->see('Welcome, Davert!');
?>

Configure it

class_name: AcceptanceTester
modules:
        enabled:
                - PhpBrowser:
                        url: {YOUR APP'S URL}
                - \Helper\Acceptance

when you change a configuration you may need to run codecept build

Create a class file ( a cest)

codecept generate:cest functional Project

A class file can contain multiple tests

Note _before() and _after() runs after each test If you want some variables defined once only put in the __construct() method

Run it

Normal: php codecept.phar run With Steps: codecept run acceptance --steps With debug: codecept run acceptance --debug One test: codecept run acceptance login

Debugging

codecept_debug($response);

Make sure you run tests with --debug or it won't show up

Functional tests

<?php
$I = new FunctionalTester($scenario);
$I->amOnPage('/');
$I->click('Login');
$I->fillField('Username', 'Miles');
$I->fillField('Password', 'Davis');
$I->click('Enter');
$I->see('Hello, Miles', 'h1');
// $I->seeEmailIsSent() - special for Symfony2
?>

Modules

 Laravel

Note: Laravel module should only be used in Functional Tests not Acceptance Tests. This is because the Laravel module expects to be connected internally via PHP, while WebDriver connects through a webserver.

The module makes Codeception use the "testing" environment in Laravel.

You can override these settings though:

config:
    Laravel4:
        environment : 'testing'
        filters : true
                    cleanup: false
                    environment: testing

Cleanup:false means that the database won't run in transaction mode

More info

Example

$user = User::find(30);
$I->amLoggedAs($user);
$post = $I->grabRecord('posts', array('user_id' => 30));
$I->sendAjaxPostRequest("/ajax/like",array("post_id"=>$post->id,"user_id"=>$post->user_id,"csrf_token"=>csrf_token()));
$I->seeResponseCodeIs(200);

PhpUnit

\PHPUnit_Framework_Assert::assertEquals(1,count($items));

PhpBrowser

http://codeception.com/docs/modules/PhpBrowser

Click $I->click('//*[starts-with(@id, \'colleague_\')]');

Javascirpt

Execute javascript function waitForJS(function) Execute javascript function with timeout waitForJS(10000,function) Execute javascript code $I->executeJS("$('*:contains(\"No results found\")').length > 0;");

Check if Jquery is active //$jsCondition = 'jQuery.active == 0';

Forms

Checkboxes

Find checkbox with value of 4 within #subjects div

$selector = '#subjects input[value="4"]';
$I->checkOption($selector);
$I->seeCheckboxIsChecked($selector);

Select / radio

$I->selectOption('form select[name=account]', 'Premium');

Problems

CSRF token

$token = $I->grabValueFrom("input[name='_token']");
dd($token);

Alternatively you could just ignore csrf in Laravel:

Route::filter('csrf', function() {
...
if (App::environment() == "testing") return;
...
}

make sure environment : 'testing'

Cannot redeclare _generated\AcceptanceTesterActions::switchToIFrame()

See https://github.com/Codeception/Codeception/issues/2435

You need to add

modules:
enabled: 
    - Laravel5:
        part: ORM

or

    modules:
        enabled: 
                - Laravel4:
                        part: ORM

Ajax

  • sendAjaxXRequest() PhpBrowser module - expects an HTML response to test, so you check for html elements for example afterwards
  • sendGET(), sendPOST() REST module - expect a JSON response to test

PSR7 / Guzzle

`[PHPUnit_Framework_Exception] Argument 2 passed to GuzzleHttp\Exception\RequestException::__construct() must be an instance of GuzzleHttp\Message\RequestInterface, instance of GuzzleHttp\Psr7\Request given, called in phar:///vagrant/bin/codecept/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php on line 186 and defined`
  • Upgrade guzzle to 6
  • make sure you have codeception 2.1
  • make sure you are on PHP 5.6

Helpers

in tests/_support/ you will find various helper classes. Call $I->myHelper() Config:

    modules:
            enabled:
                            - FunctionalHelper