简体   繁体   English

"Codeception,使用 pageObject 设计模式和 gherkin 编写验收测试"

[英]Codeception, write acceptance tests with the pageObject design pattern and gherkin

I'm looking for a simple example of code with the pageObject design pattern and gherkin because when I follow the codeception BDD documentation , all examples written in the tests/ support/AcceptanceTester.php.我正在寻找一个带有 pageObject 设计模式和 gherkin 的简单代码示例,因为当我遵循codeception BDD 文档时,所有示例都写在 tests/ support/AcceptanceTester.php 中。 I don't understand (poor English skills - -) how not concentrate all code in the AcceptanceTester.php file.我不明白(英语能力差- -)如何不将所有代码集中在 AcceptanceTester.php 文件中。

For example, I have a sample home page with two buttons A and B. If the user clicks on button A, page A is loaded else if the user clicks on button B, page B is loaded.例如,我有一个带有两个按钮 A 和 B 的示例主页。如果用户单击按钮 A,则加载页面 A,否则如果用户单击按钮 B,则加载页面 B。

Currently, my AcceptanceTester :目前,我的 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');
    }
}

If I run the command './vendor/bin/codecept run acceptance', all works like a charm.如果我运行命令“./vendor/bin/codecept run accept”,一切都会像魅力一样。 But as I said previously, I need to learn how don't concentrate all code in the AcceptanceTester file.但正如我之前所说,我需要学习如何不将所有代码集中在 AcceptanceTester 文件中。

So, I created three pageObjects ;所以,我创建了三个 pageObjects ; one for the home page, one for the page A and one for the page B. The code :一个用于主页,一个用于页面 A,一个用于页面 B。代码:

the home pageObject :主页对象

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

the A pageObject : 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;
    }
}

And the B pageObject :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;
    }
}

Then, I created three stepObjects ;然后,我创建了三个 stepObjects ; homeChecker, goToPageA, goToPageB homeChecker, goToPageA, goToPageB

The homeChecker stepObject : 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);
    }
}

The PageAChecker stepObject : PageAChecker 步骤对象

<?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);
    }

}

And the PageBChecker stepObject :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);
    }

}

And now, I don't know what I must do.而现在,我不知道我必须做什么。 If I empty my AcceptanceTester file and run again the './vendor/bin/codecept run acceptance' command, the test is incomplete and I get "not found in contexts" warnings in my shell :如果我清空我的 AcceptanceTester 文件并再次运行“./vendor/bin/codecept 运行接受”命令,则测试不完整,并且我在 shell 中收到“未在上下文中找到”警告:

在此处输入图像描述

What do I do?我该怎么办?

Update I created a post in the codeception GitHub here :更新我在这里的 codeception GitHub 中创建了一个帖子:

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

I describe a minimal example of reproducing my issue and a (very) ugly resolution.我描述了一个重现我的问题的最小示例和一个(非常)丑陋的解决方案。 I'm looking to getting a good way and understand why I described does not work!我正在寻找一个好方法并理解为什么我描述的不起作用!

I get "not found in contexts" warnings in my shell我在 shell 中收到“未在上下文中找到”警告

Ok, how to link gherkin files execution with steps defined in my own contexts classes (PageObjects, StepObjects, ...)?好的,如何将小黄瓜文件的执行与我自己的上下文类(PageObjects、StepObjects...)中定义的步骤联系起来? We can read chapter " BDD > Configuration " in Codeception documentation:我们可以阅读 Codeception 文档中的“ BDD > 配置”一章:

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.默认情况下,所有步骤都在 Actor 类中定义,例如 AcceptanceTester。 However, you can include more contexts.但是,您可以包含更多上下文。 This can be configured inside global codeception.yml or suite configuration file:这可以在全局 codeception.yml 或套件配置文件中配置:

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

(...) This way PageObjects, Helpers and StepObjects can become contexts as well. (...) 这样 PageObjects、Helpers 和 StepObjects 也可以成为上下文。


Better更好的

If we continue reading:如果我们继续阅读:

But more preferable to include context classes by their tags or roles.但更可取的是按标签或角色包含上下文类。

This means that, bearing in mind escalability and good organization, you will not want to overload every tests with every Page Object.这意味着,考虑到可扩展性和良好的组织性,您不会希望每个页面对象的每个测试都过载。 Therefore you can assign Page Object (or any assistant classes) by role, by tag or by paths.因此,您可以按角色、标签或路径分配页面对象(或任何助手类)。 See next paragraphs on documentation.请参阅有关文档的下一段。 Following your example, and assigning by tag:按照您的示例,并按标签分配:

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

...and in gherkin files: ...在小黄瓜文件中:

@myTagX
Feature
(...)

As I see, You are trying to write your automation layer in a reusable way.如我所见,您正在尝试以可重用的方式编写自动化层。 You can use the ScreenPlay<\/em> pattern for it.您可以使用ScreenPlay<\/em>模式。

the differences between page object and screenplay are discussed here<\/a>页面对象和剧本之间的区别在这里<\/a>讨论

The key difference is that the screenplay pattern organizes the Page Objects关键区别在于剧本模式组织了页面对象

<\/blockquote>

John Ferguson<\/em> article: ScreenPlay: the next stage in automated acceptance testing<\/a> John Ferguson<\/em>文章: ScreenPlay:自动化验收测试的下一阶段<\/a>

"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用symfony 2的Codeception验收测试 - Using Codeception acceptance tests with symfony 2 设置测试数据库以用于Codeception(Laravel)中的验收测试 - Setup testing database for acceptance tests in Codeception (Laravel) 代码接收-在多个环境中运行接收测试 - Codeception - Run acceptance tests in multiple environments 使用Codeception验收测试连接到多个数据库 - Connecting to multiple databases with Codeception acceptance tests Codeception。 用于接受测试的测试数据库,或用于纯PHP的功能测试 - Codeception. Test database for acceptance tests, or functional tests for pure PHP 在多个代码功能测试中使用相同的小黄瓜步骤 - Using the same gherkin steps in multiple codeception functional tests 所有Codeception Gherkin .feature测试是否都在Context文件中结束吗? - Do all Codeception gherkin .feature tests end up in Context files? 如何在 Codeception 命令行的验收测试中使用动态 url - How to use dynamic urls in acceptance tests from command line with Codeception 在Codeception中将灯具与验收测试一起使用的正确方法是什么? - What is the proper way to use fixtures with Acceptance tests in Codeception? 如何使用docker-compose运行自动代码接收验收测试? - How to run automated codeception acceptance tests using docker-compose?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM