refactored tests

This commit is contained in:
Davert 2016-07-16 04:13:51 +03:00
parent 4f8f207a6d
commit 0ef627f7de
55 changed files with 1910 additions and 1733 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ phpunit.phar
/phpunit.xml
tests/_output/*
tests/_support/_generated

View File

@ -100,3 +100,83 @@ return [
- Yii won't create the database for you, this has to be done manually before you can access it.
- Check and edit the other files in the `config/` directory to customize your application as required.
- Refer to the README in the `tests` directory for information specific to basic application tests.
TESTING
-------
Tests are located in `tests` directory, developed with [Codeception PHP Testing Framework](http://codeception.com/).
By default there are 3 test suites: `unit`, `functional` and `acceptance`. Tests can be executed by running
```
composer exec codecept run
```
This will execute unit and functional tests. Unit tests are testing the system components, while functional tests are for testing user interaction.
Acceptance tests are disabled by default as they require additional setup as they perform testing in real browser.
To execute acceptance tests do the following:
1. Rename `tests/acceptance.suite.yml.example` to `tests/acceptance.suite.yml` to enable suite configuration
2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full featured version of Codeception.
3. Update dependencies with Composer
```
composer update
```
4. Download [Selenium Server](http://www.seleniumhq.org/download/) and launch it:
```
java -jar java -jar ~/selenium-server-standalone-x.xx.x.jar
```
5. (Optional) Create `yii2_basic_tests` database and update it by applying migrations if you have them.
```
tests/bin/yii migrate
```
The database configuration can be found at `config/test_db.php`.
6. Start web server:
```
tests/bin/yii serve
```
7. Now you can run all available tests
```
# run all available tests
composer exec codecept run
# run acceptance tests
composer exec codecept run acceptance
# run only unit and functional tests
composer exec codecept run unit,functional
```
Code coverage support
---------------------
By default, code coverage is disabled in `codeception.yml` configuration file, you should uncomment needed rows to be able
to collect code coverage. You can run your tests and collect coverage with the following command:
```
#collect coverage for all tests
composer exec codecept run --coverage-html --coverage-xml
#collect coverage only for unit tests
composer exec codecept run unit --coverage-html --coverage-xml
#collect coverage for unit and functional tests
composer exec codecept run functional,unit --coverage-html --coverage-xml
```
You can see code coverage output under the `tests/_output` directory.

View File

@ -1,4 +1,18 @@
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
memory_limit: 1024M
colors: true
modules:
config:
Yii2:
configFile: 'config/test.php'
# To enable code coverage:
#coverage:
# #c3_url: http://localhost:8080/index-test.php/
@ -20,12 +34,3 @@ actor: Tester
# - ../views/*
# - ../web/*
# - ../tests/*
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
memory_limit: 1024M
colors: true

View File

@ -20,8 +20,7 @@
"yiisoft/yii2-swiftmailer": "*"
},
"require-dev": {
"yiisoft/yii2-codeception": "*",
"codeception/specify": "*",
"codeception/base": "^2.2.3",
"codeception/verify": "*",
"yiisoft/yii2-debug": "*",
"yiisoft/yii2-gii": "*",

View File

@ -1,7 +1,5 @@
<?php
Yii::setAlias('@tests', dirname(__DIR__) . '/tests/codeception');
$params = require(__DIR__ . '/params.php');
$db = require(__DIR__ . '/db.php');

View File

@ -1,9 +1,6 @@
<?php
$params = require(__DIR__ . '/params.php');
$dbParams = require(__DIR__ . '/db.php');
// test database! Important not to run tests on production or development databases
$dbParams['dsn'] = 'mysql:host=localhost;dbname=yii2_basic_tests';
$dbParams = require(__DIR__ . '/test_db.php');
/**
* Application configuration shared by all test types
@ -20,8 +17,11 @@ return [
'urlManager' => [
'showScriptName' => true,
],
'user' => [
'identityClass' => 'app\models\User',
],
'request' => [
// it's not recommended to run functional tests with CSRF validation enabled
'cookieValidationKey' => 'test',
'enableCsrfValidation' => false,
// but if you absolutely need it set cookie domain to localhost
/*

6
config/test_db.php Normal file
View File

@ -0,0 +1,6 @@
<?php
$db = require(__DIR__ . '/db.php');
// test database! Important not to run tests on production or development databases
$db['dsn'] = 'mysql:host=localhost;dbname=yii2_basic_tests';
return $db;

View File

@ -1,128 +0,0 @@
This directory contains various tests for the basic application.
Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/).
After creating the basic application, follow these steps to prepare for the tests:
1. Install Codeception if it's not yet installed:
```
composer global require "codeception/codeception=2.0.*"
composer global require "codeception/specify=*"
composer global require "codeception/verify=*"
```
If you've never used Composer for global packages run `composer global status`. It should output:
```
Changed current directory to <directory>
```
Then add `<directory>/vendor/bin` to you `PATH` environment variable. Now we're able to use `codecept` from command
line globally.
2. Install faker extension by running the following from template root directory where `composer.json` is:
```
composer require --dev "yiisoft/yii2-faker:*"
```
3. Create `yii2_basic_tests` database and update it by applying migrations (you may skip this step if you do not have created any migrations yet):
```
cd tests
codeception/bin/yii migrate
```
The command needs to be run in the `tests` directory.
The database configuration can be found at `tests/codeception/config/config.php`.
4. Build the test suites:
```
codecept build
```
5. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use built-in Yii
command:
```
./yii serve
```
6. Now you can run the tests with the following commands:
```
# run all available tests
codecept run
# run acceptance tests
codecept run acceptance
# run functional tests
codecept run functional
# run unit tests
codecept run unit
```
Fixtures Default Configuration
------------------------------
The `fixture` commands refer to the following `ActiveFixture` configuration by default:
- Fixtures path: `@tests/unit/fixtures`
- Fixtures data path: `@tests/unit/fixtures/data`
- Template files path: `@tests/unit/templates/fixtures`
- Namespace: `tests\unit\fixtures`
Where `@tests` refers to `@app/tests/codeception`.
Code coverage support
---------------------
By default, code coverage is disabled in `codeception.yml` configuration file, you should uncomment needed rows to be able
to collect code coverage. You can run your tests and collect coverage with the following command:
```
#collect coverage for all tests
codecept run --coverage-html --coverage-xml
#collect coverage only for unit tests
codecept run unit --coverage-html --coverage-xml
#collect coverage for unit and functional tests
codecept run functional,unit --coverage-html --coverage-xml
```
You can see code coverage output under the `tests/_output` directory.
###Remote code coverage
When you run your tests not in the same process where code coverage is collected, then you should uncomment `remote` option and its
related options, to be able to collect code coverage correctly. To setup remote code coverage you should follow [instructions](http://codeception.com/docs/11-Codecoverage)
from codeception site.
1. install `Codeception c3` remote support `composer require "codeception/c3:*"`;
2. copy `c3.php` file under your `web` directory;
3. include `c3.php` file in your `index-test.php` file before application run, so it can catch needed requests.
4. edit `c3.php` to update config file path (~ line 55) with `$config_file = realpath(__DIR__ . '/../tests/codeception.yml');`
Configuration options that are used by remote code coverage:
- c3_url: url pointing to entry script that includes `c3.php` file, so `Codeception` will be able to produce code coverage;
- remote: whether to enable remote code coverage or not;
- remote_config: path to the `codeception.yml` configuration file, from the directory where `c3.php` file is located. This is needed
so that `Codeception` can create itself instance and collect code coverage correctly.
By default `c3_url` and `remote_config` setup correctly, you only need to copy and include `c3.php` file in your `index-test.php`
After that you should be able to collect code coverage from tests that run through `PhpBrowser` or `WebDriver` with same command
as for other tests:
```
#collect coverage from remote
codecept run acceptance --coverage-html --coverage-xml
```
Please refer to [Codeception tutorial](http://codeception.com/docs/01-Introduction) for
more details about writing and running acceptance, functional and unit tests.

View File

@ -1,10 +1,8 @@
<?php
require_once(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
define('YII_ENV', 'test');
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
$_SERVER['SCRIPT_FILENAME'] = codecept_root_dir() . '/web/index.php';
$_SERVER['SCRIPT_NAME'] = 'http://localhost:8080/index-test.php';
require_once(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
require __DIR__ .'/../vendor/autoload.php';
\Codeception\Specify\Config::setDeepClone(false);

View File

@ -1,14 +0,0 @@
<?php
namespace tests\codeception\_pages;
use yii\codeception\BasePage;
/**
* Represents about page
* @property \AcceptanceTester|\FunctionalTester $actor
*/
class AboutPage extends BasePage
{
public $route = 'site/about';
}

