Как указать другой файл.env для phpunit в Laravel 5?

У меня есть .env файл, содержащий информацию о моем соединении с базой данных, как обычно для Laravel 5. Я хочу переопределить их для тестирования, что я могу сделать в phpunit.xml, Тем не менее, выполнение этого, кажется, идет вразрез с философией .env что не для фиксации конфигураций среды, в частности паролей.

Возможно ли иметь что-то вроде .env.testing и скажи phpunit.xml читать из этого?

7 ответов

Скопируйте свой .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 по умолчанию, если я не укажу что-то другое, как в этом случае.

Вы можете переопределить .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 черта характера.

Создайте локальную базу данных на вашем компьютере разработчика, например, 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) должен выполнить миграцию, чтобы заполнить базу данных таблицами:

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();
}

Это 2019 год. У меня были такие проблемы так долго, что я не смог разобраться. И вот мое предположение: если вам также трудно заставить ваш PHPUnit.xml общаться с вашим файлом.env.testing, то вы, вероятно, используете PHPStorm! Если это правда, продолжайте читать. Если нет, нет... это не поможет. Хорошо... Вот, пожалуйста

  1. Зайдите в настройки вашего PHPStorm или просто нажмите Ctrl + Alt + S.
  2. Перейти к Языки и фреймворки >> PHP >> Тест фреймворков
  3. На вкладке "Выполнение теста" щелкните "Файл конфигурации по умолчанию" и выберите (нажав на значок папки) путь к файлу PHPUnit.xml вашего проекта.

Для этого все ваши изменения в файле XML вступят в силу. Итак, продолжайте, создайте файл.env.testing, создайте ваши предпочтительные переменные конфигурации БД для тестирования... и попробуйте снова запустить ваши тесты!

По этой ссылке

Способ 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: Укажите тестовую связь с БД, которая будет использоваться в 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: Теперь модульный тест с транзакцией базы данных выглядит следующим образом:

<?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();
    }
}

Вот уже несколько месяцев я борюсь с этим и только что столкнулся с этой проблемой 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 doesn't 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;
}

Это работает очень хорошо для меня.

Обновлено

Для пользователей Laravel 5.8 вы можете создать .env.testing файл в корне вашего проекта.

Используйте другой db, например my_app_testing.

Итак, это будет в.env

DB_DATABASE=clinical_managment

и в.env.testing

DB_DATABASE=clinical_managment_testing

Затем проясните конфигурацию.

php artisan config:clear

Повторно запустите тест. В моей настройке это работает.

В вашем 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 уже при тестировании.

Я сделал все шаги в ответе @Sambhu Singh, а также перешел по его ссылке. Но у меня не получилось в L5.5

При переносе добавление / настройка APP_ENV для "тестирования" перед командой ремесленника работало для меня:

APP_ENV=testing php artisan migrate --database=sqlite_testing

Я не могу придумать иного пути, кроме как временно переименовать.env.testing в.env до начала модульных тестов.

Вы могли бы поместить некоторую логику в bootstrap/autoload.php, поскольку именно это phpunit использует в качестве файла начальной загрузки перед загрузкой приложения.

Другие вопросы по тегам