Codeception 2.1.2: Проверка ответа AJAX-запроса

Всем привет,

Не так давно открыл для себя Codeception и вот пытаюсь научиться работать с ним.

Я хочу написать функциональный тест, который проверит регистрацию на сайте.

Форма отправляется AJAX-запросом, поэтому мой приемочный тест выглядит вот так:

<?php
use \AcceptanceTester;

class RegisterCest {

    public function _before(AcceptanceTester $I){}

    public function _after(AcceptanceTester $I){}

    public function canRegisterWithCorrectCredentials(AcceptanceTester $I) {
        $I->wantTo('ensure that user can register in the system and can be redirected to the thank you page');
        $I->amOnPage(\Page\UserAuth::$registerPageUrl);

        $newUserEmail = \Page\UserAuth::getNewUserEmailAddress();

        $I->fillField('email', $newUserEmail);
        $I->fillField('password', \Page\UserAuth::$correctTestUserPassword);
        $I->uncheckOption('#chkRemember');

        $I->click(\Page\UserAuth::$normalSubmitButton);

        $newUserId = $I->grabFromDatabase('users', 'id', array('email' => $newUserEmail));

        $I->dontSeeCookie('remember_me');
        $I->seeInDatabase('users', array('email' => $newUserEmail, 'is_email_confirmed' => 0));
        $I->seeInDatabase('users_roles', array('user_id' => $newUserId, 'role_id' => 2));
        $I->seeInCurrentUrl('thanks');
    }
}

acceptance.suite.yml выглядит следующим образом:

class_name: AcceptanceTester
modules:
    enabled:
        - \Helper\Acceptance
        - WebDriver:
            url: 'http://site.dev'
            browser: chrome
            window_size: 1920x1080
            wait: 10
        - Db

functional.suite.yml имеет слудющий вид:

class_name: FunctionalTester
modules:
    enabled:
        - PhpBrowser:
            url: 'http://site.dev'
    - \Helper\Functional
    - Db
    - REST

А тест:

<?php
use \FunctionalTester;

class RegisterCest{

    public function _before(FunctionalTester $I){}

    public function _after(FunctionalTester $I){}

    public function canRegisterWithCorrectCredentials(FunctionalTester $I) {
        $I->wantTo('ensure that user can register with correct credentials');
        $registrationParams = array(
            'email' => time().'_'.\Page\UserAuth::$correctTestUserEmail,
            'password' => \Page\UserAuth::$correctTestUserPassword
        );

        $I->sendAjaxPostRequest(\Page\UserAuth::$registerPageUrl, $registrationParams);
        $I->seeResponseContainsJson(array('redirectTo' => '/thanks'));
    }
}

При запуске этого теста в консоли я получаю вот такую ошибку:

There was 1 failure:

---------
1) Failed to ensure that user can register with correct credentials in RegisterC
est::canRegisterWithCorrectCredentials (tests\functional\RegisterCest.php)

 Step  I see response contains json {"redirectTo":"/thanks"}
 Fail  Response JSON contains provided
    - array (
        'redirectTo' => '/thanks',
    )
    + NULL