View File

@ -1,26 +0,0 @@
<?php
namespace tests\codeception\_pages;
use yii\codeception\BasePage;
/**
* Represents contact page
* @property \AcceptanceTester|\FunctionalTester $actor
*/
class ContactPage extends BasePage
{
public $route = 'site/contact';
/**
* @param array $contactData
*/
public function submit(array $contactData)
{
foreach ($contactData as $field => $value) {
$inputType = $field === 'body' ? 'textarea' : 'input';
$this->actor->fillField($inputType . '[name="ContactForm[' . $field . ']"]', $value);
}
$this->actor->click('contact-button');
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace tests\codeception\_pages;
use yii\codeception\BasePage;
/**
* Represents login page
* @property \AcceptanceTester|\FunctionalTester $actor
*/
class LoginPage extends BasePage
{
public $route = 'site/login';
/**
* @param string $username
* @param string $password
*/
public function login($username, $password)
{
$this->actor->fillField('input[name="LoginForm[username]"]', $username);
$this->actor->fillField('input[name="LoginForm[password]"]', $password);
$this->actor->click('login-button');
}
}

View File

@ -20,7 +20,4 @@ class FunctionalTester extends \Codeception\Actor
{
use _generated\FunctionalTesterActions;
/**
* Define custom actions here
*/
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
<?php //[STAMP] 7d7cf724fdb83651f402d30bb414a1e4
<?php //[STAMP] 0371e992067f9f6926df379e8e9c6bd6
namespace _generated;
// This class was automatically generated by build task

View File

@ -1,4 +1,4 @@
<?php //[STAMP] 5277d920e2dff79e69b22748b3b5c29b
<?php //[STAMP] 511934dbe87dbbd3a10594f1137bfa92
namespace _generated;
// This class was automatically generated by build task

View File

@ -1,27 +1,9 @@
# Codeception Test Suite Configuration
# suite for acceptance tests.
# perform tests in browser using the Selenium-like tools.
# powered by Mink (http://mink.behat.org).
# (tip: that's what your customer will see).
# (tip: test your ajax and javascript by one of Mink drivers).
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser
# you can use WebDriver instead of PhpBrowser to test javascript and ajax.
# This will require you to install selenium. See http://codeception.com/docs/03-AcceptanceTests#selenium-webdriver
# "restart" option is used by the WebDriver to start each time per test-file new session and cookies,
# it is useful if you want to login in your app in each test.
# - WebDriver
config:
PhpBrowser:
# PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO
url: http://localhost:8080
# WebDriver:
# url: http://localhost:8080
# browser: firefox
# restart: true
- WebDriver:
url: http://127.0.0.1:8080/
browser: firefox
- Yii2:
part: orm
entryScript: index-test.php

View File

@ -1,10 +0,0 @@
<?php
use tests\codeception\_pages\AboutPage;
/* @var $scenario Codeception\Scenario */
$I = new AcceptanceTester($scenario);
$I->wantTo('ensure that about works');
AboutPage::openBy($I);
$I->see('About', 'h1');

View File

@ -1,11 +1,12 @@
<?php
use yii\helpers\Url as Url;
class AboutCest
{
public function ensureThatAboutWorks(AcceptanceTester $I)
{
//$I->amOnPage(['site/about']);
$I->amOnPage('index.php?r=site%2Fabout');
$I->amOnPage(Url::toRoute('/site/about'));
$I->pauseExecution();
$I->see('About', 'h1');
}
}

View File

@ -1,57 +0,0 @@
<?php
use tests\codeception\_pages\ContactPage;
/* @var $scenario Codeception\Scenario */
$I = new AcceptanceTester($scenario);
$I->wantTo('ensure that contact works');
$contactPage = ContactPage::openBy($I);
$I->see('Contact', 'h1');
$I->amGoingTo('submit contact form with no data');
$contactPage->submit([]);
if (method_exists($I, 'wait')) {
$I->wait(3); // only for selenium
}
$I->expectTo('see validations errors');
$I->see('Contact', 'h1');
$I->see('Name cannot be blank');
$I->see('Email cannot be blank');
$I->see('Subject cannot be blank');
$I->see('Body cannot be blank');
$I->see('The verification code is incorrect');
$I->amGoingTo('submit contact form with not correct email');
$contactPage->submit([
'name' => 'tester',
'email' => 'tester.email',
'subject' => 'test subject',
'body' => 'test content',
'verifyCode' => 'testme',
]);
if (method_exists($I, 'wait')) {
$I->wait(3); // only for selenium
}
$I->expectTo('see that email address is wrong');
$I->dontSee('Name cannot be blank', '.help-inline');
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
$I->dontSee('The verification code is incorrect', '.help-inline');
$I->amGoingTo('submit contact form with correct data');
$contactPage->submit([
'name' => 'tester',
'email' => 'tester@example.com',
'subject' => 'test subject',
'body' => 'test content',
'verifyCode' => 'testme',
]);
if (method_exists($I, 'wait')) {
$I->wait(3); // only for selenium
}
$I->dontSeeElement('#contact-form');
$I->see('Thank you for contacting us. We will respond to you as soon as possible.');

View File

@ -1,13 +1,12 @@
<?php
/**
* Class ContactCest
*/
use yii\helpers\Url as Url;
class ContactCest
{
public function _before(\AcceptanceTester $I)
{
$I->amOnPage('index-test.php?r=site%2Fcontact');
$I->amOnPage(Url::toRoute('/site/contact'));
}
public function contactPageWorks(AcceptanceTester $I)
@ -27,6 +26,8 @@ class ContactCest
$I->click('contact-button');
$I->wait(2); // wait for button to be clicked
$I->dontSeeElement('#contact-form');
$I->see('Thank you for contacting us. We will respond to you as soon as possible.');
}

View File

@ -1,11 +0,0 @@
<?php
/* @var $scenario Codeception\Scenario */
$I = new AcceptanceTester($scenario);
$I->wantTo('ensure that home page works');
$I->amOnPage(Yii::$app->homeUrl);
$I->see('My Company');
$I->seeLink('About');
$I->click('About');
$I->see('This is the About page.');

View File

@ -4,7 +4,6 @@ class HomeCest
{
public function ensureThatHomePageWorks(AcceptanceTester $I)
{
//$I->amOnPage(Yii::$app->homeUrl);
$I->amOnPage('index.php?r=site%2Findex');
$I->see('My Company');

View File

@ -1,37 +0,0 @@
<?php
use tests\codeception\_pages\LoginPage;
/* @var $scenario Codeception\Scenario */
$I = new AcceptanceTester($scenario);
$I->wantTo('ensure that login works');
$loginPage = LoginPage::openBy($I);
$I->see('Login', 'h1');
$I->amGoingTo('try to login with empty credentials');
$loginPage->login('', '');
if (method_exists($I, 'wait')) {
$I->wait(3); // only for selenium
}
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
$I->amGoingTo('try to login with wrong credentials');
$loginPage->login('admin', 'wrong');
if (method_exists($I, 'wait')) {
$I->wait(3); // only for selenium
}
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
$I->amGoingTo('try to login with correct credentials');
$loginPage->login('admin', 'admin');
if (method_exists($I, 'wait')) {
$I->wait(3); // only for selenium
}
$I->expectTo('see user info');
$I->see('Logout (admin)');

View File

@ -1,19 +1,20 @@
<?php
use yii\helpers\Url as Url;
class LoginCest
{
public function ensureThatLoginWorks(AcceptanceTester $I)
{
//$I->amOnPage(['site/login']);
$I->amOnPage('index.php?r=site%2Flogin');
$I->amOnPage(Url::toRoute('/site/login'));
$I->see('Login', 'h1');
$I->amGoingTo('try to login with correct credentials');
$I->fillField('input[name="LoginForm[username]"]', 'admin');
$I->fillField('input[name="LoginForm[password]"]', 'admin');
$I->click('login-button');
$I->wait(2); // wait for button to be clicked
$I->expectTo('see user info');
$I->see('Logout (admin)');
$I->see('Logout');
}
}

View File

@ -1,2 +1 @@
<?php
new yii\web\Application(require(dirname(__DIR__) . '/config/acceptance.php'));

View File

@ -1,10 +0,0 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
defined('YII_APP_BASE_PATH') or define('YII_APP_BASE_PATH', dirname(dirname(dirname(__DIR__))));
require(YII_APP_BASE_PATH . '/vendor/autoload.php');
require(YII_APP_BASE_PATH . '/vendor/yiisoft/yii2/Yii.php');
Yii::setAlias('@tests', dirname(dirname(__DIR__)));

15
tests/bin/yii Normal file → Executable file
View File

@ -8,13 +8,22 @@
* @license http://www.yiiframework.com/license/
*/
require_once __DIR__ . '/_bootstrap.php';
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
require(__DIR__ . '/vendor/autoload.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
$config = yii\helpers\ArrayHelper::merge(
require(YII_APP_BASE_PATH . '/config/console.php'),
require(__DIR__ . '/../config/config.php')
require(__DIR__ . '/config/console.php'),
[
'components' => [
'db' => require(__DIR__ . '/config/test_db.php')
]
]
);
$application = new yii\console\Application($config);
$exitCode = $application->run();
exit($exitCode);

View File

@ -1,4 +0,0 @@
# these files are auto generated by codeception build
/unit/UnitTester.php
/functional/FunctionalTester.php
/acceptance/AcceptanceTester.php

View File

@ -1,26 +0,0 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
use _generated\AcceptanceTesterActions;
/**
* Define custom actions here
*/
}

View File

@ -1,26 +0,0 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class FunctionalTester extends \Codeception\Actor
{
use _generated\FunctionalTesterActions;
/**
* Define custom actions here
*/
}

View File

@ -1,26 +0,0 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
*
* @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
use _generated\UnitTesterActions;
/**
* Define custom actions here
*/
}

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -1,29 +0,0 @@
# Codeception Test Suite Configuration
# suite for acceptance tests.
# perform tests in browser using the Selenium-like tools.
# powered by Mink (http://mink.behat.org).
# (tip: that's what your customer will see).
# (tip: test your ajax and javascript by one of Mink drivers).
# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.
class_name: AcceptanceTester
modules:
enabled:
- PhpBrowser
# - Yii2:
# configFile: '/codeception/config/acceptance.php'
# you can use WebDriver instead of PhpBrowser to test javascript and ajax.
# This will require you to install selenium. See http://codeception.com/docs/03-AcceptanceTests#selenium-webdriver
# "restart" option is used by the WebDriver to start each time per test-file new session and cookies,
# it is useful if you want to login in your app in each test.
# - WebDriver
config:
PhpBrowser:
# PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO
url: http://localhost:8080
# WebDriver:
# url: http://localhost:8080
# browser: firefox
# restart: true

View File

@ -1,11 +0,0 @@
<?php
/**
* Application configuration for acceptance tests
*/
return yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../config/web.php'),
require(__DIR__ . '/config.php'),
[
]
);

View File

@ -1,22 +0,0 @@
<?php
/**
* Application configuration for functional tests
*/
return yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../config/web.php'),
require(__DIR__ . '/config.php'),
[
'components' => [
'request' => [
// it's not recommended to run functional tests with CSRF validation enabled
'enableCsrfValidation' => false,
// but if you absolutely need it set cookie domain to localhost
/*
'csrfCookie' => [
'domain' => 'localhost',
],
*/
],
],
]
);

View File

@ -1,11 +0,0 @@
<?php
/**
* Application configuration for unit tests
*/
return yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../config/web.php'),
require(__DIR__ . '/config.php'),
[
]
);

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -10,5 +10,4 @@ class_name: FunctionalTester
modules:
enabled:
- Filesystem
- Yii2:
configFile: 'config/test.php'
- Yii2

View File

@ -1,10 +0,0 @@
<?php
use tests\codeception\_pages\AboutPage;
/* @var $scenario Codeception\Scenario */
$I = new FunctionalTester($scenario);
$I->wantTo('ensure that about works');
AboutPage::openBy($I);
$I->see('About', 'h1');

View File

@ -1,48 +0,0 @@
<?php
use tests\codeception\_pages\ContactPage;
/* @var $scenario Codeception\Scenario */
$I = new FunctionalTester($scenario);
$I->wantTo('ensure that contact works');
$contactPage = ContactPage::openBy($I);
$I->see('Contact', 'h1');
$I->amGoingTo('submit contact form with no data');
$contactPage->submit([]);
$I->expectTo('see validations errors');
$I->see('Contact', 'h1');
$I->see('Name cannot be blank');
$I->see('Email cannot be blank');
$I->see('Subject cannot be blank');
$I->see('Body cannot be blank');
$I->see('The verification code is incorrect');
$I->amGoingTo('submit contact form with not correct email');
$contactPage->submit([
'name' => 'tester',
'email' => 'tester.email',
'subject' => 'test subject',
'body' => 'test content',
'verifyCode' => 'testme',
]);
$I->expectTo('see that email address is wrong');
$I->dontSee('Name cannot be blank', '.help-inline');
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
$I->dontSee('The verification code is incorrect', '.help-inline');
$I->amGoingTo('submit contact form with correct data');
$contactPage->submit([
'name' => 'tester',
'email' => 'tester@example.com',
'subject' => 'test subject',
'body' => 'test content',
'verifyCode' => 'testme',
]);
$I->dontSeeElement('#contact-form');
$I->see('Thank you for contacting us. We will respond to you as soon as possible.');

View File

@ -0,0 +1,55 @@
<?php
class ContactFormCest
{
public function _before(\FunctionalTester $I)
{
$I->amOnPage(['site/contact']);
}
public function openContactPage(\FunctionalTester $I)
{
$I->see('Contact', 'h1');
}
public function submitEmptyForm(\FunctionalTester $I)
{
$I->submitForm('#contact-form', []);
$I->expectTo('see validations errors');
$I->see('Contact', 'h1');
$I->see('Name cannot be blank');
$I->see('Email cannot be blank');
$I->see('Subject cannot be blank');
$I->see('Body cannot be blank');
$I->see('The verification code is incorrect');
}
public function submitFormWithIncorrectEmail(\FunctionalTester $I)
{
$I->submitForm('#contact-form', [
'ContactForm[name]' => 'tester',
'ContactForm[email]' => 'tester.email',
'ContactForm[subject]' => 'test subject',
'ContactForm[body]' => 'test content',
'ContactForm[verifyCode]' => 'testme',
]);
$I->expectTo('see that email address is wrong');
$I->dontSee('Name cannot be blank', '.help-inline');
$I->see('Email is not a valid email address.');
$I->dontSee('Subject cannot be blank', '.help-inline');
$I->dontSee('Body cannot be blank', '.help-inline');
$I->dontSee('The verification code is incorrect', '.help-inline');
}
public function submitFormSuccessfully(\FunctionalTester $I)
{
$I->submitForm('#contact-form', [
'ContactForm[name]' => 'tester',
'ContactForm[email]' => 'tester@example.com',
'ContactForm[subject]' => 'test subject',
'ContactForm[body]' => 'test content',
'ContactForm[verifyCode]' => 'testme',
]);
$I->dontSeeElement('#contact-form');
$I->see('Thank you for contacting us. We will respond to you as soon as possible.');
}
}

View File

@ -1,11 +0,0 @@
<?php
/* @var $scenario Codeception\Scenario */
$I = new FunctionalTester($scenario);
$I->wantTo('ensure that home page works');
$I->amOnPage(Yii::$app->homeUrl);
$I->see('My Company');
$I->seeLink('About');
$I->click('About');
$I->see('This is the About page.');

View File

@ -1,28 +0,0 @@
<?php
use tests\codeception\_pages\LoginPage;
/* @var $scenario Codeception\Scenario */
$I = new FunctionalTester($scenario);
$I->wantTo('ensure that login works');
$loginPage = LoginPage::openBy($I);
$I->see('Login', 'h1');
$I->amGoingTo('try to login with empty credentials');
$loginPage->login('', '');
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
$I->amGoingTo('try to login with wrong credentials');
$loginPage->login('admin', 'wrong');
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
$I->amGoingTo('try to login with correct credentials');
$loginPage->login('admin', 'admin');
$I->expectTo('see user info');
$I->see('Logout (admin)');

View File

@ -0,0 +1,41 @@
<?php
class LoginFormCest
{
public function _before(\FunctionalTester $I)
{
$I->amOnPage(['site/login']);
}
public function openLoginPage(\FunctionalTester $I)
{
$I->see('Login', 'h1');
}
public function loginWithEmptyCredentials(\FunctionalTester $I)
{
$I->submitForm('#login-form', []);
$I->expectTo('see validations errors');
$I->see('Username cannot be blank.');
$I->see('Password cannot be blank.');
}
public function loginWithWringCredentials(\FunctionalTester $I)
{
$I->submitForm('#login-form', [
'LoginForm[username]' => 'admin',
'LoginForm[password]' => 'wrong',
]);
$I->expectTo('see validations errors');
$I->see('Incorrect username or password.');
}
public function loginSuccessfully(\FunctionalTester $I)
{
$I->submitForm('#login-form', [
'LoginForm[username]' => 'admin',
'LoginForm[password]' => 'admin',
]);
$I->see('Logout (admin)');
$I->dontSeeElement('form#login-form');
}
}

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -8,5 +8,4 @@ modules:
enabled:
- Asserts
- Yii2:
configFile: 'config/test.php'
part: orm

View File

@ -1,63 +1,56 @@
<?php
namespace tests\codeception\unit\models;
namespace tests\models;
use app\models\ContactForm;
use Yii;
use yii\codeception\TestCase;
use Codeception\Specify;
class ContactFormTest extends TestCase
class ContactFormTest extends \Codeception\Test\Unit
{
use Specify;
private $model;
protected function setUp()
protected function _before()
{
parent::setUp();
Yii::$app->mailer->fileTransportCallback = function ($mailer, $message) {
\Yii::$app->mailer->fileTransportCallback = function () {
return 'testing_message.eml';
};
}
protected function tearDown()
protected function _after()
{
unlink($this->getMessageFile());
parent::tearDown();
}
public function testContact()
public function testEmailIsSentOnContact()
{
/** @var ContactForm $model */
$model = $this->getMockBuilder('app\models\ContactForm')
$this->model = $this->getMockBuilder('app\models\ContactForm')
->setMethods(['validate'])
->getMock();
$model->expects($this->once())->method('validate')->will($this->returnValue(true));
$model->attributes = [
$this->model->expects($this->once())
->method('validate')
->will($this->returnValue(true));
$this->model->attributes = [
'name' => 'Tester',
'email' => 'tester@example.com',
'subject' => 'very important letter subject',
'body' => 'body of current message',
];
$this->specify('email should be send', function () use ($model) {
expect('ContactForm::contact() should return true', $model->contact('admin@example.com'))->true();
expect('email file should exist', file_exists($this->getMessageFile()))->true();
});
expect_that($this->model->contact('admin@example.com'));
expect_that(file_exists($this->getMessageFile()));
$this->specify('message should contain correct data', function () use ($model) {
$emailMessage = file_get_contents($this->getMessageFile());
$emailMessage = file_get_contents($this->getMessageFile());
expect('email should contain user name', $emailMessage)->contains($model->name);
expect('email should contain sender email', $emailMessage)->contains($model->email);
expect('email should contain subject', $emailMessage)->contains($model->subject);
expect('email should contain body', $emailMessage)->contains($model->body);
});
expect($emailMessage)->contains($this->model->name);
expect($emailMessage)->contains($this->model->email);
expect($emailMessage)->contains($this->model->subject);
expect($emailMessage)->contains($this->model->body);
}
private function getMessageFile()
{
return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml';
return \Yii::getAlias(\Yii::$app->mailer->fileTransportPath) . '/testing_message.eml';
}
}

View File

@ -1,61 +1,52 @@
<?php
namespace tests\codeception\unit\models;
namespace tests\models;
use Yii;
use yii\codeception\TestCase;
use app\models\LoginForm;
use Codeception\Specify;
class LoginFormTest extends TestCase
class LoginFormTest extends \Codeception\Test\Unit
{
use Specify;
private $model;
protected function tearDown()
protected function _after()
{
Yii::$app->user->logout();
parent::tearDown();
\Yii::$app->user->logout();
}
public function testLoginNoUser()
{
$model = new LoginForm([
$this->model = new LoginForm([
'username' => 'not_existing_username',
'password' => 'not_existing_password',
]);
$this->specify('user should not be able to login, when there is no identity', function () use ($model) {
expect('model should not login user', $model->login())->false();
expect('user should not be logged in', Yii::$app->user->isGuest)->true();
});
expect_not($this->model->login());
expect_that(\Yii::$app->user->isGuest);
}
public function testLoginWrongPassword()
{
$model = new LoginForm([
$this->model = new LoginForm([
'username' => 'demo',
'password' => 'wrong_password',
]);
$this->specify('user should not be able to login with wrong password', function () use ($model) {
expect('model should not login user', $model->login())->false();
expect('error message should be set', $model->errors)->hasKey('password');
expect('user should not be logged in', Yii::$app->user->isGuest)->true();
});
expect_not($this->model->login());
expect_that(\Yii::$app->user->isGuest);
expect($this->model->errors)->hasKey('password');
}
public function testLoginCorrect()
{
$model = new LoginForm([
$this->model = new LoginForm([
'username' => 'demo',
'password' => 'demo',
]);
$this->specify('user should be able to login with correct credentials', function () use ($model) {
expect('model should login user', $model->login())->true();
expect('error message should not be set', $model->errors)->hasntKey('password');
expect('user should be logged in', Yii::$app->user->isGuest)->false();
});
expect_that($this->model->login());
expect_not(\Yii::$app->user->isGuest);
expect($this->model->errors)->hasntKey('password');
}
}

View File

@ -1,17 +1,43 @@
<?php
namespace tests\models;
use app\models\User;
namespace tests\codeception\unit\models;
use yii\codeception\TestCase;
class UserTest extends TestCase
class UserTest extends \Codeception\Test\Unit
{
protected function setUp()
public function testFindUserById()
{
parent::setUp();
// uncomment the following to load fixtures for user table
//$this->loadFixtures(['user']);
expect_that($user = User::findIdentity(100));
expect($user->username)->equals('admin');
expect_not(User::findIdentity(999));
}
public function testFindUserByAccessToken()
{
expect_that($user = User::findIdentityByAccessToken('100-token'));
expect($user->username)->equals('admin');
expect_not(User::findIdentityByAccessToken('non-existing'));
}
public function testFindUserByUsername()
{
expect_that($user = User::findByUsername('admin'));
expect_not(User::findByUsername('not-admin'));
}
/**
* @depends testFindUserByUsername
*/
public function testValidateUser($user)
{
$user = User::findByUsername('admin');
expect_that($user->validateAuthKey('test100key'));
expect_not($user->validateAuthKey('test102key'));
expect_that($user->validatePassword('admin'));
expect_not($user->validatePassword('123456'));
}
// TODO add test methods here
}

View File

@ -11,6 +11,6 @@ defined('YII_ENV') or define('YII_ENV', 'test');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
$config = require(__DIR__ . '/../tests/codeception/config/acceptance.php');
$config = require(__DIR__ . '/../config/test.php');
(new yii\web\Application($config))->run();