Laravel не может подключиться к sqlite во время тестирования и использует настройки postgresql для разработки - PullRequest
3 голосов
/ 25 июня 2019

У меня есть следующий phpunit тест:

namespace  Test\Database\Integration\Repositories;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Repositories\RoverRepository;
use App\Model\Rover;
use App\Model\Grid;

class RoverRepositoryTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Undocumented variable
     *
     * @var RoverRepository|null
     */
    private $repository=null;

    /**
     * Undocumented variable
     *
     * @var Grid|null;
     */
    private $grid=null;

    public function setUp(): void
    {
        parent::setUp();

        $this->runDatabaseMigrations();

        $grid=factory(Grid::class)->create([
            'width'=>5,
            'height'=>5
        ]);

        $rover=factory(Rover::class, 5)->create([
            'grid_id' => $grid->id,
            'grid_pos_x' => rand(0, $grid->width),
            'grid_pos_y' => rand(0, $grid->height),
        ]);

        $this->grid=$grid;
        //How do I run Migrations and generate the db?

        $this->repository = new RoverRepository();
    }

    public function tearDown(): void
    {
        parent::tearDown();
        //How do I nuke my Database?
    }

   /**
     * Testing Base Search
     *
     * @return void
    */
    public function testBasicSearch(): void
    {
        $this->assertTrue(true);
    }
}

И мой phpunit.xml установлен как:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>

        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
        <testsuite name="Database">
            <directory suffix="Test.php">./tests/Database</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="MAIL_DRIVER" value="array"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="DB_CONNECTION" value="sqlite"/>
        <env name="DATABASE_URL" value="localhost"/>
        <env name="DB_DATABASE" value=":memory:"/>
    </php>
</phpunit>

Но по какой-то причине, когда я запускаю свой тест скоманда:

1) Test\Database\Integration\Repositories\RoverRepositoryTest::testBasicSearch
Illuminate\Database\QueryException: SQLSTATE[08006] [7] FATAL:  password authentication failed for user "laravel" (SQL: select tablename from pg_catalog.pg_tables where schemaname = 'public')

/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:624
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:333
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Schema/PostgresBuilder.php:108
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Schema/PostgresBuilder.php:35
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:79
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:46
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:576
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:183
/var/www/html/vendor/symfony/console/Command/Command.php:255
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:170
/var/www/html/vendor/symfony/console/Application.php:921
/var/www/html/vendor/symfony/console/Application.php:273
/var/www/html/vendor/symfony/console/Application.php:149
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:182
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:275
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:136
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:220
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:56
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:55
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:18
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:105
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:72
/var/www/html/tests/Database/Integration/Repositories/RoverRepositoryTest.php:31

Caused by
PDOException: SQLSTATE[08006] [7] FATAL:  password authentication failed for user "laravel"

/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:46
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connectors/PostgresConnector.php:33
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php:182
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:918
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:943
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:399
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:325
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:657
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:624
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:333
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Schema/PostgresBuilder.php:108
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Schema/PostgresBuilder.php:35
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:79
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:46
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:576
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:183
/var/www/html/vendor/symfony/console/Command/Command.php:255
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:170
/var/www/html/vendor/symfony/console/Application.php:921
/var/www/html/vendor/symfony/console/Application.php:273
/var/www/html/vendor/symfony/console/Application.php:149
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:182
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:275
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:136
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:220
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:56
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:55
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:18
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:105
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:72
/var/www/html/tests/Database/Integration/Repositories/RoverRepositoryTest.php:31

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

Для настройки производства я использую следующий файл .env для базы данных thw:

DB_CONNECTION=pgsql
DB_HOST=postgresql
DB_PORT=5432
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=IDontTellYouThisIsNotAnActuallPassword

ТАК У меня есть 2 вопроса:

  • Почему вводятся мои настройки для sqlite?
  • Как принудительно использовать память sqlite при тестировании?

Редактировать 1

Я сделал файлс именем .env.testing:

DB_CONNECTION=sqlite
DATABASE_URL=localhost
DB_DATABASE=:memory:

И изменил мой phpunit.xml на:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>

        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
        <testsuite name="Database">
            <directory suffix="Test.php">./tests/Database</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="BCRYPT_ROUNDS" value="4"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="MAIL_DRIVER" value="array"/>
        <env name="QUEUE_CONNECTION" value="sync"/>
        <env name="SESSION_DRIVER" value="array"/>
    </php>
</phpunit>

Также настройки для sqlite в laravel's:

'sqlite' => [
            'driver' => 'sqlite',
            'url' => env('DATABASE_URL'),
            'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'prefix' => '',
            'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
        ],