Failed asserting that false is true.

    Scenario Steps:

 2. $I->seeResponseContainsJson({"redirectTo":"/thanks"})
 1. $I->sendAjaxPostRequest("register",{"email":"1461586358_AcceptanceTestUser@r
m.dev","password":"QwertyUiop"})


FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

А вот JSON-ответ, который я получаю в броузере:

{"status":true,"messages":[],"redirectTo":"\/thanks"}

Версия Codeception: Codeception PHP Testing Framework v2.1.2

Для конкретно этого теста я смогу использовать какой-то обходной путь, но мне бы хотелось разобраться, как правильно работать с ответом AJAX-запроса.

Спасибо

Ну тут скорее надо поработать над запросом а не над ответом. Т.к. строка "+ NULL " говорит о том что в ответе пришло NULL.
Я бы попробовал использовать метод executeJS и напсать запрос на JS

Не, тут такой номер не пройдет, это REST запросы, браузер не участвует вообще.

pvk, а что в консоли после этого шага (–steps)
$I->sendAjaxPostRequest(\Page\UserAuth::$registerPageUrl, $registrationParams); ?

Добавил логирование.
Вот такой JSON генерирует моё приложение:

{"status":true,"messages":[],"redirectTo":"\/thanks"}

@RayRom, вот полный лог после выполнения этого теста:

Codeception PHP Testing Framework v2.1.2
Powered by PHPUnit 4.8.2 by Sebastian Bergmann and contributors.
PHP Warning:  The use statement with non-compound name 'FunctionalTester' has no
 effect in D:\workspace\RM2\vendor\Codeception-2.1.2\tests\functional\RegisterCe
st.php on line 2

Warning: The use statement with non-compound name 'FunctionalTester' has no effe
ct in D:\workspace\RM2\vendor\Codeception-2.1.2\tests\functional\RegisterCest.ph
p on line 2

Functional Tests (1) -----------------------------------------------------------
--------------------------------------------------------------------------
Ensure that user can register with correct credentials (RegisterCest::canRegiste
rWithCorrectCredentials)                                             Fail
--------------------------------------------------------------------------------
--------------------------------------------------------------------------


Time: 5.78 seconds, Memory: 13.50Mb

There was 1 failure:

---------
1) Failed to ensure that user can register with correct credentials in RegisterC
est::canRegisterWithCorrectCredentials (tests\functional\RegisterCest.php)

 Step  I see response contains json {"redirectTo":"thanks"}
 Fail  Response JSON contains provided
- array (
  'redirectTo' => 'thanks',
)
+ NULL
Failed asserting that false is true.

Scenario Steps:

 2. $I->seeResponseContainsJson({"redirectTo":"thanks"})
 1. $I->sendAjaxPostRequest("register",{"email":"1461589113_AcceptanceTestUser@r
m.dev","password":"Password123"})


FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

Не уверен что поможет, но попробуй добавить “/”
$I->sendAjaxPostRequest("/register",{“email”:“1461589113_AcceptanceTestUser@r
m.dev”,“password”:“Password123”})

Лог не полный, я специально пометил

(–steps)
т.е. запустить тест с этой опцией
пример
$ codecept run functional RegisterCest --debug --steps

1 лайк

@Ugin_Berets, нет, это не помогло.

@RayRom, сразу не понял :(. Вот полный лог с указанными опциями:

Codeception PHP Testing Framework v2.1.2
Powered by PHPUnit 4.8.2 by Sebastian Bergmann and contributors.

    Warning: The use statement with non-compound name 'FunctionalTester' has no effect in D:\workspace\RM2\vendor\Codeception-2.1.2\tests\functional\RegisterCest.php on line 2

Functional Tests (1) -------------------------------------------------------------------------------------------------------------------------------------
    Modules: PhpBrowser, \Helper\Functional, Db, REST
----------------------------------------------------------------------------------------------------------------------------------------------------------
    Ensure that user can register with correct credentials (RegisterCest::canRegisterWithCorrectCredentials)
Scenario:
    * I send ajax post request "register",{"email":"1461592039_AcceptanceTestUser@rm.dev","password":"Password123"}

    [Response] 200
    [Page] http://rm2.dev/register
    [Cookies] []
        [Headers] {"Date":["Mon, 25 Apr 2016 13:47:19 GMT"],"Server":["Apache/2.4.12 (Win64) PHP/5.5.25"],"X-Powered-By":["Ridna Mova"],"X-Content-Type-Options":["nosniff"],"X-Frame-Options":["SAMEORIGIN"],"X-XSS-Protection":["1; mode=block"],"Cache-Control":["no-cache, no-store, must-revalidate"],"Set-Cookie":["just_registered=bc08a2606b6c51e6169a46cb5d9ba4b7; path=/; domain=rm2.dev; httponly"],"Content-Length":["56"],"Content-Type":["application/json"]}
* I see response contains json {"redirectTo":"thanks"}
FAIL

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
----------------------------------------------------------------------------------------------------------------------------------------------------------


    Time: 6.13 seconds, Memory: 13.50Mb

There was 1 failure:

    ---------
        1) Failed to ensure that user can register with correct credentials in RegisterCest::canRegisterWithCorrectCredentials (tests\functional\RegisterCest.php)

Step  I see response contains json {"redirectTo":"thanks"}
Fail  Response JSON contains provided
    - array (
    'redirectTo' => 'thanks',
)
+ NULL
Failed asserting that false is true.

    Scenario Steps:

    2. $I->seeResponseContainsJson({"redirectTo":"thanks"})
1. $I->sendAjaxPostRequest("register",{"email":"1461592039_AcceptanceTestUser@rm.dev","password":"Password123"})


FAILURES!
    Tests: 1, Assertions: 1, Failures: 1.

Как видишь, нет того, что проверяешь в следующем шаге :frowning:

1 лайк

@RayRom, точно, спасибо!

Для чистоты эксперимента я попробовал обратиться к JSON-файлу, который никак не связан с другими фреймворками/приложениями, но результат остался тем же:

Codeception PHP Testing Framework v2.1.2
Powered by PHPUnit 4.8.2 by Sebastian Bergmann and contributors.

Warning: The use statement with non-compound name 'FunctionalTester' has no effect in D:\workspace\RM2\vendor\Codeception-2.1.2\tests\functional\RegisterCest.php on line 2

Functional Tests (1) -------------------------------------------------------------------------------------------------------------------------------------
Modules: PhpBrowser, \Helper\Functional, Db, REST
----------------------------------------------------------------------------------------------------------------------------------------------------------
Ensure that user can register with correct credentials (RegisterCest::canRegisterWithCorrectCredentials)
Scenario:
* I send ajax post request "test.json",{"email":"1461665270_AcceptanceTestUser@rm.dev","password":"Password123"}

  [Response] 200
  [Page] http://localhost/tmp/test.json
  [Cookies] []
  [Headers] {"Date":["Tue, 26 Apr 2016 10:07:50 GMT"],"Server":["Apache/2.4.12 (Win64) PHP/5.5.25"],"Last-Modified":["Tue, 26 Apr 2016 10:05:22 GMT"],"ETag":[""36-531606e61233b""],"Accept-Ranges":["bytes"],"Content-Length":["54"],"Content-Type":["application/json"]}
* I see response contains json {"redirectTo":"thanks"}
 FAIL 

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
----------------------------------------------------------------------------------------------------------------------------------------------------------


Time: 16.69 seconds, Memory: 13.50Mb

There was 1 failure:

---------
1) Failed to ensure that user can register with correct credentials in RegisterCest::canRegisterWithCorrectCredentials (tests\functional\RegisterCest.php)

 Step  I see response contains json {"redirectTo":"thanks"}
 Fail  Response JSON contains provided
- array (
  'redirectTo' => 'thanks',
)
+ NULL
Failed asserting that false is true.

Scenario Steps:

 2. $I->seeResponseContainsJson({"redirectTo":"thanks"})
 1. $I->sendAjaxPostRequest("test.json",{"email":"1461665270_AcceptanceTestUser@rm.dev","password":"Password123"})


FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

Эта команда не относится к REST модулю.
См REST - Codeception - Documentation

1 лайк

Да, вот такой вариант работает корректно:

public function canRegisterWithCorrectCredentials(FunctionalTester $I) {
    $I->wantTo('ensure that user can register with correct credentials');
    $registrationParams = array(
        'email' => time().'_'.\Page\UserAuth::$correctTestUserEmail,
        'password' => \Page\UserAuth::$correctTestUserPassword
    );

    $I->sendPOST('test.json', $registrationParams);
    $I->seeResponseContainsJson(array('redirectTo' => 'thanks'));
}

Получается, что средствами модуля PhpBrowser у меня нет возможности анализировать ответ сервера. Могу только отправить запрос: PhpBrowser - Codeception - Documentation

Почему, ты сейчас все правильно сделал, после $I->sendPOST ты проанализировал ответ через $I->seeResponseContainsJson

Не работает:

$I->sendAjaxPostRequest('test.json', $registrationParams);
$I->seeResponseContainsJson(array('redirectTo' => 'thanks'));

Работает:

$I->sendPOST('test.json', $registrationParams);
$I->seeResponseContainsJson(array('redirectTo' => 'thanks'));

sendAjaxPostRequest - находится в модуле PhpBrowser.
sendPOST - в модуле REST.
seeResponseContainsJson - тоже в модуле REST.

Я имел ввиду, что для того, чтобы проанализировать AJAX-ответ сервера необходимо использовать модуль REST. А использовать sendAjaxPostRequest (из модуля PhpBrowser) надо для каких-то других целей, т.к. внутри него я не нашел функций для анализа возвращаемого JSON-кода.

REST модуль использует PhpBrowser для себя изолированно, для анализа не только ответа сервера но и возможно возвращаемого контента.

Я разобрался, спасибо!