bigweld86's avatar

Database tables deleted after running phpunit test

Hi. Every time I run a test all my database tables (except for the migrations table) are being deleted and I have to run the migrations again. For instance, if I have the following tables:

migrations users tableA tableB

after running:

phpunit --filter user_can_view_a_record ViewRecordTest tests/Feature/ViewRecordTest.php

my tables are deleted and I end up with just the migrations table.

I'm using MySQL as database and according to the configuration I have set up the tests are being running in memory:

database.php

'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            //'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'database' => ':memory:',
            'prefix' => '',
        ],

        'mysql' => [
            'driver' => 'mysql',
            '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' => '',
            'strict' => false,
            'engine' => null,
            'sticky' => 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="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <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=":memory:" />
    </php>
</phpunit>

Thanks

0 likes
9 replies
bigweld86's avatar

Indeed I had it, but after commenting it out I'm still getting the same outcome

Cronix's avatar

Check the classes that your class is extending, as well. I'm also not sure if in-memory databases persist after the tests run.

Tray2's avatar

You need to make sure that phpunit uses the phpunit.xml otherwise it will use the normal database and not the in memory database you specified in phpunit.xml.

I use an alias for ./vendor/bin/phpunit and I run it from the project root where my phpunit.xml file is located.

If that still gives you issues you can always specify which phpunit.xml phpunit should use.

2 likes
bigweld86's avatar

@Tray2 tried what you mentioned but didn't work. How can I specify which phpunit.xml phpunit should use? Thanks

tykus's avatar

Are you running PHPUnit from an IDE; make sure it is configured to use your project's phpunit.xml. Otherwise, from the commandline, you will see which PHPUnit configuration is being used.

1 like
Tray2's avatar

try phpunit -c phpunit.xmlor ./vendor/bin -c phpunit.xml

hepabolu's avatar

It looks like you're running into the same problem I ran into where your phpunit tests clear out the database you use for manual testing/development. PHPunit probably uses the correct APP_ENV but somehow fails to pass it on to php artisan that does the database migrations and/or database refresh.

Here is how I solved it:

  1. in config/database.php I added a 'testing' connection which in your case, looking through your description, would be a copy of your 'sqlite' connection.

  2. I created a bash script that I run instead of the ./vendor/bin/phpunit statement:

    php artisan cache:clear
    php artisan config:clear
    
    APP_ENV=testing
    
    ./vendor/bin/phpunit "$@"
    
  3. in CreatesApplication.php I added a function that throws an exception if the database name is not 'testing'. I found this: https://hackernoon.com/how-i-destroyed-the-staging-database-b435f98569ab

kreierson's avatar

This happened to me out of nowhere today.

Ran the following artisan commands and it fixed the issue.

php artisan cache:clear
php artisan config:clear

15 likes

Please or to participate in this conversation.