Редактировать2

Я попробовал как предложено:

namespace  Test\Database\Integration\Repositories;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use App\Repositories\RoverRepository;
use App\Model\Rover;
use App\Model\Grid;

class RoverRepositoryTest extends TestCase
{
    use RefreshDatabase;
    use DatabaseMigrations;

    /**
     * Undocumented variable
     *
     * @var RoverRepository|null
     */
    private $repository=null;

    /**
     * Undocumented variable
     *
     * @var Grid|null;
     */
    private $grid=null;

    public function setUp(): void
    {
        parent::setUp();

        $this->runDatabaseMigrations();

        $grid=factory(Grid::class)->create([
            'width'=>5,
            'height'=>5
        ]);

        $rover=factory(Rover::class, 5)->create([
            'grid_id' => $grid->id,
            'grid_pos_x' => rand(0, $grid->width),
            'grid_pos_y' => rand(0, $grid->height),
        ]);

        $this->grid=$grid;
        //How do I run Migrations and generate the db?

        $this->repository = new RoverRepository();
    }

    public function tearDown(): void
    {
        parent::tearDown();
        //How do I nuke my Database?
    }

   /**
     * Testing Base Search
     *
     * @return void
    */
    public function testBasicSearch(): void
    {
        $this->assertTrue(true);
    }
}

И затем я запускаю следующие команды:

php artisan config:clear
php artisan config:clear --env=testing
php artisan config:clear --env=development
php artisan config:cache

Все еще ошибка продолжается.

Редактировать3

После многих испытаний я очищаю файл .env.Затем я запускаю команду:

php artisan config:cache

И ошибка меняется на:

PHPUnit 7.5.13 by Sebastian Bergmann and contributors.

E                                                                   1 / 1 (100%)

Time: 111 ms, Memory: 18.00 MB

There was 1 error:

1) Test\Database\Integration\Repositories\RoverRepositoryTest::testBasicSearch
Mockery\Exception\BadMethodCallException: Received Mockery_1_Illuminate_Console_OutputStyle::askQuestion(), but no expectations were specified

/var/www/html/vendor/symfony/console/Style/SymfonyStyle.php:222
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:332
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/ConfirmableTrait.php:31
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:34
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:576
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:183
/var/www/html/vendor/symfony/console/Command/Command.php:255
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:170
/var/www/html/vendor/symfony/console/Application.php:921
/var/www/html/vendor/symfony/console/Application.php:273
/var/www/html/vendor/symfony/console/Application.php:149
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:182
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:275
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:136
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:220
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:56
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:55
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/RefreshDatabase.php:18
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:105
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:72

Также, если я сохраняю только настройки sqlite и восстанавливаю в исходное .env, я получаюошибка:

PHPUnit 7.5.13 by Sebastian Bergmann and contributors.

E                                                                   1 / 1 (100%)

Time: 115 ms, Memory: 18.00 MB

There was 1 error:

1) Test\Database\Integration\Repositories\RoverRepositoryTest::testBasicSearch
InvalidArgumentException: Database [pgsql] not configured.

/var/www/html/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:152
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:115
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:86
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:77
/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/FreshCommand.php:46
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:32
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php:34
/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:576
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:183
/var/www/html/vendor/symfony/console/Command/Command.php:255
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Command.php:170
/var/www/html/vendor/symfony/console/Application.php:921
/var/www/html/vendor/symfony/console/Application.php:273
/var/www/html/vendor/symfony/console/Application.php:149
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:90
/var/www/html/vendor/laravel/framework/src/Illuminate/Console/Application.php:182
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:275
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:136
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/PendingCommand.php:220
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithConsole.php:56
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseMigrations.php:16
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:109
/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:72

Это означает, что .env.testing полностью игнорируется, если указан .env.

Ответы [ 4 ]

1 голос
/ 25 июня 2019

При реализации базы данных SQLite для тестирования вам не нужно указывать URL базы данных, поскольку она работает в памяти.

Удалить строку из phpunit.xml

<env name="DATABASE_URL" value="localhost"/>

Возможно, ваш конфиг кэшируется. Запустите команду

php artisan config:clear

Теперь повторите тест.

Удалить код из функции setUp ()

$this->runDatabaseMigrations();

Для переноса базы данных в SQLite вы можете использовать

use Illuminate\Foundation\Testing\DatabaseMigrations;

Редактировать: Для config / database.php

Для использования SQLite необходимо настроить файл database.php.

