Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 无法在自定义Laravel测试环境(codeception)中进行身份验证_Php_Authentication_Laravel_Codeception - Fatal编程技术网

Php 无法在自定义Laravel测试环境(codeception)中进行身份验证

Php 无法在自定义Laravel测试环境(codeception)中进行身份验证,php,authentication,laravel,codeception,Php,Authentication,Laravel,Codeception,我正在运行Vagrant(homestead)、PHP5.5.12和Laravel4.2。我正在尝试配置codeception以使用测试环境进行验收测试(在phantomJS上运行)。在宅地盒子上,我有两个环境:本地环境和测试环境。我很小心,没有在默认的“测试”环境上重复,这是为PHPUnit测试保留的 我的问题是,虽然我可以使用Eloquent来实例化一个用户(并检索它),但我无法对该用户进行任何测试的身份验证。这使我无法运行测试套件,其中90%需要用户身份验证 我在/etc/nginx/si

我正在运行Vagrant(homestead)、PHP5.5.12和Laravel4.2。我正在尝试配置codeception以使用测试环境进行验收测试(在phantomJS上运行)。在宅地盒子上,我有两个环境:本地环境和测试环境。我很小心,没有在默认的“测试”环境上重复,这是为PHPUnit测试保留的

我的问题是,虽然我可以使用Eloquent来实例化一个用户(并检索它),但我无法对该用户进行任何测试的身份验证。这使我无法运行测试套件,其中90%需要用户身份验证

我在/etc/nginx/sites中定义了两个站点:myapp.app和myapp.test。我将fastcgi_参数APP_ENV定义为本地和测试(分别)。我还在我的~/.bashrc中指定了APP_ENV,因此echo$APP_ENV返回“local”。我已经使用指向测试数据库的database.php凭据创建了相应的config/test文件夹。下面是默认的codeception.yml设置,以及由acceptance.suite.yml设置覆盖的设置(这是我专门运行的套件)

我无法在测试环境中进行身份验证。所有这样做的尝试都返回false或null

codeception.yml acceptance.suite.yml 此acceptance helper编译到AcceptanceTester类中,并在所有需要身份验证的CEST上的before筛选器中运行。我在这里测试了User::create方法的输出,它实际上创建了一个用户对象,例如,我可以在login方法中访问它。但是,它不会出现在我的数据库中(从Navicat查看)。数据库当前是从test-dump.sql文件填充的,只包含没有任何数据的架构。我不确定为什么雄辩的创建方法不会写入数据库,但我最好的猜测是,在测试套件运行之后,数据库正在回滚

AcceptanceHelper.php 我直接拨入Auth::trunt方法,该方法调用Auth/Guard->hasValidCredentials

