I would like to know how tet up Laravel 5.4 with Dusk using phpunit.xml, .env.dusk.local, and an sqlite in-memory database as what I have so far doesn't work. It _does_ work with a MySQL database though.
I can run the tests, but I get an error: "No such table: users"
I have added a .env.dusk.local which contains
APP_ENV=local
APP_KEY=RANDOM_STRING_HERE
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://laravel54.dev
DB_CONNECTION=sqlite
DB_DATABASE=':memory:' // I've also tried just :memory: and also adding these details to the config/database.php file but to no avail
This is the test I am running (directly from the docs)
<?php
namespace Tests\Browser;
use App\User;
use Tests\DuskTestCase;
use Laravel\Dusk\Chrome;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class LoginTest extends DuskTestCase
{
use DatabaseMigrations;
public function test_login_page()
{
$user = factory(User::class)->create();
$this->browse(function ($browser) use ($user) {
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'secret')
->press('Sign in')
->assertPathIs('/home');
});
}
}
Same here!
Taylor replied "I don't think that's gonna work. Dusk runs in a separate process", but I don't see how this makes a difference.
Solved by editing tests/CreatesApplication.php:
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
$app['config']->set('database.default','sqlite');
$app['config']->set('database.connections.sqlite.database', ':memory:');
return $app;
}
@MarceauKa this does not work for me, the sample LoginTest fails with a message saying the credentials do not match. Does this mean that the database was migrated?
You won't be able to use an in memory db because, as Taylor has pointed out, the tests and the web server are running under separate processes. You could use a common mysql db connection or a single sqlite file, and then do a migrate/refresh option (although this does rely on all your migrations supporting down migration steps).
The approach I have taken (which is adapted from an approach I was using pre-dusk) is to create an empty file for an sqlite db that both my web server and my tests point to. The tests create this file as part of the setup process, and migrate it, so you have a clean db at the start of each test, Much like you get with an in memory sqlite db.
If you want to see an example, take a look at my medium post that has the Trait I wrote for this:
https://medium.com/@splatEric/working-with-laravel-dusk-54d67cc0241b#.xqalwcjxi
Thanks, I'll check it out.
Is this the same for the DatabaseTransactions trait?
If I use it I run into errors with the credentials not being correct when logging in. If I disable it the test works, but then fails the next time because the user is still in the database.
Do we need to write Dusk tests to clean up after themselves? This is on a MySQL database that's used for local development.
Basically yes.
Use the approach I've taken in my medium post and it will take care of the
same issue.
On 31 January 2017 at 10:11, Adam Greer notifications@github.com wrote:
Is this the same for the DatabaseTransactions trait?
If I use it I run into errors with the credentials not being correct when
logging in. If I disable it the test works, but then fails the next time
because the user is still in the database.Do we need to write Dusk tests to clean up after themselves?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/laravel/dusk/issues/73#issuecomment-276324025, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACVP6K0Sd42iEC6cpSOugb-kNBOA6Rczks5rXwi3gaJpZM4LwwYg
.
@MarceauKa that is what worked for me. I just used $app['config']->set('database.default','testing');. The thing I noticed is that the ChromeDriver was using the proper sqlite file, but the actual tests were defaulting to mysql. This forced the Dusk tests to use the proper db.
On another note, though, I use https://github.com/SRLabs/laravel-testing-utilities for updating the testing database. It really simplifies the testing setup.
A bit more on this, since I just spent 40 minutes wrestling with getting my tests working again. I'm not sure entirely what changed, but I was again having an issue with the consistency of the db connection used by the testing process versus that of the web server process.
There has been an update to dusk to 1.0.4 that forces a reload of the environment in the testing process after the environment files are moved around, however the reload calls Dotenv()->overload(), which means that if any environment variables are not set in your dusk env file, they will default to whatever you had in your core .env file. This was causing a problem with the database filename I was using for sqlite.
TLDR; I set up an sqlite_testing connection in my database config, and pointed at that from the dusk .env file:
'sqlite_testing' => [
'driver' => 'sqlite',
'database' => database_path('testing.sqlite'),
'prefix' => '',
],
This seems to have resolved my connection consistency issues.
@splatEric Yes, there was issue that Dusk was using the wrong file so it was not working in correct way. I've fixed it to reload environment after changing Dusk env into normal env so it's possible it's working fine now
@splatEric Thank you. https://github.com/laravel/dusk/issues/73#issuecomment-276618137 was super helpful. I looked at my database config array and saw that 'sqlite' was already set up that way, so all I needed to do was delete superfluous lines in my .env files.
I think the issue is setting the environment to local, because then the server uses the values in .env which also has the environment set to local. When I created an .env.dusk.testing file with the following values in it, everything worked fine. No need for a new php artisan serve.
APP_ENV=testing
...
DB_CONNECTION=sqlite
Putting it here if someone has same problem and gets here using search engine.
Dusk accesses different database because you are starting server in another terminal for example using ./artisan serve. And when in Dusk you do $this->browse it sends request to your started server which in turn queries the database that it is configured to query (i.e. your local database). And later in your tests if you for example do $this->assertDatabaseHas Dusk this time uses the database it is configured to query (i.e. your test database). To solve this I use a shell script to run my tests. To use it first you need to put your Dusk config into file called .env.dusk. Remember to set listen port to something different than default, for example set it to 8001 (APP_URL=http://localhost:8001). And then create a file called (I do it on Linux) run_tests in the same directory as your Laravel app with following contents and make it runnable:
#!/bin/bash
nohup ./artisan serve --port=8001 --env=dusk > art_8001.hup &
./vendor/bin/phpunit
./artisan dusk --env=dusk
kill $(lsof -t -i:8001)
rm art_8001.hup
Now you can run it from terminal using ./run_tests. What it does is run artisan on port 8001 with an environment file .env.dusk so that it picks up configuration that you did for Dusk. After this it starts to run your phpunit and Dusk tests so that all queries go to same database. Hope this helps to someone who faces the same problem.
Most helpful comment
Solved by editing
tests/CreatesApplication.php: