The problem
- I am using Laravel
8.83.23
- I have schema dump from squashed migrations in
databaseschemamysql-schema.dump
- tests are running above test database, as in
database.php
'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', ''),
],
- Before I squashed migrations, my test cases only used
DatabaseMigrations
trait, and the test database was recreated every time and all worked, example of test class:
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
- the migrations were found and executed, recreating the database
- then, I squashed the migrations, so all migrations got deleted, and I got
databaseschemamysql-schema.dump
php artisan migrate
works as expected through command line, creating full database schemas from the dump (it finds it)- tests however no longer work, as there is an error
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cinema_test.roles' doesn't exist (SQL: delete from `roles`)
- when I check the sql test database after the test runs, it is empty (only table
migrations
gets created there, and it is empty) - this error persists even when I call
artisan migrate
in the test’s setup:
public function setUp(): void
{
parent::setUp();
Artisan::call('migrate', array(
'--database' => 'testing',
'--force' => true));
//it crashes here
$this->seed(RoleAndPermissionSeeder::class);
RoleAndPermissionSeeder
just operates with the sql tables, which do not exist, hence the error- I even tried
DatabaseMigrations
andDatabaseTransactions
andRefreshDatabase
traits, without any success - how do I populate the database data? There is no way for me to read the output of the
Artisan::call('migrate')
command, so I do not know what is happening there - return code of
Artisan::call('migrate')
is0
- is there maybe some setup I am missing?
2
Answers
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 onedatabase.php
I had the main database connection:and the testing connection
testing
connection data into a newmysql
connection, just to see, whether on a command line I get same resultsphp artisan:migrate
phpunit.xml
, I will explain it nowThe file
phpunit.xml
The
phpunit.xml
was as follows (not full file shown here):phpunit.xml
becamedatabase.php
and related obsolete variables from.env
fileConclusion
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.
Seems like schema dumps can’t be used for the in-memory database when testing
https://laravel.com/docs/9.x/migrations#squashing-migrations
May be able to do something like this
DB::unprepared(file_get_contents("path/file.sql"));
Would only try as a last resort, personally would want a test environment migration, also you should add a check for a test environment migration if you take this approach