//config/database.php 
...
'sqlite' => [
    'driver' => 'sqlite',
    'database' => storage_path('database/database.sqlite'),
    'prefix' => '',
    'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
    ],
...
1 голос
/ 25 июня 2019

похоже, что ваши тесты все еще используют базу данных sql.

при выполнении тестов с использованием базы данных SQLite я предлагаю вам проверить следующее:

  1. ваш database.sqlite должен быть создан в папке базы данных, и не забудьте настроить права файла.

  2. Вы должны включить эти 2 черты:

// this trait is used to wrap every query in a transaction where this one will be deleted at the end of the test
use DatabaseTransactions;

// this one allow Laravel to prepare the database
use DatabaseMigrations;

если он все еще не работает, я предлагаю вам остановить сервер, выполнить текущую команду ремесленника php artisan config:clear и перезапустить его.

EDIT

Я только что увидел, что ваш phpunit.xml содержит какую-то ошибку, удалите все теги env и добавьте только эти:

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>

создание .env.testing не требуется

0 голосов
/ 25 июня 2019

Используете ли вы какую-либо переменную среды с ОЧЕНЬ ЖЕ ИМЯ с той, которая указана в .env?Иногда theese может вызвать огромный конфликт с теми, которые указаны в .env ovveriding их.

В вашем случае это может быть в этом случае либо с использованием Homestead или docker с docker-compose, в этих случаяхХорошая идея - установить уникальный префикс, определяющий его использование.Например, использование имен, таких как DB_CONNECTION, назовите его DOCKER_DB_CONNECTION, следовательно, никакого конфликта вообще нет.

Также в случае docker-compose это плохая идея:

version: '3.1'
services:
  develop:
    image: ddesyllas/php-dev:dev-n-build
    volumes:
      - ".:/var/www/html"
      - "./.laravel.env:/var/www/html/.env"
    links:
      - memcache
    environment:
      DB_CONNECTION: pgsql
      DB_HOST : postgresql
      DB_PORT : 5432
      DB_DATABASE: ${DOCKER_POSTGRES_DB}
      DB_USERNAME: ${DOCKER_POSTGRES_USER}
      DB_PASSWORD: ${DOCKER_POSTGRES_PASSWORD}

  nginx:
    image: nginx:alpine
    ports:
      - 7880:7880
    links:
      - "develop:develop"
    volumes:
      - ".:/var/www/html"
      - "./docker/nginx.conf:/etc/nginx/nginx.conf:ro"


  postgresql:
    image: postgres:alpine
    volumes:
      - './docker/misc_volumes/postgresql:/var/lib/postgresql/data'
    environment:
      POSTGRES_USER: ${DOCKER_POSTGRES_USER}
      POSTGRES_DB: ${DOCKER_POSTGRES_DB}
      POSTGRES_PASSWORD: ${DOCKER_POSTGRES_PASSWORD}

  memcache:
    image: memcached:alpine

Вместо этого используйте имена переменных среды, как указано в следующем docker-compose.yml - хорошая идея:

version: '3.1'
services:
  develop:
    image: ddesyllas/php-dev:dev-n-build
    volumes:
      - ".:/var/www/html"
      - "./.laravel.env:/var/www/html/.env"
    links:
      - memcache
    environment:
      DOCKER_DB_CONNECTION: pgsql
      DOCKER_DB_HOST : postgresql
      DOCKER_DB_PORT : 5432
      DOCKER_DB_DATABASE: ${DOCKER_POSTGRES_DB}
      DOCKER_DB_USERNAME: ${DOCKER_POSTGRES_USER}
      DOCKER_DB_PASSWORD: ${DOCKER_POSTGRES_PASSWORD}

  nginx:
    image: nginx:alpine
    ports:
      - 7880:7880
    links:
      - "develop:develop"
    volumes:
      - ".:/var/www/html"
      - "./docker/nginx.conf:/etc/nginx/nginx.conf:ro"


  postgresql:
    image: postgres:alpine
    volumes:
      - './docker/misc_volumes/postgresql:/var/lib/postgresql/data'
    environment:
      POSTGRES_USER: ${DOCKER_POSTGRES_USER}
      POSTGRES_DB: ${DOCKER_POSTGRES_DB}
      POSTGRES_PASSWORD: ${DOCKER_POSTGRES_PASSWORD}

  memcache:
    image: memcached:alpine

Вы заметили, что я переименовал переменные среды следующим образом:

  • DB_CONNECTION=> DOCKER_DB_CONNECTION
0 голосов
/ 25 июня 2019

Убедитесь, что ваш файл .env имеет тот же пароль, что и ваша база данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...