Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Why Dusk Page Test uses DatabaseMigrations instead of DatabaseTransactions? #110

Closed
gabbydgab opened this issue Feb 9, 2017 · 16 comments

Comments

@gabbydgab
Copy link

gabbydgab commented Feb 9, 2017

Similar to Feature/Unit test, I don't want the database to be populated with test data.

It seem it's more appropriate using DatabaseTransactions instead of DatabaseMigration in running dusk test.

See: https://laravel.com/docs/5.4/dusk#creating-browsers

Can someone enlighten me, why? Thanks in advance.

cc @sileence

@georaldc
Copy link

georaldc commented Feb 9, 2017

Transactions started in your test files won't work because Dusk operates under a separate process. Would be nice though if this weren't the case

@sileence
Copy link
Contributor

sileence commented Feb 9, 2017

Yes, it is not possible to use transactions with Dusk for that reason, a possible solution could be to trigger a command to truncate all the tables after the test finishes, it could be faster than re-running the migrations each time.

@vinayakkulkarni
Copy link

This works for me:

<?php

namespace Tests\Browser;

use App\User;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends DuskTestCase
{
    use DatabaseTransactions;

    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $user = factory(User::class)->create([
            'email' => 'demo@example.com',
        ]);

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                    ->type('login', $user->email)
                    ->type('password', '123456')
                    ->press('Login')
                    ->assertPathIs('/');
        });
    }
}

@DivineOmega
Copy link

DivineOmega commented Feb 16, 2017

@vinayakkulkarni I'm not quite sure how that could be working. The creation of the user record and the use of it in the browser are happened in two different processes. This means the created user is part of a database transaction which is not committed and thus not accessible by the browser process.

@vinayakkulkarni
Copy link

well, i have 2 .env files

  1. .env
  2. .env.dusk.local

I got 2 databases,

  1. prodDB
  2. testDB

.env.dusk.local file has testDB where all tests are done
.env has prodDB

both DB's are properly seeded

@DivineOmega
Copy link

@vinayakkulkarni Is the demo@example.com user one that is seeded?

@vinayakkulkarni
Copy link

@DivineOmega : yes.

@georaldc
Copy link

@vinayakkulkarni if your test db was pre seeded before running tests, then yes your tests would pass. That has nothing to do with migrations though and your user create code above still would have had no effect inside your browser tests

@DivineOmega
Copy link

@georaldc Precisely what I was going to say. Thanks.

@deleugpn
Copy link
Contributor

deleugpn commented Mar 2, 2017

You can lose the model factory and the use DatabaseTransaction, then. They're useless.

@deleugpn deleugpn mentioned this issue Apr 21, 2017
@aboustayyef
Copy link

aboustayyef commented Jun 10, 2017

Here's how I do it:

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

public function setUp()
    {
        Parent::setUp();
        $this->user = factory(\App\User::class)->make(['password' => bcrypt('pass123')]) ;
        $this->user->save();
    }

    /** @test */
    public function when_users_login_successfully_they_are_redirected_to_root()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
            ->type('email', $this->user->email)
            ->type('password', 'pass123')
            ->press('Login')
            ->assertPathIs('/');
        });

        // after test is done. Delete test user
        $this->user->delete();
    }

@dlucian
Copy link

dlucian commented Aug 10, 2017

@aboustayyef - why not delete the user in a tearDown() method?

@AhmadWaleed
Copy link

That's how i do it.

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

    /** @test */
    public function when_users_login_successfully_they_are_redirected_to_root()
    {

        try {
              $user = factory(\App\User::class)->create() ;

               $this->browse(function (Browser $browser) {
                   $browser->visit('/login')
                   ->type('email', $this->user->email)
                   ->type('password', 'pass123')
                   ->press('Login')
                   ->assertPathIs('/');
              });

      } finally {
            $user->delete(); // or you could for delete it to make sure record deleted
     }

    }

@kerimkuscu
Copy link

kerimkuscu commented Apr 25, 2019

That's how i do it.

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

    /** @test */
    public function when_users_login_successfully_they_are_redirected_to_root()
    {

        try {
              $user = factory(\App\User::class)->create() ;

               $this->browse(function (Browser $browser) {
                   $browser->visit('/login')
                   ->type('email', $this->user->email)
                   ->type('password', 'pass123')
                   ->press('Login')
                   ->assertPathIs('/');
              });

      } finally {
            $user->delete(); // or you could for delete it to make sure record deleted
     }

    }

But in this way, it says undefined variable for $user.

`<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

/** @test */
public
function when_users_login_successfully_they_are_redirected_to_root()
{
        $user = factory(\App\User::class)->create();

        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
                ->type('email', $this->user->email)
                ->type('password', 'pass123')
                ->press('Login')
                ->assertPathIs('/');

        $user->delete();

        });
}`

Data generated by this path is deleted after use.

@AhmadWaleed
Copy link

AhmadWaleed commented Apr 25, 2019

That's how i do it.

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

    /** @test */
    public function when_users_login_successfully_they_are_redirected_to_root()
    {

        try {
              $user = factory(\App\User::class)->create() ;

               $this->browse(function (Browser $browser) {
                   $browser->visit('/login')
                   ->type('email', $this->user->email)
                   ->type('password', 'pass123')
                   ->press('Login')
                   ->assertPathIs('/');
              });

      } finally {
            $user->delete(); // or you could for delete it to make sure record deleted
     }

    }

But in this way, it says undefined variable for $user.

`<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

/** @test */
public
function when_users_login_successfully_they_are_redirected_to_root()
{
        $user = factory(\App\User::class)->create();

        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
                ->type('email', $this->user->email)
                ->type('password', 'pass123')
                ->press('Login')
                ->assertPathIs('/');

        $user->delete();

        });
}`

Data generated by this path is deleted after use.

$this->browse(function (Browser $browser) use ($user) {
            $browser->visit('/login')
                ->type('email', $this->user->email)
                ->type('password', 'pass123')
                ->press('Login')
                ->assertPathIs('/');

        $user->delete();

        });

try this you were not passing $user with function ($browser) use ($user) {

@kerimkuscu
Copy link

That's how i do it.

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

    /** @test */
    public function when_users_login_successfully_they_are_redirected_to_root()
    {

        try {
              $user = factory(\App\User::class)->create() ;

               $this->browse(function (Browser $browser) {
                   $browser->visit('/login')
                   ->type('email', $this->user->email)
                   ->type('password', 'pass123')
                   ->press('Login')
                   ->assertPathIs('/');
              });

      } finally {
            $user->delete(); // or you could for delete it to make sure record deleted
     }

    }

But in this way, it says undefined variable for $user.

`<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

/** @test */
public
function when_users_login_successfully_they_are_redirected_to_root()
{
        $user = factory(\App\User::class)->create();

        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
                ->type('email', $this->user->email)
                ->type('password', 'pass123')
                ->press('Login')
                ->assertPathIs('/');

        $user->delete();

        });
}`

Data generated by this path is deleted after use.

$this->browse(function (Browser $browser) use ($user) {
            $browser->visit('/login')
                ->type('email', $this->user->email)
                ->type('password', 'pass123')
                ->press('Login')
                ->assertPathIs('/');

        $user->delete();

        });

try this you were not passing $user with function ($browser) use ($user) {

f28fdef6-f041-4404-bbae-8e9963b15cfe

you don't need to use it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests