Installing Codeception in Yii 2

Now that we've seen what we can theoretically do with Codeception, let's move on and install it.

Yii comes with its own Codeception extension that provides a base class for unit tests (yiicodeceptionTestCase), a class for tests that require database interaction (yiicodeceptionDbTestCase), and a base class for Codeception page objects (yiicodeceptionBasePage).

As usual, our preferred method is using Composer:

$ composer require "codeception/codeception: 2.0.*" --prefer-dist --dev

There's a specific reason to use –prefer-dist; if you're using Git, you can get into a hairy situation with Git submodules (but again excluding the /vendor folder should solve most of these problems). To avoid repeating it every time we use Composer, just add the following to your composer.json file:

// composer.json

{
    "config": {
        "preferred-install": "dist"
    }
}

Also, remember that using composer install will not work if you've added the component manually to your composer.json file as it would consider it a mismatch and raise an error. To install the package, you need to run composer update either for all the packages you have installed, or specifically with this:

$ composer update codeception/codeception

As highlighted before, you might also be interested in two additional packages codeception/specify and codeception/verify. These two packages provide a further level of abstraction that allows you to write more human readable tests by using a business-oriented syntax, close to what BDD definitions will look like.

Your composer.json file will contain the following:

// composer.json

{
    "require-dev": {
        "yiisoft/yii2-codeception": "*",
        "yiisoft/yii2-debug": "*",
        "yiisoft/yii2-gii": "*",
        "codeception/codeception": "2.0.*",
        "codeception/specify": "*",
        "codeception/verify": "*"
    }
}

Finding your way around Codeception

All our tests are available within the /tests/codeception folder. In version 2.0 this folder contains directly all the suites and configuration files needed by them and Codeception as well. The following configuration steps are based on this structure.

By listing the content of the /tests folder, we will see the main Codeception configuration file, while each single suite has its own configuration file inside of the /tests/codeception folder, which we can modify accordingly to override or further configure our tests. Starting from our /tests folder, the following are the configuration files we will be dealing with:

  • codeception.yml: This is for all the suites and Codeception in general
  • codeception/acceptance.suite.yml: This is for the acceptance tests
  • codeception/functional.suite.yml: This is for the functional tests
  • codeception/unit.suite.yml: This is for the unit tests

Together with these files, there are some additional configuration files that are mostly needed by Yii: _bootstrap.php and the content of the config/ folder. The underscore prefixing some of these files just marks them in a way such that Codeception will ignore them. Keep this in mind in case you need to create new files in the various suite folders.

Within the /tests/codeception folder, you will find the folders containing the tests for each single testing suite, unit/, functional/, and acceptance/. Each of them will contain a _bootstrap.php file for the suite, the actual tests, and other folders for fixtures for example.

The few other folders contained in /tests/codeception are as follows:

  • bin/: It contains the test-bound yii CLI command, which we will use to run migrations against our test database.
  • _data/: It contains a snapshot of the database (dump.sql) normally used to bring it to an initial state for the acceptance tests, but it can contain anything, for instance, this folder will be used by Codeception in case you want it to generate (and publish) the various scenarios from the tests you've created in plain English (run the codecept help generate:scenarios command for more information).
  • _output/: This folder will become quite useful, as it will contain the output of the fetched pages when your acceptance or functional tests are failing, giving you another way to inspect and understand what's wrong.
  • _pages/: This is where Codeception page objects are stored. There are already three page objects provided by the basic application, namely AboutPage.php, ContactPage.php, and LoginPage.php. We will explore this part further down the line as they will prove to be extremely useful as they simplify our lives quite substantially and promote modularity and reuse of code.
  • _support/: This is used for additional support files, which currently hold the FixtureHelper class used to populate the database with the provided fixtures.

Configuring Codeception

Now, we should pretty much know where all the configuration files live, so we're going to review their content and adjust it before we can start interacting with Codeception and first run all the provided tests and then our own tests.

Let's start with the YAML configuration files for the different suites.

The acceptance tests are configured by default to use PHPBrowser. We will see how things need to be adjusted to use Selenium WebDriver, but generally speaking, both tools require at least a URL to access our application:

