如何在Laravel中以登录用户身份运行Behat测试?

时间:2014-04-10 15:43:36

标签: testing laravel behat

我正在尝试使用Behat为Laravel应用程序创建一些测试。许多测试要求登录用户查看特定数据。我的方法是:

  • 以具有Auth::loginUsingId($id)
  • 的特定ID的用户身份登录
  • 转到我的应用中的特定网址
  • 检查我期待的内容是否存在

现在,在我的Behat上下文中,虽然Auth::check()返回true,但我设置的过滤器似乎没有看到这一点。该上下文中的Auth::check()会返回false,从而尝试进行身份验证(通过OAuth访问我的应用与之对话的API)。

如何以登录用户身份测试我的应用程序?

My Behat上下文文件,如果有帮助的话:

<?php

use Behat\Behat\Context\ClosuredContextInterface;
use Behat\Behat\Context\TranslatedContextInterface;
use Behat\Behat\Context\BehatContext;
use Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Behat\MinkExtension\Context\MinkContext;

/**
 * Features context.
 */
class FeatureContext extends MinkContext
{
    /**
     * Laravel application instance.
     *
     * @var Illuminate\Foundation\Application
     */
    protected $app;

    /**
     * @static
     * @beforeSuite
     */
    public static function bootstrapLaravel()
    {
        $unitTesting = true;
        $testEnvironment = true;

        $app = require_once __DIR__ . '/../../../../bootstrap/start.php';
        $app->boot();
    }

    /**
     * Initializes context.
     * Every scenario gets its own context object.
     *
     * @param array $parameters context parameters (set them up through behat.yml)
     */
    public function __construct(array $parameters)
    {
    }

    /**
     * @Given /^I am logged in as user ID (\d+)$/
     */
    public function iAmLoggedInAsUserId($id)
    {
        Auth::loginUsingId($id);
    }
}

示例测试功能:

Feature: Sample Feature

  Scenario: View groups a member is associated with
    Given I am logged in as user ID 49
    And I am on "/group"
    Then I should see "Lorem Ipsum"

2 个答案:

答案 0 :(得分:4)

您遇到的问题是iAmLoggedInAsUserId方法直接在laravel框架上执行调用,其后续指令是基于浏览器/ mink的。这就像是从命令行运行的PHP脚本,它将登录用户设置(用于执行)到123,然后转到Web浏览器 - 用户123将不会在该上下文中登录。

您需要找到一种方法,使基于代码的身份验证能够持久存储到您的浏览器测试中。

可能的选择:

  • iAmLoggedInAsUserId的聚合指令,该指令进入登录页面并执行登录。
  • 劫持mink使用的会话,并将其更新为登录
  • 仅限本地工作,您可以设置包含用户ID的标头,只有在本地运行时,您的代码才会将此用作登录用户

理想情况下,您应该编写一个测试来测试登录,但是这是结构化的(即选项1),然后重新用于需要登录用户的测试。如果你的用例不允许第一个选项,那么另外两个选项就是简单的想法。

编辑:以下是一个示例聚合指令,此特定版本要求用户存在于系统中。但是,您可以强制用户预先存在,如果它是作为测试的一部分添加的,则在使用@AfterFeature挂钩完成测试后将其删除:

/**
 * @Given /I am logged in with the username "([^"]*)" and password "([^"]*)"/
 */
public function loginWithEmailAndPassword($username, $password)
{
    //$this->ensureUserExistsWithEmailAndPassword($email, $password);

    return array(
        new Behat\Behat\Context\Step\Given("I am on \"/login\""),
        new Behat\Behat\Context\Step\When("I fill in \"login_username\" with \"$username\""),
        new Behat\Behat\Context\Step\When("I fill in \"login_password\" with \"$password\""),
        new Behat\Behat\Context\Step\When("I press \"Login\""),
        new Behat\Behat\Context\Step\Then("I should see \"Welcome\"")
    );
}

答案 1 :(得分:0)

Behat是它产生的浏览器会话的单独进程,因此以这样的方式登录将无法正常工作。

我通常所做的是描述以测试用户身份登录的步骤。如下所示。

Given I am on the login page
And I fill in "username" with "testuser"
And I fill in "password" with "testpassword"
And I press "Log in"
Then I should be logged in as "testuser"

您可以将其设置为每个方案之前运行的背景。

我可能还会将步骤缩减为FeatureContext中可以在一个步骤中调用的方法,例如Given I am logged in as "testuser"