VERSIONS: Laravel v5.8.21 & Laravel Dusk v5.1.0
I'm having real issues with getting Dusk to work with a testing database. I seem to have gone through every piece of advice and still no luck. Dusk is not loading my .env.dusk.local file for some reason. Can anyone help?
// test
class ApplicationTest extends DuskTestCase
{
use DatabaseMigrations;
/** #test */
public function it_works()
{
$this->browse(function (Browser $browser) {
$browser->visit('/test')->assertSee('It works!');
});
}
}
// .env.dusk.local
APP_NAME="Laravel"
APP_ENV=local
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=dusk
// database.php
'dusk' => [
'driver' => 'sqlite',
'database' => database_path('dusk.sqlite'),
'prefix' => '',
]
Then I run the PHP web server with php artisan serve --env=dusk.local however Dusk uses the .env file and goes to my development site using the development database.
What am I doing wrong?
I think you might need to update Laravel. Are you using an older version of the framework? This used to be a bug pre-5.8.7. See: https://github.com/laravel/framework/issues/27828
I'm getting this error:
Database (homestead) does not exist.
When I try this simple Dusk test:
class ShowArticleTest extends DuskTestCase
{
use DatabaseMigrations;
/** #test */
public function it_shows_all_articles()
{
Article::create([
'title' => 'My First Article',
'body' => 'Some body text.'
]);
$this->browse(function (Browser $browser) {
$browser->visit('/articles')
->assertSee('My First Article');
});
}
}
I can see in the stack trace that the error comes from the controller method that handles the /articles request, which looks like this:
public function all()
{
Article::all();
}
So it seems that the database is accessible by the test itself but not by the controller.
The .env.dusk.local file looks like this:
DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
The homestead file is being created in my project root folder. The file is found inside the virtual machine too and the permissions looks like this:
-rw-rw-r-- 1 vagrant vagrant
Tried setting DATABASE to database/testing.sqlite in .env.dusk.local. The file is created once Dusk starts but the error still says that it can't find the database/testing.sqlite database.
Database (database/testing.sqlite) does not exist.
The database file can be accessed using the sqlite3 CLI and I can query for records without problem.
I'm using Laravel 5.5 and Homestead.
The problem occurs inside config/database.php, around here:
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
]
Because DB_DATABASE inside .env.dusk.local is defined as homestead, the configuration value for database.connections.sqlite.database ends up just the same: homestead.
The actual value should be the full path to the file, which can be obtained with the database_path() helper. So, by simple moving database_path() out of the env() call:
'database' => database_path(env('DB_DATABASE', 'database.sqlite'))
The value for database.connections.sqlite.database becomes the full path to the database file and everything seems to be working.
I would like to add sqlite db to my lumen app but I have some troubles.
I create migration:
php artisan make:migration create_users_table --create=users
then I changed my .env file, so it looks like:
DB_CONNECTION=sqlite
DB_HOST=localhost
DB_DATABASE=database.sqlite
then I was created database.sqlite and put it in storage folder and when I 'm trying to do:
php artisan migrate
I have
[InvalidArgumentException]
Database (database.sqlite) does not exist.
I uncommented this lines in bootstrap/app.php:
Dotenv::load(__DIR__.'/../');
$app->withFacades();
I can't find what is wrong.
I work on ubuntu 14.04
In my .env file I changed to:
DB_CONNECTION=sqlite
# DB_HOST=localhost
# DB_DATABASE=database.sqlite
I left only
DB_CONNECTION=sqlite
So Lumen use default config from /vendor/laravel/lumen-framework/config/database.php. It works.
According to lumen-framwork/config/database.php
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', storage_path('database.sqlite')),
'prefix' => env('DB_PREFIX', ''),
],
sqlite is the default setting for lumen.
And you can set DB_CONNECTION in .env as follows:
DB_CONNECTION=sqlite
Then lumen will use storage_path('database.sqlite') as storage/database.sqlite
Otherwise, if you would like to assign DB_DATABASE directly, you should give the full path:
DB_DATABASE=/Users/../../storage/database.sqlite
Step 1 : Open .env file & replace respective database configuration with following piece of code.
DB_CONNECTION = sqlite
#DB_HOST = 127.0.0.1
#DB_PORT = 3306
#DB_DATABASE = homestead
#DB_USERNAME = homestead
#DB_PASSWORD = secret
Note : lines those are started with # are basically commented code.
Step 2 : Create a new file, name it database.sqlite in database folder. It will store out database structure.
Step 3 : There is need to include this file as ignored in our versioning system as there will be so many changes are going to be made with database i.e. insert, delete, update etc. To ignore database.sqlite, Open .gitignore file, and add this line at the end database/database.sqlite. (i.e. path of database.sqlite file).
I have a .env file containing my database connection details, as is normal for Laravel 5. I want to override these for testing, which I can do in phpunit.xml. However, doing this seems to go against the philosophy of .env which is not to commit environmental configurations, particularly passwords.
Is it possible to have something like .env.testing and tell phpunit.xml to read from that?
You could override the .env file being used in your TestCase file, where the framework is booted for testing.
More specific:
tests/TestCase.php
/**
* Creates the application.
*
* #return \Illuminate\Foundation\Application
*/
public function createApplication()
{
/* #var \Illuminate\Foundation\Application $app */
$app = require __DIR__ . '/../bootstrap/app.php';
$app->loadEnvironmentFrom('.env.testing'); // specify the file to use for environment, must be run before boostrap
$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();
return $app;
}
All the tests extending TestCase will use this configuration file.
Please note that any setting defined in phpunit.xml will override this configuration.
Update
Starting Laravel5.4, the createApplication function is no longer found in tests\TestCase. It has been moved to tests\CreatesApplication trait.
Copy your .env to .env.testing, then edit the .env.testing file and change the APP_ENV parameter to make it like this APP_ENV=testing this way you will be able to specify your settings int this new file
In case you don't want to create a new .env.testing file you have to specify your variables in the phpunit.xml in the php section with the values you need, something like this
<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="testing"/>
</php>
Just use the key values in the name section and the value of that key in the value section.
For this example I am specifying phpunit to use an sqlite database with the name of testing.
By the way in config/database.php I added this
'default' => env('DB_CONNECTION', 'mysql'), to use mysql by default unless I specify something diferent, as in this case.
Create a local database on your dev machine, e.g. 'local_test_db'
Create a new .env.testing file.
DB_DATABASE=local_test_db
DB_USERNAME=root
Make sure your phpunit.xml file has at least this one env var:
<php>
<env name="APP_ENV" value="testing"/>
</php>
Lastly your base testcase (TestCase.php) should run a migration to populate the db with tables:
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
}
public function tearDown()
{
Artisan::call('migrate:reset');
parent::tearDown();
}
This is 2019.
I had this issues for so long until I was able to figure it out.
And here is my assumption:
If you are also finding it difficult to make your PHPUnit.xml talk with your .env.testing file, then you are likely using PHPStorm!
If this is true, continue reading.
If not, nope...this won't help.
Ok...
Here you go:
Go to Settings of your PHPStorm or just simply press Ctrl + Alt + S.
Go to Languages And Frameworks >> PHP >> Test Frameworks
Under Test Runner tab, click Default configuration file and select (by clicking the folder icon) the path of your project's PHPUnit.xml file.
What this does is to make all your changes in the xml file take effect.
So, go ahead, create the .env.testing file, create your preferred DB config variables for test...and try running your tests again!
From this link
Method 1
Step 1: Create New Test Database Connection on Database/Config.php as below:
return [
...
'default' => env('DB_CONNECTION', 'db'),
'connections' => [
'sqlite_testing_db' => [
'driver' => 'sqlite',
'database' => storage_path().'/testing_database.sqlite',
'prefix' => '',
],
/**************** OR ******************/
'testing_db' => [
'driver' => 'mysql',
'host' => env('TEST_DB_HOST', 'localhost'),
'database' => env('TEST_DB_DATABASE', 'forge'),
'username' => env('TEST_DB_USERNAME', 'forge'),
'password' => env('TEST_DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
/** Production or database DB **/
'db' => [
'driver' => 'mysql',
'host' => env('TEST_DB_HOST', 'localhost'),
'database' => env('TEST_DB_DATABASE', 'forge'),
'username' => env('TEST_DB_USERNAME', 'forge'),
'password' => env('TEST_DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],
];
Step 2: Specify the Database Credential on .env file
TEST_DB_HOST=localhost
TEST_DB_DATABASE=laravel
TEST_DB_USERNAME=root
TEST_DB_PASSWORD=rootwdp
Step 3: Specify test db conection to be used on phpunit.xml.
<env name="DB_CONNECTION" value="testing_db"/>
OR Below If you prefer sqlite
<env name="DB_CONNECTION" value="sqlite_testing_db"/>
Step 4: Migrate database to this new testing database - if you choose to use Database Transaction to Rollback insertion on the table.
php artisan migrate --database=testing_db
//If using sqlite
touch storage/testing_database.sqlite
php artisan migrate --database=sqlite_testing
Step 5: Now, the Unit test with Database Transaction looks like below:
<?php
use App\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UserTest extends TestCase
{
use DatabaseTransactions;
/** #test */
function it_test_user_can_be_saved()
{
factory(User::class, 2)->create();
$users = User::all();
$this->assertEquals(2, $users->count());
}
}
//Run Php Unit
-> vendor/bin/phpunit --color tests/acceptance/model/UserTest.php
Note: If you prefer not to use Database Transaction, you can use setup and teardown method on TestCase.php class to migrate and rollback the database as below:
<?php
use Illuminate\Support\Facades\Artisan;
class TestCase extends Illuminate\Foundation\Testing\TestCase
{
...
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
}
public function tearDown()
{
Artisan::call('migrate:reset');
parent::tearDown();
}
}
In your app.php change the Dotenv section
$envFile = 'testing' === env('APP_ENV') ? '.env.testing' : null;
try {
(new Dotenv\Dotenv(__DIR__ . '/../', $envFile))->load();
} catch (Dotenv\Exception\InvalidPathException $e) {
//
}
This will work hence PHPUnit changes the env before loading your app..so if running tests you will have the env already at testing
Been struggling with this for a few months now and just came across this Github issue today.
From the solutions proposed there, here's what you should do in your CreatesApplication.php file (to delete the cached config in order to have Laravel load the test environment):
/**
* Creates the application.
*
* #return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$this->clearCache(); // NEW LINE -- Testing doesn't work properly with cached stuff.
return $app;
}
/**
* Clears Laravel Cache.
*/
protected function clearCache()
{
$commands = ['clear-compiled', 'cache:clear', 'view:clear', 'config:clear', 'route:clear'];
foreach ($commands as $command) {
\Illuminate\Support\Facades\Artisan::call($command);
}
}
If you're still experiencing this issue after the above modification, you can go further by rebuilding the entire application as follows:
public function createApplication()
{
$createApp = function() {
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
};
$app = $createApp();
if ($app->environment() !== 'testing') {
$this->clearCache();
$app = $createApp();
}
return $app;
}
This is working just fine for me.
Updated
For Laravel 5.8 users, you may create a .env.testing file in the root of your project.
Use a different db, like my_app_testing.
So, it will be, in .env
DB_DATABASE=clinical_managment
and in .env.testing
DB_DATABASE=clinical_managment_testing
Then, make config clear.
php artisan config:clear
Re-run the test. In my setup, it works.
I did all the steps in #Sambhu Singh answer as well as followed his link.
But didn't work for me in L5.5
When migrating, adding/setting APP_ENV to 'testing' in front of the artisan command worked for me:
APP_ENV=testing php artisan migrate --database=sqlite_testing
I can't think of a way other than temporarily renaming .env.testing to .env before the unit tests start.
You could put some logic in bootstrap/autoload.php as this is what phpunit uses as it's bootstrap file before loading the application.
I'm using PostgreSQL and want to try Laravel.
First - my up() function:
public function up()
{
Schema::create('entries.entries', function($t) {
$t->increments('id');
$t->string('username', 50);
$t->string('email', 100);
$t->text('comment');
$t->timestamps();
});
}
And i have two questions:
1) I haven't shema entries in my database, so, how can i change my up function to create it too? I dont want to do it manually.
2) I got an error when executed migration:
sudo php artisan migrate
[Illuminate\Database\QueryException]
SQLSTATE[3F000]: Invalid schema name: 7 ERROR: no schema has been selected
to create in (SQL: create table "emigrations" ("migration" varchar(255) not null,
"batch" integer not null))
How can i fix it?
Well i know that this question has more than 2 year's... but for the future people that reaches this. Laravel does not recognize the default 'public' schema of postgres by default and that's why you get the:
[Illuminate\Database\QueryException]
SQLSTATE[3F000]: Invalid schema name: 7 ERROR: no schema has been selected
to create in (SQL: create table "emigrations" ("migration" varchar(255) not null,
"batch" integer not null))
Thus to solve this error you just rename your Schema in postgres to anything besides public and, in your laravel project in the file config/database.php change the name of your pgsql conection schema to the one you want to use in your DB.
This should solve it.
It did for me anyways...
1) I don't think there is such functionality in Laravel but you can use an external package like https://github.com/pacuna/Laravel-PGSchema
2) Did you remove the default schema in your app/config/database.php file?
'pgsql' => array(
'driver' => 'pgsql',
'host' => 'localhost',
'database' => 'forge',
'username' => 'forge',
'password' => '',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
),
Laravel and PostgreSQL DB Connection, Authentication, Migration:
Prerequisites*
PHP 7.2+
Composer (a dependency manager for PHP)
PostgreSQL 9.5+
Installing Laravel
Create a new project with auth scaffolding.
laravel new blog --auth
Now Change default db connection in blog\config\database.php
'default' => env('DB_CONNECTION', 'mysql'),
change to
'default' => env('DB_CONNECTION', 'pgsql'),
Next, we’ll need to configure our database credentials in Laravel by updating the .env file:
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=projectmanager
DB_USERNAME=postgres
DB_PASSWORD=1234
Finally, we have to enable the PostgreSQL driver in our php.ini file. Let’s go into our XAMPP/WAMP directory and modify this file by commenting out these two drivers:
- extension=pdo_pgsql
- extension=pgsql
Note: check php.ini file location is bin\php\php7.3.5. Also, check the php.ini file is PHP or apache file.
Then Run migration for creating the table.
php artisan migrate
Now you get your final output.
Thanks and best of luck.