Codeception, напишите приемочные тесты с шаблоном оформления объекта и огурчиком - PullRequest
0 голосов
/ 02 сентября 2018

Я ищу простой пример кода с шаблоном дизайна pageObject и gherkin, потому что, когда я следую документации BDD для кодирования , все примеры пишутся в тестах / support / AcceptanceTester.php , Я не понимаю (плохое знание английского языка - -), как не сконцентрировать весь код в файле AcceptanceTester.php.

Например, у меня есть пример домашней страницы с двумя кнопками A и B. Если пользователь нажимает кнопку A, страница A загружается в противном случае, если пользователь нажимает кнопку B, страница B загружается.

В настоящее время мой AcceptanceTester :

<?php
// tests/_support/AcceptanceTester.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;

    /**
     * @Given The home page
     */
    public function inHomePage()
    {
        $this->amOnPage("/");
        $this->seeInTitle('home');
    }

    /**
     * @When I click on the button A
     */
    public function goToThePageA()
    {
        $this->click(['name' => 'A']);
    }

    /**
     * @Then l go to the page A
     */
    public function ImInPageA()
    {
        $this->seeInTitle('page A');
    }

    /**
     * @When I click on the button B
     */
    public function goToThePageB()
    {
        $this->click(['name' => 'B']);
    }

    /**
     * @Then l go to the page B
     */
    public function ImInPageB()
    {
        $this->seeInTitle('page B');
    }
}

Если я запускаю команду «./vendor/bin/codecept run accept», все работает как чудо. Но, как я уже говорил ранее, я хочу научиться не концентрировать весь код в файле AcceptanceTester.

Итак, я создал три объекта pageObjects; один для домашней страницы, один для страницы A и один для страницы B. Код:

главная страницаОбъект :

<?php
// tests/_support/Page/PageHome.php
namespace Page;

class PageHome
{
    public static $URL = '/home';
    public static $title = "home";
    public static $aButton = ['name' => 'A'] ;
    public static $bButton = ['name' => 'B'] ;

    public static function route($param){
        return static::$URL.$param;
    }

    /**
     * @var \AcceptanceTester;
     */
    protected $acceptanceTester;

    public function __construct(\AcceptanceTester $I){
        $this->acceptanceTester = $I;
    }
}

Объект страницы :

<?php
// tests/_support/Page/PageA.php
namespace Page;

class PageA
{
    public static $URL = '/home/pageA';
    public static $title = "page A";

    public static function route($param){
        return static::$URL.$param;
    }

    /**
     * @var \AcceptanceTester;
     */
    protected $acceptanceTester;

    public function __construct(\AcceptanceTester $I){
        $this->acceptanceTester = $I;
    }
}

А Страница BОбъект :

<?php
// tests/_support/Page/PageB.php
namespace Page;

class PageB
{
    public static $URL = '/home/pageB';
    public static $title = "page B";

    public static function route($param){
        return static::$URL.$param;
    }

    /**
     * @var \AcceptanceTester;
     */
    protected $acceptanceTester;

    public function __construct(\AcceptanceTester $I){
        $this->acceptanceTester = $I;
    }
}

Затем я создал три stepObjects; homeChecker, goToPageA, goToPageB

шаг homeCheckerObject :

<?php
// tests/_support/Step/Acceptance/HomeChecker.php

namespace Step\Acceptance;
use Page\Acceotance\HomePage;

class HomeChecker extends \AcceptanceTester
{
    /**
     * @Given The home page
     */
    public function main()
    {
        $homePage = new PageHome($this);

        $this->amOnPage($homePage::URL);
        $this->checkTitle($homePage);
        $this->checkButtons($homePage);
    }

    private function checkTitle($homePage){
        $this->seeInTitle($homePage::$title);
    }

    private function checkButtons($homePage){
        $this->see($homePage::$aButton);
        $this->see($homePage::$bButton);
    }
}

PageAChecker stepObject :

<?php
// tests/_support/Step/Acceptance/PageAChecker.php

namespace Step\Acceptance;
use Page\PageHome;
use Page\PageA;

class PageAChecker extends \AcceptanceTester
{
    /**
     * @When I click on the button A
     */
    public function clickButton()
    {
        $homePage = new PageHome($this);
        $this->click($homePage::$aButton);
    }

    /**
     * @Then l go to the page A
     */
    public function checkTitle()
    {
        $aPage = new PageA($this);
        $this->seeInTitle($aPage::$title);
    }

}

и PageBChecker stepObject :

<?php
// tests/_support/Step/Acceptance/PageBChecker.php

namespace Step\Acceptance;
use Page\PageHome;
use Page\PageB;

class PageBChecker extends \AcceptanceTester
{
    /**
     * @When I click on the button B
     */
    public function clickButton()
    {
        $homePage = new PageHome($this);
        $this->click($homePage::$bButton);
    }

    /**
     * @Then l go to the page B
     */
    public function checkTitle()
    {
        $bPage = new PageB($this);
        $this->seeInTitle($bPage::$title);
    }

}

А теперь я не знаю, что я должен делать. Если я очищаю свой файл AcceptanceTester и снова запускаю команду.

enter image description here

Что мне делать?

Обновление Я создал пост в GitHub кодекса здесь:

https://github.com/Codeception/Codeception/issues/5157

Я описываю минимальный пример для воспроизведения моей проблемы и (очень) некрасивое решение. Я ищу хороший способ и понимаю, почему я описал, не работает!

1 Ответ

0 голосов
/ 18 июня 2019

Я получаю предупреждения "не найдено в контекстах" в моей оболочке

Хорошо, как связать выполнение файлов корнишона с шагами, определенными в моих собственных классах контекстов (PageObjects, StepObjects, ...)? Мы можем прочитать главу " BDD> Конфигурация " в документации Codeception:

Как мы упоминали ранее, шаги должны быть определены внутри классов контекста. По умолчанию все шаги определены внутри класса Actor, например, AcceptanceTester. Тем не менее, вы можете включить больше контекстов. Это можно настроить внутри глобального codeception.yml или файла конфигурации пакета:

gherkin:
    contexts:
        default:
            - AcceptanceTester
            - AdditionalSteps
            - PageHome
            - HomeChekcer

(...) Таким образом, PageObjects, Helpers и StepObjects также могут становиться контекстами.


Better

Если мы продолжим читать:

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

Это означает, что, учитывая возможность расширения и хорошую организацию, вы не захотите перегружать все тесты каждым объектом Page Object. Поэтому вы можете назначить объект страницы (или любые вспомогательные классы) по роли, тегу или пути. Смотрите следующие параграфы по документации. Следуя вашему примеру и присваивая тегом:

gherkin:
   contexts:
      default:
         - AcceptanceTester
      tag:
         myTagX:
             - Page\Acceotance\HomePage\HomeChecker
             - Page\PageHome
         anotherTag:
             - Page\Acceotance\another\AnotherChecker
             - Page\PageAnother

... и в файлах корнишонов:

@myTagX
Feature
(...)
...