phpmysqllaraveltestinglaravel-8

Laravel tests database migration from schema


The problem


    'testing' => [
                    'driver' => 'mysql',
                    'host' => env('DB_TEST_HOST', '127.0.0.1'),
                    'port' => env('DB_TEST_PORT', '3306'),
                    'database' => env('DB_TEST_DATABASE', 'forge'),
                    'username' => env('DB_TEST_USERNAME', 'forge'),
                    'password' => env('DB_TEST_PASSWORD', ''),
                ],


    class SystemControllerTest extends TestCase
    {
        use WithFaker;
        use DatabaseMigrations;
        /**
         * @var User
         */
        private $user;
    
        public function setUp(): void
        {
            parent::setUp();
    
            //create roles and data
            $this->seed(RoleAndPermissionSeeder::class);
        ... etc


    SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cinema_test.roles' doesn't exist (SQL: delete from `roles`)


    public function setUp(): void
        {
            parent::setUp();
            Artisan::call('migrate', array(
       '--database' => 'testing',
       '--force' => true));
            //it crashes here
            $this->seed(RoleAndPermissionSeeder::class);


Solution

  • I have finally figured this out.

    The reason for the problem

    The problem was in incorrect setup of the testing environment. I have not discovered the exact reason, but I figured out how to setup the testing environment so that the dump would be found and loaded.

    How I hunt down the bug

    This describes my steps on how I found a way to fix this.

    In database.php I have copied testing database instead of normal one
    
        'mysql' => [
                    'driver' => 'mysql',
                    'url' => env('DATABASE_URL'),
                    'host' => env('DB_HOST', '127.0.0.1'),
                    'port' => env('DB_PORT', '3306'),
                    'database' => env('DB_DATABASE', 'forge'),
                    'username' => env('DB_USERNAME', 'forge'),
                    'password' => env('DB_PASSWORD', ''),
                    'unix_socket' => env('DB_SOCKET', ''),
                    'charset' => 'utf8mb4',
                    'collation' => 'utf8mb4_unicode_ci',
                    'prefix' => '',
                    'prefix_indexes' => true,
                    'strict' => false,
                    'engine' => null,
                    'options' => extension_loaded('pdo_mysql') ? array_filter([
                        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                    ]) : [],
                ],
    
    

    and the testing connection

    
        'testing' => [
                        'driver' => 'mysql',
                        'host' => env('DB_TEST_HOST', '127.0.0.1'),
                        'port' => env('DB_TEST_PORT', '3306'),
                        'database' => env('DB_TEST_DATABASE', 'forge'),
                        'username' => env('DB_TEST_USERNAME', 'forge'),
                        'password' => env('DB_TEST_PASSWORD', ''),
                    ],
    
    
    
        'mysql' => [
                    'url' => env('DATABASE_URL'),
                    'driver' => 'mysql',
                        'host' => env('DB_TEST_HOST', '127.0.0.1'),
                        'port' => env('DB_TEST_PORT', '3306'),
                        'database' => env('DB_TEST_DATABASE', 'forge'),
                        'username' => env('DB_TEST_USERNAME', 'forge'),
                        'password' => env('DB_TEST_PASSWORD', ''),
                    'unix_socket' => env('DB_SOCKET', ''),
                    'charset' => 'utf8mb4',
                    'collation' => 'utf8mb4_unicode_ci',
                    'prefix' => '',
                    'prefix_indexes' => true,
                    'strict' => false,
                    'engine' => null,
                    'options' => extension_loaded('pdo_mysql') ? array_filter([
                        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                    ]) : [],
                ],
        
        /*'testing' => [
                        'driver' => 'mysql',
                        'host' => env('DB_TEST_HOST', '127.0.0.1'),
                        'port' => env('DB_TEST_PORT', '3306'),
                        'database' => env('DB_TEST_DATABASE', 'forge'),
                        'username' => env('DB_TEST_USERNAME', 'forge'),
                        'password' => env('DB_TEST_PASSWORD', ''),
                    ],*/
    
    
    The file phpunit.xml

    The phpunit.xml was as follows (not full file shown here):

    
           <server name="QUEUE_CONNECTION" value="sync"/>
            <server name="SESSION_DRIVER" value="array"/>
            <server name="TELESCOPE_ENABLED" value="false"/>
            <env name="DB_CONNECTION" value="testing"/>     
        </php>
    </phpunit>
    
    
           <server name="QUEUE_CONNECTION" value="sync"/>
            <server name="SESSION_DRIVER" value="array"/>
            <server name="TELESCOPE_ENABLED" value="false"/>
            <env name="DB_DATABASE" value="cinema_test"/>   
        </php>
    </phpunit>
    
    
    Conclusion

    Although I have not figured out the real cause for the lavavel not loading the dump file, I have found a workaround which was to only change the database name for tests, instead of defining entirely new sql connection for testing pursposes. This solved the issue, and the database dump file gets loaded during tests now.