Я использую Vagrant (усадьба), PHP 5.5.12 и Laravel 4.2. Я пытаюсь настроить кодовое восприятие для использования среды тестирования для приемочных тестов (работающих на phantomJS). На усадьбе у меня есть две среды: локальная и тестовая. Я старался не дублировать стандартную среду тестирования, зарезервированную для тестов PHPUnit.
Моя проблема в том, что, хотя я могу использовать Eloquent для создания экземпляра пользователя (и извлечения его), я не могу аутентифицироваться с этим пользователем ни для одного из моих тестов. Это мешает мне запустить мой набор тестов, 90% из которых требует аутентификации пользователя.
У меня есть два сайта, определенных в / etc / nginx / sites-available: myapp.app и myapp.test. Я определяю fastcgi_param APP_ENV как локальный и тестовый (соответственно). Я также указал APP_ENV в моем ~ / .bashrc, поэтому echo $ APP_ENV возвращает ‘local’. Я создал соответствующую папку config / test с учетными данными database.php, которые указывают на тестовую базу данных. Ниже приведены настройки codeception.yml по умолчанию и те, которые переопределяются настройками accept.suite.yml (это пакет, который я специально запускаю).
Я не могу пройти аутентификацию в тестовой среде. Все попытки сделать это возвращают false или null.
actor: Tester
paths:
tests: tests
log: tests/_output
data: tests/_data
helpers: tests/_support
settings:
bootstrap: _bootstrap.php
colors: true
memory_limit: 1024M
modules:
config:
Db:
dsn: 'pgsql:host=localhost;dbname=myapp'
user: 'myapp'
password: 'myapp'
dump: tests/_data/dump.sql
class_name: AcceptanceTester
modules:
enabled:
- Laravel4
- AcceptanceHelper
- WebDriver
- Db
config:
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
Этот помощник принятия компилируется в класс AcceptanceTester и запускается в фильтре before на всех моих Cests, требующих аутентификации. Я протестировал вывод метода User :: create, и он фактически создает объект пользователя, к которому я могу получить доступ, например, в методе входа в систему. Однако он не отображается в моей базе данных (если смотреть с Navicat). База данных в настоящее время заполняется из файла test-dump.sql и содержит только схему без каких-либо данных. Я не уверен, почему метод создания Eloquent не записывает данные в базу данных, но я думаю, что откат базы данных выполняется после запуска набора тестов.
<?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' => '[email protected]'
]);
$this->login($I, '[email protected]', '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 [email protected]');
}
public function logoutUser(AcceptanceTester $I)
{
$I->amOnPage('/logout');
$I->seeCurrentUrlEquals('/login');
$I->see('You have been logged out');
}
}
Ниже приведено действие store на контроллере сессий, которое должно аутентифицировать пользователей (и которое отлично работает в «локальной» среде для http-запросов myapp.app). Для попыток входа в myapp.test метод Auth :: try возвращает false.
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();
}
Я набрал номер прямо в метод Auth :: попытки, который вызывает Auth / Guard-> hasValidCredentials.
protected function hasValidCredentials($user, $credentials)
{
return ! is_null($user) && $this->provider->validateCredentials($user, $credentials);
}
Это возвращает ноль. Чтобы уточнить, он даже возвращает NULL НЕМЕДЛЕННО после вызова $ user-> first_name и возвращает true, или User :: all () -> first () -> first_name возвращает правильное имя. Другими словами, я могу создать и затем извлечь пользователя с помощью Eloquent, а затем сразу же после этого проверить Auth :: попытку, которая в конечном итоге вызывает hasValidCredentials, которая вызывает Eloquent / Builder-> где, ищет на основе адреса электронной почты формы входа в систему и возвращает ноль. Возможно ли, что пользователь хранится в памяти, а не в базе данных?
Я вручную создал пользователя и попытался выполнить аутентификацию вручную, и форма входа в систему просто перезагружается. У меня нет таких проблем аутентификации в «локальной» среде.
Приведенный ниже метод вызывается во время аутентификации и возвращает объект запроса, который содержит нулевой результат.
call_user_func_array(array($this->query, 'where'), func_get_args());
Ниже мой файл UserCest.php. BaseAcceptanceHelper просто вызывает функцию AcceptanceTester-> login для аутентификации тестового пользователя по умолчанию. Это не удается.
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');
}
}
Любая помощь будет принята с благодарностью. Я полностью в замешательстве относительно того, почему аутентификация терпит неудачу.
Решение состоит в том, чтобы определить параметры конфигурации для модуля Laravel4, в accept.suite.yml:
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
предотвращает откат среды БД между тестами и environment: test
говорит Laravel4 использовать правильную базу данных.
Еще одна проблема, с которой я столкнулся, которую я не осознавал во время публикации, заключалась в том, что моя папка «test» окружения продублировала файлы конфигурации cache.php и session.php из среды тестирования Laravel по умолчанию, которая назначает оба кеш и сессия в массиве в памяти. Между сессиями не было данных сеанса, что делало невозможной аутентификацию. Я просто удалил эти два файла из config / test, и я был в порядке.
Других решений пока нет …