Behat对Symfony2用户进行身份验证

tvl*_*ooy 12 symfony behat

我在Symfony2/Doctrine2中使用Behat.现在,我有这个场景可以归结为"如果我已登录并进入/登录,我应该转到/取而代之":

@login
Scenario: Go to the login page while being logged in
  Given I am logged in
  When I go to "/login"
  Then I should be on "/"
Run Code Online (Sandbox Code Playgroud)

对于@login,我创建了以下内容:

/**
 * @BeforeScenario @login
 */
public function loginUser()
{
    $doctrine = $this->getContainer()->get('doctrine');
    $userRepository = $doctrine->getRepository('MyTestBundle:User');
    $user = $userRepository->find(1); // 1 = id

    $token = new UsernamePasswordToken($user, NULL, 'main', $user->getRoles());
    $this->getContainer()->get('security.context')->setToken($token);
}
Run Code Online (Sandbox Code Playgroud)

在"当我进入/登录"代码(控制器被调用)时,令牌似乎消失了(不是我想要的):

/**
 * @Route("/login", name="login")
 */
public function loginAction()
{
    $token = $this->get('security.context')->getToken();
    $fd = fopen('/tmp/debug.log', 'a');
    fwrite($fd, $token);

    // prints 'AnonymousToken(user="anon.", authenticated=true, roles="")'
    ...
Run Code Online (Sandbox Code Playgroud)

但是在FeatureContext中,它似乎一直存在(我希望它的工作方式).在"鉴于我登录":

/**
 * @Given /^I am logged in$/
 */
public function iAmLoggedIn()
{        
    $token = $this->getContainer()->get('security.context')->getToken();
    $fd = fopen('/tmp/debug.log', 'a');
    fwrite($fd, $token);

    // prints 'UsernamePasswordToken(user="admin", authenticated=true, roles="ROLE_ADMIN")'
    ...
Run Code Online (Sandbox Code Playgroud)

我这样运行:

app/console -e=test behat
Run Code Online (Sandbox Code Playgroud)

我也在控制器中做了这个以确定它的测试:

fwrite($fd, $this->get('kernel')->getEnvironment());
// prints 'test'
Run Code Online (Sandbox Code Playgroud)

任何线索如何验证用户?我将不得不测试很多管理页面,所以如果我可以将登录挂钩到@ BeforeSuite,@ BeforeFeature(或@BeforeScenario ......)以便我不会被阻止,那就太好了.

(关于禁用测试认证机制的建议,或者存根/模拟用户的方法也是受欢迎的.)

eve*_*zet 19

天啊.它不起作用,因为您的FeatureContext中的DIC不与您的应用共享 - 您的应用具有单独的内核和DIC.你可以通过Mink得到它.或者,你可以简单地做到这一点:-)

正确的方式意味着,最终用户可以观察到的行为的每个部分都应该在*.feature中描述,而不是在FeatureContext中描述.这意味着,如果你想登录用户,你应该简单地用步骤描述它(比如:"我在/登录","我填写用户名......","我填写密码"和stuf) .如果你想多次这样做 - 你应该创建一个metastep.

Metasteps只是描述多个其他步骤的步骤,例如 - "我以everzet身份登录".你可以在这里阅读它们:http://docs.behat.org/guides/2.definitions.html#step-execution-chaining

  • 仅仅因为用户必须使用登录页面访问某个区域并不意味着所有测试也应该使用登录表单.通过这样做,您现在将每个测试场景耦合到登录表单.在许多应用程序中,还有"记住我"功能和电子邮件链接登录(电子邮件验证,忘记密码等).仅仅因为它被称为行为驱动开发并不意味着最终用户行为.它表示来自所有角色,用户,业务组等的预期系统行为. (4认同)
  • 你提到可以获得应用程序的内核和DIC,你会怎么做? (2认同)