Symfony2 Behat 扩展上下文将导致 "Step is already defined"
Symfony2 Behat Extending Contexts will result in "Step is already defined"
我正在尝试为应用程序编写一些 Behat 测试,我需要分离上下文,以便我可以在不同的其他上下文中使用一些核心元素,例如登录用户步骤。
behat.yml
suites:
common:
type: symfony_bundle
bundle: CommonBundle
mink_session: symfony2
mink_javascript_session: selenium2
autoload:
'CommonContext': %paths.base%/src/xxx/CommonBundle/Features/Context
contexts: [ xxx\CommonBundle\Features\Context\CoreContext ]
user:
type: symfony_bundle
bundle: UserBundle
mink_session: symfony2
mink_javascript_session: selenium2
autoload:
'UserContext': %paths.base%/src/xxx/UserBundle/Features/Context
contexts:
- Behat\MinkExtension\Context\MinkContext
- xxx\CommonBundle\Features\Context\CoreContext
- xxx\UserBundle\Features\Context\UserContext
DefaultContext.php
namespace XXX\CommonBundle\Features\Context;
use ...
/**
* Class DefaultContext
*/
class DefaultContext extends MinkContext implements Context, KernelAwareContext
{
/**
* @param AbstractEntity $oEntity
*
* @return object
*/
protected function getRepository(AbstractEntity $oEntity)
{
return $this->getService($oEntity);
}
/**
* @return mixed
*/
protected function getEntityManager()
{
return $this->getService('doctrine')->getManager();
}
/**
* @param $id
*
* @return object
*/
protected function getService($id)
{
return $this->getContainer()->get($id);
}
CoreContext.php
namespace XXX\CommonBundle\Features\Context;
use ...
/**
* Class SubContext
*/
class CoreContext extends DefaultContext implements Context, SnippetAcceptingContext
{
/**
* @Given I visit the homepage
* @When I visit the homepage
*/
public function iVisitHomepage()
{
$this->visitPath('/');
}
/**
* @And /^I am logged in as "([^"]*)"$/
* @Then /^I am logged in as "([^"]*)"$/
*/
public function iAmLoggedInAs($username)
{
$user = $this->getContainer()->get('fos_user.user_manager')->findUserByUsername($username);
$this->visit('/login');
$this->fillField('_username', $user->getEmailCanonical());
$this->fillField('_password', self::USER_PASSWORD);
$this->pressButton('_submit');
}
UserContext.php
namespace xxx\UserBundle\Features\Context;
use ...
/**
* Defines application features from the specific context.
*/
class UserContext extends CoreContext implements Context, SnippetAcceptingContext
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
}
register_user.feature
Feature: Register user
@javascript
Scenario: Register user
Given I am on homepage
And I go to "/register/"
And I am logged in as "foo@bar.com"
Then I should see "Terms and Conditions"
因此,当我 运行 测试时,我收到一条错误消息:
Given I am on homepage
Step "I visit the homepage" is already defined in xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
And I go to "/register/"
Step "I visit the homepage" is already defined in xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
我的理解完全错误还是我在这里遗漏了一些设置?
不要扩展提供步骤定义的上下文。没有办法解决这个问题。
好的扩展提供了方便的方法但没有步骤定义的上下文。对于 Mink 扩展,MinkContext
旁边还有 RawMinkContext
。首先提供步骤定义,不应扩展。另一个提供您可能感兴趣的辅助方法。RawMinkContext
是您应该扩展的方法。或者,您也可以使用 MinkAwareTrait
.
Behat2 中的上下文以及它们现在在 Behat3 中的位置发生了变化。 Behat3 中的上下文更多地是关于 "situations" 的,您的测试可能会在其中发生。例如:
- 已登录
- 匿名访客
- PublicAPI来电
- 已验证 API 调用
- 已禁用 javascript 浏览器
- 启用javascript浏览器
以此类推
恐怕问题出在您对两个套件中使用的 CoreContext 的配置中。您可以尝试通过 运行 您的套件单独避免这种情况,这样它就不会加载两种配置(并且它不会自动加载两次相同的上下文)或更改上下文策略以不使用自动加载,但有些不同,例如封装将通用步骤逻辑合并到它们自己的 类 中,然后从不同的上下文中使用。
希望对您有所帮助
我正在尝试为应用程序编写一些 Behat 测试,我需要分离上下文,以便我可以在不同的其他上下文中使用一些核心元素,例如登录用户步骤。
behat.yml
suites:
common:
type: symfony_bundle
bundle: CommonBundle
mink_session: symfony2
mink_javascript_session: selenium2
autoload:
'CommonContext': %paths.base%/src/xxx/CommonBundle/Features/Context
contexts: [ xxx\CommonBundle\Features\Context\CoreContext ]
user:
type: symfony_bundle
bundle: UserBundle
mink_session: symfony2
mink_javascript_session: selenium2
autoload:
'UserContext': %paths.base%/src/xxx/UserBundle/Features/Context
contexts:
- Behat\MinkExtension\Context\MinkContext
- xxx\CommonBundle\Features\Context\CoreContext
- xxx\UserBundle\Features\Context\UserContext
DefaultContext.php
namespace XXX\CommonBundle\Features\Context;
use ...
/**
* Class DefaultContext
*/
class DefaultContext extends MinkContext implements Context, KernelAwareContext
{
/**
* @param AbstractEntity $oEntity
*
* @return object
*/
protected function getRepository(AbstractEntity $oEntity)
{
return $this->getService($oEntity);
}
/**
* @return mixed
*/
protected function getEntityManager()
{
return $this->getService('doctrine')->getManager();
}
/**
* @param $id
*
* @return object
*/
protected function getService($id)
{
return $this->getContainer()->get($id);
}
CoreContext.php
namespace XXX\CommonBundle\Features\Context;
use ...
/**
* Class SubContext
*/
class CoreContext extends DefaultContext implements Context, SnippetAcceptingContext
{
/**
* @Given I visit the homepage
* @When I visit the homepage
*/
public function iVisitHomepage()
{
$this->visitPath('/');
}
/**
* @And /^I am logged in as "([^"]*)"$/
* @Then /^I am logged in as "([^"]*)"$/
*/
public function iAmLoggedInAs($username)
{
$user = $this->getContainer()->get('fos_user.user_manager')->findUserByUsername($username);
$this->visit('/login');
$this->fillField('_username', $user->getEmailCanonical());
$this->fillField('_password', self::USER_PASSWORD);
$this->pressButton('_submit');
}
UserContext.php
namespace xxx\UserBundle\Features\Context;
use ...
/**
* Defines application features from the specific context.
*/
class UserContext extends CoreContext implements Context, SnippetAcceptingContext
{
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
}
register_user.feature
Feature: Register user
@javascript
Scenario: Register user
Given I am on homepage
And I go to "/register/"
And I am logged in as "foo@bar.com"
Then I should see "Terms and Conditions"
因此,当我 运行 测试时,我收到一条错误消息:
Given I am on homepage
Step "I visit the homepage" is already defined in xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
And I go to "/register/"
Step "I visit the homepage" is already defined in xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
xxx\CommonBundle\Features\Context\CoreContext::iVisitHomepage()
我的理解完全错误还是我在这里遗漏了一些设置?
不要扩展提供步骤定义的上下文。没有办法解决这个问题。
好的扩展提供了方便的方法但没有步骤定义的上下文。对于 Mink 扩展,MinkContext
旁边还有 RawMinkContext
。首先提供步骤定义,不应扩展。另一个提供您可能感兴趣的辅助方法。RawMinkContext
是您应该扩展的方法。或者,您也可以使用 MinkAwareTrait
.
Behat2 中的上下文以及它们现在在 Behat3 中的位置发生了变化。 Behat3 中的上下文更多地是关于 "situations" 的,您的测试可能会在其中发生。例如:
- 已登录
- 匿名访客
- PublicAPI来电
- 已验证 API 调用
- 已禁用 javascript 浏览器
- 启用javascript浏览器
以此类推
恐怕问题出在您对两个套件中使用的 CoreContext 的配置中。您可以尝试通过 运行 您的套件单独避免这种情况,这样它就不会加载两种配置(并且它不会自动加载两次相同的上下文)或更改上下文策略以不使用自动加载,但有些不同,例如封装将通用步骤逻辑合并到它们自己的 类 中,然后从不同的上下文中使用。
希望对您有所帮助