Spec-Zone.ru › Codeception

Использование повторного кода тестов

Codeception использует модульность для создания удобной среды тестирования для каждого набора тестов, который вы пишете. Модули позволяют вам выбирать действия и утверждения, которые могут выполняться в тестах.

Что такое Актеры

Все действия и утверждения, которые может выполнять объект Актера в классе, определены в модулях. Возможно, Codeception ограничит вас в тестировании, но это не так. Вы можете расширить набор тестов своими собственными действиями и утверждениями, написав их в пользовательском модуле, называемом Помощником. Мы вернемся к этому позже в этой главе, но сейчас давайте рассмотрим следующий тест:

<?php
$I->amOnPage('/');
$I->see('Hello');
$I->seeInDatabase('users', ['id' => 1]);
$I->seeFileFound('running.lock');

Он может работать с различными сущностями: веб-страницу можно загрузить с помощью модуля PhpBrowser, утверждение базы данных использует модуль Db, а состояние файла можно проверить с помощью модуля Filesystem.

Модули присоединяются к классам Актера в конфигурации набора. Например, в tests/acceptance.suite.yml мы должны увидеть:

actor: AcceptanceTester
modules:
    enabled:
        - PhpBrowser:
            url: http://localhost
        - Db
        - Filesystem

Класс AcceptanceTester имеет свои методы, определенные в модулях. Давайте посмотрим, что внутри класса AcceptanceTester, который находится в каталоге tests/_support:

<?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 void haveFriend($name, $actorClass = null)
 *
 * @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
    use _generated\AcceptanceTesterActions;

   /**
    * Define custom actions here
    */
}

Самая важная часть — это трейт _generated\AcceptanceTesterActions, который используется в качестве прокси для включенных модулей. Он знает, какой модуль выполняет какое действие и передает параметры в него. Этот трейт был создан при запуске codecept build и перегенерируется каждый раз при изменении модуля или конфигурации.

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

PageObjects

Для приемочного и функционального тестирования нам не только нужно иметь общие действия, которые повторно используются в разных тестах, но и кнопки, ссылки и поля форм, которые также повторно используются. В таких случаях нам нужно реализовать шаблон PageObject, который широко используется инженерами по автоматизации тестирования. Шаблон PageObject представляет веб-страницу как класс, элементы DOM на этой странице как его свойства и некоторые основные взаимодействия как его методы. PageObjects очень важны, когда вы разрабатываете гибкую архитектуру своих приемочных или функциональных тестов. Не нужно жестко кодировать сложные CSS или XPath-локатороы в тестах, а вместо этого перенесите их в классы PageObject.

Codeception может сгенерировать для вас класс PageObject с командой:

php vendor/bin/codecept generate:pageobject acceptance Login

Рекомендуется использовать page objects только для приемочного тестирования

Это создаст класс Login в tests/_support/Page/Acceptance. Базовый PageObject — это не более чем пустой класс с несколькими заглушками.

Ожидается, что вы заполните его локаторами пользовательского интерфейса страницы, которую он представляет. Локаторы можно добавить как публичные свойства:

<?php
namespace Page\Acceptance;

class Login
{
    public static $URL = '/login';

    public $usernameField = '#mainForm #username';
    public $passwordField = '#mainForm input[name=password]';
    public $loginButton = '#mainForm input[type=submit]';

    // ...
}

Но давайте пойдем дальше. Концепция PageObject указывает, что методы для взаимодействия со страницей также должны храниться в классе PageObject.

Давайте определим метод login в этом классе:

<?php
namespace Page\Acceptance;

class Login
{
    public static $URL = '/login';

    public $usernameField = '#mainForm #username';
    public $passwordField = '#mainForm input[name=password]';
    public $loginButton = '#mainForm input[type=submit]';

    /**
     * @var AcceptanceTester
     */
    protected $tester;

    // we inject AcceptanceTester into our class
    public function __construct(\AcceptanceTester $I)
    {
        $this->tester = $I;
    }

    public function login($name, $password)
    {
        $I = $this->tester;

        $I->amOnPage(self::$URL);
        $I->fillField($this->usernameField, $name);
        $I->fillField($this->passwordField, $password);
        $I->click($this->loginButton);
    }
}

