Today’s Objective(s)
Write a new acceptance test- Research best practices for acceptance/functional testing in Yii
Introduction
So today we write a new acceptance test. Nothing complicated, I just want to create a basic acceptance test to confirm a page shows the text ‘Hello’ and has a text field. And text inserted into the text field will be appended to the ‘Hello’ string.
The Acceptance Test
Made HelloCept.php in ~\tests\codeception\acceptance :
<?php /* @var $scenario Codeception\Scenario */ $I = new AcceptanceTester($scenario); $I->wantTo('ensure that say page displays "Hello"'); //$I->amOnPage(\yii\helpers\Url::to(['say/index'])); (Hoped to use this, but doesn't work) $I->amOnPage('index.php?r=say/index'); //used this for the time being $I->see('Hello'); $I->amGoingTo('submit form without an input'); $I->fillField('input[name="SayForm[string]"]', ''); $I->click('say-button'); if (method_exists($I, 'wait')) { $I->wait(3); // only for selenium } $I->see('Hello'); $I->amGoingTo('submit a string'); $I->fillField('input[name="SayForm[string]"]', 'World!'); $I->click('say-button'); if (method_exists($I, 'wait')) { $I->wait(3); // only for selenium } $I->expectTo('see updated string'); $I->see('Hello World!');
Now to make the controller, model and view for this.
Controller (~\controllers\SayController.php):
<?php namespace app\controllers; use Yii; use app\models\SayForm; class SayController extends \yii\web\Controller { public function actionIndex() { $model = new SayForm(); if (Yii::$app->request->isPost) { $model->load(Yii::$app->request->post()); } return $this->render('index',[ 'model' => $model ]); } }
Basic controller that will load our model if the request has POST variables (This should be validated, but that’s out of scope ).
Model (~\models\SayForm.php):
<?php namespace app\models; use Yii; use yii\base\Model; /** * SayForm is the model to hold hold our string. */ class SayForm extends Model { public $string; /** * simple rule set so that value is "safe" * @return array the validation rules. */ public function rules() { return [ ['string', 'string'], ]; } /** * Basic label for string value. * @return array customized attribute labels */ public function attributeLabels() { return [ 'string' => 'Say hello to what?', ]; } }
Also very basic, just has a public variable named $string which will be used in our view.
View (~\views\say\index.php):
<?php /* @var $this yii\web\View */ use yii\widgets\ActiveForm; ?> <h1>say/index</h1> <p> Hello<?= ($model->string ? ' ' . $model->string : '') ?> </p> <p> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'string') ?> <?= \yii\helpers\Html::submitButton('Submit', ['id' => 'say-button']) ?> <?php ActiveForm::end(); ?> </p>
Set the submit button to have an id of “say-button” (Since that is the button/link being clicked on in the acceptance test). And we append the string from SayModel to our ‘Hello’ string if there is a string to append.
And the acceptance test passes!
C:\wamp\www\codeception-test\tests>codecept run acceptance HelloCept Codeception PHP Testing Framework v2.0.12 Powered by PHPUnit 4.5.1 by Sebastian Bergmann and contributors. ←[1mAcceptance Tests (1) ←[22m---------------------------------------------------------------------------------------------------------------- ←[35;1mEnsure that say page displays "Hello"←[39;22m (HelloCept) Ok -------------------------------------------------------------------------------------------------------------------------------------
Now you can see what I mean about ugly outputs But it works, and this does seem to be a very easy method to confirm that pages do what they are supposed to.
I do find myself a bit troubled over complicated scenarios, but think that’s just me overthinking it all. So believe I’ve already thought of my next acceptance test
Conclusion
This form of acceptance testing is excellent in my opinion, the test itself is written in such a way that it’s simple to understand at a glance and could become very powerful with the right implementation.
Upcoming Objective(s)
- Get acceptance test to pull url without having to hardcode (ie. use a function instead of ‘index.php?r=site/index’)
- Write an acceptance test for functionality that uses a session.
- Research best practices for acceptance/functional testing in Yii