Как указать другой файл .env для phpunit в Laravel 5?
У меня есть файл .env
, содержащий мои данные о соединении с базой данных, как это обычно бывает для Laravel 5. Я хочу переопределить их для тестирования, что я могу сделать в phpunit.xml
. Однако делать это, похоже, идет вразрез с философией .env
, которая заключается не в том, чтобы определять экологические конфигурации, особенно пароли.
Возможно ли иметь что-то вроде .env.testing
и сообщить phpunit.xml
для чтения из этого?
Ответы
Ответ 1
Скопируйте .env
в .env.testing
, затем отредактируйте файл .env.testing
и измените параметр APP_ENV
, чтобы сделать это как APP_ENV=testing
таким образом, вы сможете указать свои настройки в этом новом файле
Если вы не хотите создавать новый файл .env.testing
, вы должны указать свои переменные в phpunit.xml
в разделе php со значениями, которые вам нужны, что-то вроде этого
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value="testing"/>
</php>
Просто используйте значения ключей в разделе имен и значение этого ключа в разделе значений.
В этом примере я указываю phpunit использовать базу данных sqlite с именем тестирования.
Кстати, в config/database.php я добавил это
'default' => env('DB_CONNECTION', 'mysql'),
использовать mysql по умолчанию, если я не укажу что-то другое, как в этом случае.
Ответ 2
Вы можете переопределить файл .env
, используемый в вашем файле TestCase
, где среда загружается для тестирования.
Более конкретно:
Тесты /TestCase.php
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
/* @var \Illuminate\Foundation\Application $app */
$app = require __DIR__ . '/../bootstrap/app.php';
$app->loadEnvironmentFrom('.env.testing'); // specify the file to use for environment, must be run before boostrap
$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();
return $app;
}
Все тесты, расширяющие TestCase
будут использовать этот файл конфигурации.
Обратите внимание, что любой параметр, определенный в phpunit.xml
, переопределит эту конфигурацию.
Обновить
Начиная с Laravel5.4, функция createApplication
больше не находится в tests\TestCase
. Он был перемещен в черту tests\CreatesApplication
.
Ответ 3
Это 2019.
У меня были такие проблемы до тех пор, пока я не смог разобраться.
И вот мое предположение:
Если вам также трудно заставить ваш PHPUnit.xml общаться с вашим файлом .env.testing, то вы, вероятно, используете PHPStorm!
Если это правда, продолжайте чтение.
Если нет, то нет... это не поможет.
Хорошо...
Вот, пожалуйста:
- Зайдите в настройки вашего PHPStorm или просто нажмите Ctrl + Alt + S.
- Перейти к разделу Языки и фреймворки >> PHP >> Тест фреймворков
- На вкладке "Выполнение теста" щелкните "Файл конфигурации по умолчанию" и выберите (нажав на значок папки) путь к файлу PHPUnit.xml вашего проекта.
Для этого все ваши изменения в файле XML вступят в силу.
Итак, продолжайте, создайте файл .env.testing, создайте предпочтительные переменные конфигурации БД для тестирования... и попробуйте снова запустить ваши тесты!
Ответ 4
Создайте локальную базу данных на вашем компьютере-разработчике, например. 'Local_test_db'
Создайте новый файл .env.testing.
DB_DATABASE=local_test_db
DB_USERNAME=root
Убедитесь, что в файле phpunit.xml имеется по крайней мере один env var:
<php>
<env name="APP_ENV" value="testing"/>
</php>
Наконец, ваш базовый тестовый файл (TestCase.php) должен выполнить миграцию, чтобы заполнить db таблицами:
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
}
public function tearDown()
{
Artisan::call('migrate:reset');
parent::tearDown();
}
Ответ 5
Из этого ссылка
Способ 1
Шаг 1. Создайте новое соединение с тестовой базой данных в базе данных /Config.php, как показано ниже:
return [
...
'default' => env('DB_CONNECTION', 'db'),
'connections' => [
'sqlite_testing_db' => [
'driver' => 'sqlite',
'database' => storage_path().'/testing_database.sqlite',
'prefix' => '',
],
/**************** OR ******************/
'testing_db' => [
'driver' => 'mysql',
'host' => env('TEST_DB_HOST', 'localhost'),
'database' => env('TEST_DB_DATABASE', 'forge'),
'username' => env('TEST_DB_USERNAME', 'forge'),
'password' => env('TEST_DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
/** Production or database DB **/
'db' => [
'driver' => 'mysql',
'host' => env('TEST_DB_HOST', 'localhost'),
'database' => env('TEST_DB_DATABASE', 'forge'),
'username' => env('TEST_DB_USERNAME', 'forge'),
'password' => env('TEST_DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
];
Шаг 2: укажите учетные данные базы данных в файле .env
TEST_DB_HOST=localhost
TEST_DB_DATABASE=laravel
TEST_DB_USERNAME=root
TEST_DB_PASSWORD=rootwdp
Шаг 3: Укажите тестовый интерфейс db, который будет использоваться на phpunit.xml.
<env name="DB_CONNECTION" value="testing_db"/>
OR Below If you prefer sqlite
<env name="DB_CONNECTION" value="sqlite_testing_db"/>
Шаг 4: Перенос базы данных в новую тестовую базу данных - если вы решите использовать транзакцию базы данных для вставки отката в таблице.
php artisan migrate --database=testing_db
//If using sqlite
touch storage/testing_database.sqlite
php artisan migrate --database=sqlite_testing
Шаг 5: Теперь Unit test с транзакцией базы данных выглядит следующим образом:
<?php
use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UserTest extends TestCase
{
use DatabaseTransactions;
/** @test */
function it_test_user_can_be_saved()
{
factory(User::class, 2)->create();
$users = User::all();
$this->assertEquals(2, $users->count());
}
}
//Run Php Unit
-> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php
Примечание. Если вы предпочитаете не использовать транзакцию базы данных, вы можете использовать метод настройки и удаления в классе TestCase.php для переноса и отката базы данных, как показано ниже:
<?php
use Illuminate\Support\Facades\Artisan;
class TestCase extends Illuminate\Foundation\Testing\TestCase
{
...
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
}
public function tearDown()
{
Artisan::call('migrate:reset');
parent::tearDown();
}
}
Ответ 6
Я не могу думать о другом способе, кроме временного переименования .env.testing в .env до начала модульных тестов.
Вы можете поместить некоторую логику в bootstrap/autoload.php, поскольку это то, что phpunit использует в качестве загрузочного файла перед загрузкой приложения.
Ответ 7
В вашем приложении app.php измените раздел Dotenv
$envFile = 'testing' === env('APP_ENV') ? '.env.testing' : null;
try {
(new Dotenv\Dotenv(__DIR__ . '/../', $envFile))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
//
}
Это будет работать, поэтому PHPUnit изменяет env перед загрузкой вашего приложения. Так что если вы выполняете тесты, вы будете иметь env уже при тестировании
Ответ 8
Я сделал все шаги в ответе @Sambhu Singh, а также последовал его ссылке.
Но я не работал у меня в L5.5
При переносе для меня работало добавление/настройка APP_ENV на "тестирование" перед командой artisan:
APP_ENV=testing php artisan migrate --database=sqlite_testing
Ответ 9
Вот уже несколько месяцев я борюсь с этим и только что столкнулся с этой проблемой Github сегодня.
Из предложенных там решений, вот что вы должны сделать в файле CreatesApplication.php (чтобы удалить кэшированный конфиг, чтобы Laravel загрузил тестовую среду):
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$this->clearCache(); // NEW LINE -- Testing does not work properly with cached stuff.
return $app;
}
/**
* Clears Laravel Cache.
*/
protected function clearCache()
{
$commands = ['clear-compiled', 'cache:clear', 'view:clear', 'config:clear', 'route:clear'];
foreach ($commands as $command) {
\Illuminate\Support\Facades\Artisan::call($command);
}
}
Если после вышеуказанной модификации проблема не исчезла, вы можете пойти дальше, перестроив все приложение следующим образом:
public function createApplication()
{
$createApp = function() {
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
};
$app = $createApp();
if ($app->environment() !== 'testing') {
$this->clearCache();
$app = $createApp();
}
return $app;
}
Это работает очень хорошо для меня.