Rafał's avatar

Not able to run test through SQLite.

I'm not able to run tests through SQLite,

Running: phpunit -c phpunit.xml

I did manage to change:

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="bootstrap/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Application Test Suite">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
            <exclude>
                <file>./app/routes/web.php</file>
            </exclude>
        </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="testing_sqlite"/>
        <env name="DB_TYPE" value="testing_sqlite"/>


        <ini name="display_errors" value="On" />
        <ini name="display_startup_errors" value="On" />
    </php>
</phpunit>
'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset'   => 'utf8',
            'collation' => 'utf8_general_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],

        'testing_sqlite' => [
            'driver'   => 'sqlite',
            'database' => ':memory:', // storage_path().'/testing.sqlite',
            'prefix'   => '',
        ],
]

The most shady thing is that I had to apply

protected $connectionsToTransact = ['mysql', 'sqlite'];

in TestCase class

because it was not wrapping transaction over , so I figured out that somewhere mysql connection is defined (??!) and it should be added to remove

Return from PHPUnit

PHPUnit 4.8.31 by Sebastian Bergmann and contributors.

.EE

Time: 528 ms, Memory: 17.75MB

There were 2 errors:

1) GenericListingManagerTest::it_allows_to_add_items
InvalidArgumentException: Database [mysql] not configured.

and that's the case because I do not use "mysql" driver/connection in phpunit configs:

  • nor .env
  • nor phpunit.xml
  • nor database.php@'default' = 'sqlite'
0 likes
6 replies
ejdelmonico's avatar

You may want to try using it this way:

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

This always works for me.

1 like
Rafał's avatar

For

        <env name="DB_CONNECTION" value="sqlite"/>
        <env name="DB_TYPE" value="testing_sqlite"/>

i get PDO Exception!

1) GenericListingManagerTest::it_allows_to_add_items
Doctrine\DBAL\Driver\PDOException: SQLSTATE[HY000] [1044] Access denied for user ''@'localhost' to database ':memory:'

that's weird!

If I set this up like this:

        <env name="DB_CONNECTION" value="mysql"/>
        <env name="DB_TYPE" value="testing_sqlite"/>

        <env name="DB_HOST" value="127.0.0.1"/>
        <env name="DB_PORT" value="3306"/>
        <env name="DB_USERNAME" value="root"/>
        <env name="DB_DATABASE" value="db"/>
        <env name="DB_PASSWORD" value="db"/>

i get SQLite Exception!

1) GenericListingManagerTest::it_allows_to_add_items
InvalidArgumentException: Database (db) does not exist.

/var/www/html/laravel/vendor/laravel/framework/src/Illuminate/Database/Connectors/SQLiteConnector.php:34
ejdelmonico's avatar

@rafal Do you still have this in your config/database.php?

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

If you are using the SQLite DB in memory, you don't have to declare anything in the config or .env

Rafał's avatar

Hmm.. I'm feeling like error from SQLite falls back database connection to mysql. But there is no logs or occurences.

Rafał's avatar

Now I'm on:

'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset'   => 'utf8',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
],

'testing_sqlite' => [
        'driver'   => 'sqlite',
        'database' => ':memory:',
    'prefix'   => '',
],
            
<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_TYPE" value="testing_sqlite"/>

        <env name="DB_HOST" value="127.0.0.1"/>
        <env name="DB_PORT" value="3306"/>
        <env name="DB_USERNAME" value="root"/>
        <env name="DB_DATABASE" value="db"/>
        <env name="DB_PASSWORD" value="db"/>

        <ini name="display_errors" value="On" />
        <ini name="display_startup_errors" value="On" />
</php>

now the replication:

  1. Do not migrate any tables into SQLite
  2. Define factory object:
$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => bcrypt(str_random(10)),
        'remember_token' => str_random(10),
    ];
});
  1. Run test (use DatabaseTransactions) which add this object (assume that you have valid structure in mySQL). Its should be green. Even though you've used DB Transaction trait no transaction will be runned.
  2. Add in TestCase.php
class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    protected $connectionsToTransact = ['sqlite'];

    ...
}

you will se error, change to:

class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    protected $connectionsToTransact = ['sqlite', 'mysql'];

    ...
}

you will see green with DB rollback

ejdelmonico's avatar

In my TestCase, I don't declare any DB's to connect so I couldn't respond to that. However, I mostly use this in my tests: use DatabaseMigrations;

Please or to participate in this conversation.