编程语言
首页 > 编程语言> > php – Codeception,使用pageObject设计模式和小黄瓜编写验收测试

php – Codeception,使用pageObject设计模式和小黄瓜编写验收测试

作者:互联网

我正在寻找一个带有pageObject设计模式和小黄瓜的简单代码示例,因为当我遵循the codeception BDD documentation时,所有示例都在tests / 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 acceptance’,那么所有的工作都像魅力一样.但正如我之前所说,我想学习如何不将所有代码集中在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;
    }
}

A pageObject:

<?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 pageObject:

<?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

homeChecker stepObject:

<?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文件并再次运行’./vendor/bin/codecept run acceptance’命令,则测试不完整,我的shell中出现“在上下文中找不到”警告:

enter image description here

我该怎么办 ?

更新
我在这里的代码github中创建了一个帖子:

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

我描述了一个重现我的问题和一个(非常)难看的分辨率的最小例子.我正在寻找好方法并理解为什么我描述不起作用!

解决方法:

I get “not found in contexts” warnings in my shell

好的,如何将小黄瓜文件执行与我自己的上下文类(PageObjects,StepObjects,…)中定义的步骤相关联?我们可以在Codeception文档中阅读“BDD > Configuration”一章:

As we mentioned earlier, steps should be defined inside context classes. By default all the steps are defined inside an Actor class, for instance, AcceptanceTester. However, you can include more contexts. This can be configured inside global codeception.yml or suite configuration file:

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

(…) This way PageObjects, Helpers and StepObjects can become contexts as well.

更好

如果我们继续阅读:

But more preferable to include context classes by their tags or roles.

这意味着,考虑到可扩展性和良好的组织,您不希望每个页面对象都超载每个测试.因此,您可以按角色,按标记或路径分配页面对象(或任何助手类).请参阅文档的下一段.按照您的示例,并按标记分配:

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

…和小黄瓜文件:

@myTagX
Feature
(...)

标签:pageobjects,codeception,php,gherkin
来源: https://codeday.me/bug/20191006/1860158.html