Если вы указываете, какой объект вам нужен для теста, Codeception попытается создать его с помощью контейнера для инъекции зависимостей. В случае PageObject вы должны объявить класс в качестве параметра для метода теста:

<?php
class UserCest
{
    function showUserProfile(AcceptanceTester $I, \Page\Acceptance\Login $loginPage)
    {
        $loginPage->login('bill evans', 'debby');
        $I->amOnPage('/profile');
        $I->see('Bill Evans Profile', 'h1');
    }
}

Контейнер для инъекции зависимостей может создавать любой объект, который требует любой известного типа класса. Например, Page\Login потребовал AcceptanceTester, и поэтому он был внедрен в конструктор Page\Login, а PageObject был создан и передан в аргументы метода. Вы должны явно указать типы необходимых объектов, чтобы Codeception знал, какие объекты должны быть созданы для теста. Инъекция зависимостей будет описана в следующей главе.

StepObjects

StepObjects отлично подходят, если вам нужна общая функциональность для группы тестов. Допустим, вы собираетесь протестировать административную область сайта. Вам, вероятно, не понадобятся те же действия из административной области при тестировании передней части, поэтому неплохо перенести эти специфичные для администратора тесты в свой собственный класс. Мы называем такие классы StepObjects.

Давайте создадим Admin StepObject с помощью генератора:

php vendor/bin/codecept generate:stepobject acceptance Admin

Вы можете указать необязательные имена действий. Введите их по одному, а затем нажмите Enter. Закончите пустой строкой, чтобы продолжить создание StepObject.

php vendor/bin/codecept generate:stepobject acceptance Admin
Add action to StepObject class (ENTER to exit): loginAsAdmin
Add action to StepObject class (ENTER to exit):
StepObject was created in /tests/acceptance/_support/Step/Acceptance/Admin.php

Это сгенерирует класс в /tests/_support/Step/Acceptance/Admin.php, аналогичный этому:

<?php
namespace Step\Acceptance;

class Admin extends \AcceptanceTester
{
    public function loginAsAdmin()
    {
        $I = $this;
    }
}

Как видите, этот класс очень прост. Он расширяет класс AcceptanceTester, что означает, что он может получить доступ ко всем методам и свойствам класса AcceptanceTester.

Метод loginAsAdmin может быть реализован следующим образом:

<?php
namespace Step\Acceptance;

class Admin extends \AcceptanceTester
{
    public function loginAsAdmin()
    {
        $I = $this;
        $I->amOnPage('/admin');
        $I->fillField('username', 'admin');
        $I->fillField('password', '123456');
        $I->click('Login');
    }
}

StepObject может быть автоматически инициализирован при использовании в формате Cest:

<?php
class UserCest
{
    function showUserProfile(\Step\Acceptance\Admin $I)
    {
        $I->loginAsAdmin();
        $I->amOnPage('/admin/profile');
        $I->see('Admin Profile', 'h1');
    }
}

Если у вас есть сложный сценарий взаимодействия, вы можете использовать несколько step objects в одном тесте. Если вы чувствуете, что добавляете слишком много действий в свой класс Actor (в данном случае это AcceptanceTester), подумайте о переносе некоторых из них в отдельные StepObjects.

Используйте StepObjects, когда у вас есть несколько областей приложения или несколько ролей.

Заключение

Есть много способов создать повторно используемые и читаемые тесты. Группируйте общие действия вместе и переноситите их в класс Actor или StepObjects. Перенесите CSS и XPath-локатороы в PageObjects. Напишите свои пользовательские действия и утверждения в Helpers. Тесты, ориентированные на сценарий, не должны содержать ничего более сложного, чем $I->doSomething команды. Следование этому подходу позволит вам сохранить тесты чистыми, читаемыми, стабильными и простыми в обслуживании.

  • Следующая глава: AdvancedUsage >
  • Предыдущая глава: < ModulesAndHelpers

© 2011 Michael Bodnarchuk and contributors
Licensed under the MIT License.
https://codeception.com/docs/06-ReusingTestCode

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API