# tests/codeception/acceptance.suite.yml

class_name: AcceptanceTester
modules:
    enabled:
        - PhpBrowser
    config:
        PhpBrowser:
            url: 'http://basic.yii2.sandbox'

The default URL is http://localhost:8080, which you won't need to change when, for instance, you're using Vagrant or the PHP built-in server. In the preceding example, I've set up a custom domain name; this is not required in order to run your tests as it might require additional configuration steps that won't be needed, unless you're in a larger environment and your configuration is a bit more complex (for instance in case your tests are being executed remotely). We'll see more of this in the final chapters.

Please also note that you don't need to specify the entry file, index-test.php, as you want Yii to resolve the routing for you.

The base URL for our application isn't needed for our functional tests, as I highlighted before. In fact what Codeception cares about for our functional tests is the entry script for the application: all the functionality is provided by the yii2-codeception package (which should come pre-installed in your application), so in the configuration file, you have just a reference pointing to the configuration of your test application:

# tests/codeception/functional.suite.yml
...
modules:
    config:
        Yii2:
            configFile: 'codeception/config/functional.php'

Heading over to this file, we will find that at the very beginning we have a couple of $_SERVER variables set:

// tests/codeception/config/functional.php
...
// set correct script paths
$_SERVER['SCRIPT_FILENAME'] = YII_TEST_ENTRY_FILE;
$_SERVER['SCRIPT_NAME'] = YII_TEST_ENTRY_URL;

These two constants have been defined in the overall Yii bootstrap file:

// tests/codeception/_bootstrap.php


defined('YII_TEST_ENTRY_URL') or define('YII_TEST_ENTRY_URL', parse_url(CodeceptionConfiguration::config()['config']['test_entry_url'], PHP_URL_PATH));

defined('YII_TEST_ENTRY_FILE') or define('TEST_TEST_ENTRY_FILE', dirname(__DIR__) . '/web/index-test.php'),

In other words, the entry file is always the one found in /web/index-test.php while the URL can be configured in the main configuration file:

// tests/codeception.yml
...
config:
    test_entry_url: https://basic.yii2.sandbox/index-test.php

Note

Remember to adjust the hostname to the one you will use, or leave the default, which is localhost:8080.

For unit tests, there isn't much to be configured, as Codeception is just wrapping around PHPUnit, and the two packages, verify and specify, will work out of the box.

The only thing left to update is the configuration of the database: as we said earlier, currently, you can simply update the DSN in /tests/codeception/config/config.php, in the same way that the main Yii database configuration is defined.

Tests available in Yii 2

Compared to what Yii 1 was offering, Yii 2 now comes with examples of working tests for any suite of tests available. This is a great thing as it would help us understand how to structure and implement our tests.

Once we've got the server running and all the configuration set up properly, we can just run the following command:

$ cd tests
$ ../vendor/bin/codecept run

This will run all the tests and see them passing. At the end, you will see a nice summary:

...
Time: 6.92 seconds, Memory: 35.75Mb

OK (12 tests, 60 assertions)
$

The tests provided for acceptance and functional tests are quite self-explanatory; they're basically ensuring the four pages, namely the homepage, the about page, the contact page and the login page, available in the basic application work as expected.

These tests are exactly the same, with the only difference that acceptance tests take into consideration the ability for you to run the tests via Selenium and include specific directives for it:

// tests/functional/ContactCept.php
...
if (method_exists($I, 'wait')) {
    $I->wait(3); // only for selenium
}
...

This is just an example, and it shouldn't really matter to you right now, as we're going to see how Selenium WebDriver works in detail further down the line in Chapter 7, Having Fun Doing Browser Testing.

The unit tests shipped by Yii 2 are the ones that are unsurprisingly different; they mostly cover integration tests between various components, for instance, for the login form and the contact form, while they leave to us the burden of implementing any test for the user. We will get there, in the next chapter.

The only thing worth noticing in the unit tests is that they make use of Specify for a more declarative way to write units, instead of the more common PHPUnit syntax. Again, this is just syntactic sugar and it might be easier for you to start with it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset