Setting up Laravel Dusk with testing database - php

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

Related

Getting "MongoDB\Driver\Manager Not Found" when using view composers in Laravel

I am using Laravel 7 and Jensseger's MongoDB package.
Everything works fine, except for this:
When I issue php artisan view:clear, I get MongoDB\Driver\Manager Not Found error.
I already have installed the latest version of MongoDB module for php 7.4 and everything else works fine. Meanwhile, I am using a dockerized environment. So, I am totally clueless why this is happening when I try to clear cached views.
This is my ViewServiceProvider file:
class ViewServiceProvider extends ServiceProvider
{
public function register()
{
}
public function boot(HeaderRepository $repository)
{
$header = $repository->getHeader();
View::composer('errors::*', function($view) use($header){
$view->with([
'header' => $header,
]);
});
}
}
My purpose is to create a customized 404 error page, but the header has to be fetched from MongoDB and shared between customized error pages. That's why I'm using view composers. Any other solution is welcome as well.
I suppose, you enter command php artisan view:clear from a local console.
You have choice:
Install mongo drive to your local interpreter
Use artisan from docker container eg docker exec {PHP_CONTAINER} php artisan view:clear

Laravel Ratchet not reading config file after vendor:publish

Im trying to make Socket server base on laravel-ratchet.
ive done installation steps from git :
1."composer require askedio/laravel-ratchet"
2. "$ php artisan vendor:publish --provider="Askedio\LaravelRatchet\Providers\LaravelRatchetServiceProvider"
then ive entered class address in app.php like this :
Askedio\LaravelRatchet\Providers\LaravelRatchetServiceProvider::class,
now from this help ive created my simple socket IoServer class in app folder (App/MyRatchetSocketServer):
<?php
namespace App;
use Ratchet\ConnectionInterface;
use Askedio\LaravelRatchet\RatchetServer;
class MyRatchetSocketServer extends RatchetServer
{
public function onMessage(ConnectionInterface $conn, $input)
{
parent::onMessage($conn, $input);
if (!$this->throttled) {
$this->send($conn, 'Hello you.');
$this->sendAll('Hello everyone.');
$this->send($conn, 'Wait, I don\'t know you! Bye bye!');
$this->abort($conn);
}
}
}
then ive changed my /config/ratchet.php to this :
<?php
return [
'class' => \App\MyRatchetSocketServer::class,
'host' => '127.0.0.1',
'port' => '8989',
'connectionLimit' => false,
'throttle' => [
'onOpen' => '5:1',
'onMessage' => '20:1',
],
'abortOnMessageThrottle' => false,
'blackList' => [],
'zmq' => [
'host' => '127.0.0.1',
'port' => 5555,
'method' => \ZMQ::SOCKET_PULL,
],
];
and in final part im going to start my service with serve :
php artisan ratchet:serve
and it gives this error :
Starting WampServer server on: 0.0.0.0:8080
In RatchetServerCommand.php line 204:
Askedio\LaravelRatchet\Examples\Pusher must be an instance of Askedio\LaravelRatchet\RatchetWampServer to create a Wamp server
my guess is that , serve command is bypassing the ratchet config file.
also if i try this :
php artisan ratchet:serve --driver=IoServer --class="App\MyRachetSocketServer::class"
the error changed to this :
Starting IoServer server on: 0.0.0.0:8080
In RatchetServerCommand.php line 155:
Class 'App\MyRachetSocketServer::class' not found
the file path is correct (bottom pic). dont know what to test next ?!
Im using Xamp , Vscode , Laravel 5.5.
I had the same problem long time ago
after a few try , find out that it was a cache problem.
try this Package for clearing cache with this command :
php artisan clear:data
or u can use these generic command in order:
php artisan cache:clear
php artisan view:clear
php artisan route:clear
php artisan clear-compiled
php artisan config:cache
and finaly , try your server command as follows :
php artisan ratchet:serve --driver=IoServer
hope that helps :)

Dusk SQLite database not found

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.

why is laravel 5 artisan migrate not creating sqlite database?

I'm trying to use artisan migrate to create tables in sqlite.
I have the following in database.php
'sqlite' => [
'driver' => 'sqlite',
'database' => database_path('database.sqlite'),
'prefix' => '',
],
and this is my migrate class up function
Schema::connection('sqlite')->create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
Note:- I have set DB_CONNECTION to be sqlite via the environment variable.
On the command line I get nothing to migrate, and no db is created (also no table).
Any ideas how I can get artisan migrate to create an sqlite db in laravel 5?
I have no problem creating mysql tables via artisan.
Thanks
its because you didnt create the db. use touch command like this to create new sqlite database.
touch database/database.sqlite
then configure the environment variable like this
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
In order to answer this part of the OP's question:
"Any ideas how I can get artisan migrate to create an sqlite db in laravel 5?"
In some cases where deployment and migrations need to be scripted I use a Service Provider to check the Sqlite DB exists and if not create it.
Here are the steps:
1) Create a Provider and save it to app/Providers/SqliteServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class SqliteServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
$databaseFile = config('database.connections.sqlite.database');
if (!file_exists($databaseFile)) {
info('Make Sqlite File "' . $databaseFile . '"');
file_put_contents($databaseFile, '');
}
}
}
2) Register the provider in config/app.php. For example in a fresh L5.8 install the SqliteServiceProvider would be placed under the RouteServiceProvider like so:
'providers' => [
//...
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\SqliteServiceProvider::class, // <--- HERE
],
3) Add/replace the following to the 'connections' element of config/database.php
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_SQLITE_FILEPATH', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
4) In my .env file I add this:
DB_SQLITE_FILEPATH=/full/path/to/mysqlitefilename.sqlite
...but if you prefer you can skip this step and the DB will be created as database/database.sqlite.
5) Run your migration as usual and the sqlite file should be created then populated.
Ok I got it. artisan migrate seems to ignore the env DB_CONNECTION and the database.php default (which reads the env anyway). Instead it like the .env file DB_CONNECTION, with this set to sqlite it works (plus, as mentioned above you do need to manually create the database file, which is a pain for making dbs on the fly.
Also means you can't really change artisan migrate database types (ie: sqlite and mysql) on the fly as you need to change the .env variable each time you change the target db type.
go laravel.
That's right, you need to create empty database.sqlite file.
You should also use artisan --env parameter if you want artisan to load the concrete .env file. For example, artisan --env=testing migrate will force artisan to load .env.testing file.

How to specify a different .env file for phpunit in Laravel 5?

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.

Categories