【发布时间】:2019-02-07 12:04:51
【问题描述】:
我正在寻找一个带有 pageObject 设计模式和 gherkin 的简单代码示例,因为当我关注 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 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;
}
}
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 运行接受”命令,则测试不完整,并且我在 shell 中收到“未在上下文中找到”警告:
我该怎么办?
更新 我在这里的 codeception GitHub 中创建了一个帖子:
https://github.com/Codeception/Codeception/issues/5157
我描述了一个重现我的问题的最小示例和一个(非常)丑陋的解决方案。我正在寻找一个好方法并理解为什么我描述的不起作用!
【问题讨论】:
-
尝试将依赖项作为方法参数传递,例如
function clickButton($homePage PageHome) { $this->click($homePage::$bButton); }. -
感谢您的帮助 :) 我像您说的那样进行了更改,但我得到了相同的输出...(“在上下文中找不到
I click on the button B的步骤定义”) -
我相信您在上述函数的 /**/ cmets 中设置的消息正在被您的工具解析。你在那里放了@符号,也许你不应该那样做?
-
我在创建 stackoverflow 帖子时收到了这些消息:/ 帮助我的救星哈哈
-
这看起来很复杂。 “页面对象”和“步骤对象”本质上不是一回事吗?两者都是您一遍又一遍地做某事的速记符号。将它们结合起来就像进入兔子洞一样。测试应该很容易理解。或者它有什么意义。
标签: php codeception gherkin pageobjects