protected function hasValidCredentials($user, $credentials)
{
    return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
这将返回null。为了澄清,它甚至在调用$user->first\u name返回true后立即返回null,或者user::all()->first()->first\u name返回正确的名字。换句话说,我可以使用Eloquent创建并检索一个用户,然后立即测试Auth::trunt,它最终调用hasValidCredentials,调用Eloquent/Builder->where,根据登录表单的电子邮件地址进行查找,并返回null。用户是否可能存储在内存中而不是数据库中

我已经手动创建了一个用户并尝试手动验证,登录表单只是重新加载。我在“本地”环境中进行身份验证时没有此类问题

在身份验证期间调用下面的方法,并返回一个包含空结果的查询对象

Eloquent/Builder.php行:569 下面是我的UserCest.php文件。BaseAcceptanceHelper仅调用AcceptanceTester->login函数来验证默认测试用户。这是失败的

UserCest.php
任何帮助都将不胜感激。我完全不知道身份验证失败的原因。

解决方案是在acceptance.suite.yml中定义Laravel4模块的配置设置:

class_name: AcceptanceTester
modules:
    enabled:
        - Laravel4
        - AcceptanceHelper
        - WebDriver
        - Db
    config:
        Laravel4:
            cleanup: false
            environment: test
        WebDriver:
            url: 'http://myapp.test'
            browser: phantomjs
            window_size: 1024x768
        Db:
            dsn: 'pgsql:host=localhost;dbname=myapp_testing'
            user: 'myapp_testing'
            password: 'myapp_testing'
            dump: tests/_data/test-dump.sql
            populate: true
            cleanup: false
cleanup:true
防止在测试之间回滚db环境,并且
environment:test
告诉Laravel4使用正确的数据库


我遇到的另一个问题是,我的“测试”环境文件夹复制了默认Laravel“测试”环境中的cache.php和session.php配置文件,该环境将缓存和会话分配给内存阵列,我在发帖时没有意识到这一点。页面之间没有持久的会话数据,因此无法进行身份验证。我刚刚从config/test中删除了这两个文件,我很好。

尝试从验收套件中删除Laravel4。Laravel4模块仅用于功能和单元测试,不用于验收测试。我知道文档中说明了这一点,但我认为这是一个原则问题,而不是功能问题。Laravel4只是提供了对Laravel应用程序的访问,如果您需要为测试从IoC容器中解析任何内容,这是必不可少的,我就是这么做的。问题在于未能告知Laravel4模块要使用哪种环境(见下文)。通常情况下,您不应该为验收测试解决IoC之外的任何问题。验收测试应尽可能接近真实代码。一旦您开始执行诸如从IoC容器中解析之类的操作,您所做的更多的是功能测试,而不是验收测试。
<?php namespace Codeception\Module;

// here you can define custom actions
// all public methods declared in helper class will be available in $I

use AcceptanceTester;
use Hash;
use LoginPage;
use User;

class AcceptanceHelper extends \Codeception\Module
{
    public function loginUser(AcceptanceTester $I)
    {
        User::create([
            'first_name' => 'test',
            'last_name' => 'test',
            'password' => Hash::make('1234'),
            'email' => 'test@test.com'
        ]);
        $this->login($I, 'test@test.com', '1234');
    }

    public function login(AcceptanceTester $I, $email, $password)
    {
        $I->amOnPage(LoginPage::$URL);
        $I->fillField('email', $email);
        $I->fillField('password', $password);
        $I->click(LoginPage::$loginButton);
        $I->see('Welcome. Your email address is test@test.com');
    }

    public function logoutUser(AcceptanceTester $I)
    {
        $I->amOnPage('/logout');
        $I->seeCurrentUrlEquals('/login');
        $I->see('You have been logged out');
    }
}
public function store()
{
    $this->loginForm->validate($input = Input::only('email', 'password'));

    if (Auth::attempt($input))
    {
        return Redirect::intended('profile')->with('flash_message', 'You have been logged in!');
    }

    return Redirect::back()->with('flash_message', 'Invalid credentials.')->withInput();
}
protected function hasValidCredentials($user, $credentials)
{
    return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
call_user_func_array(array($this->query, 'where'), func_get_args());
use MyApp\Helpers\TestHelpers\BaseAcceptanceHelper;

class UserCest extends BaseAcceptanceHelper {

    public function _before(AcceptanceTester $I)
    {
        parent::_before($I);
    }

    public function _after()
    {
    }

    public function view_profile(AcceptanceTester $I)
    {
        $I->wantTo("view a user's profile");

        $I->amOnPage('users');

        NavBarComponent::goToMyProfile($I);

        $I->seeInCurrentUrl('profile');
    }

}
class_name: AcceptanceTester
modules:
    enabled:
        - Laravel4
        - AcceptanceHelper
        - WebDriver
        - Db
    config:
        Laravel4:
            cleanup: false
            environment: test
        WebDriver:
            url: 'http://myapp.test'
            browser: phantomjs
            window_size: 1024x768
        Db:
            dsn: 'pgsql:host=localhost;dbname=myapp_testing'
            user: 'myapp_testing'
            password: 'myapp_testing'
            dump: tests/_data/test-dump.sql
            populate: true
            cleanup: false