简体   繁体   English

如何在 Laravel 黄昏测试中共享用户数据

[英]How to share user data in laravel dusk tests

I'm very new to Laravel Dusk (like less than 24 hours) and I'm experimenting with creating some tests but I can't wrap my head around getting past the initial test.我对Laravel Dusk非常陌生(比如不到 24 小时),我正在尝试创建一些测试,但我无法绕过最初的测试。

So I have UserCanRegisterTest.php and UserCanSeeDashboardTest.php , In UserCanRegisterTest.php I register a user, how can I access that user info in UserCanSeeDashboardTest.php without having to recreate another user?所以我有UserCanRegisterTest.phpUserCanSeeDashboardTest.php ,在UserCanRegisterTest.php我注册了一个用户,如何在UserCanSeeDashboardTest.php访问该用户信息而不必重新创建另一个用户? I have tried researching but I've fallen down a rabbit hole, I've looked at memory, cookies, DatabaseTransactions but nothing seems to make sense or show an example.我尝试过研究,但我掉进了一个兔子洞,我查看了内存、cookie、DatabaseTransactions,但似乎没有任何意义或显示示例。

Is it possible for me to use the $faker->safeEmail and $password from UserCanRegisterTest.php in UserCanSeeDashboardTest.php and all other tests I make?是否有可能对我来说,使用$faker->safeEmail$passwordUserCanRegisterTest.phpUserCanSeeDashboardTest.php和所有其他测试中,我做什么呢?

UserCanRegisterTest.php : UserCanRegisterTest.php :

<?php

namespace Tests\Browser;

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

class UserCanRegisterTest extends DuskTestCase
{
    use DatabaseMigrations;

    /*public function setUp()
    {
        parent::setUp();
        $this->artisan('db:seed');
    }*/

    /** @test */
    public function user_passes_registration_form()
    {
        $faker = \Faker\Factory::create();

        /*$roleSeeder = new RoleTableSeeder();
        $roleSeeder->run();

        $permissionSeeder = new PermissionTableSeeder();
        $permissionSeeder->run();*/

        $this->browse(function($browser) use ($faker) {
            $password = $faker->password(9);

            $browser->visit('/register')
                //->assertSee('Welcome Back!')
                ->type('company_name', $faker->company)
                ->type('name', $faker->name)
                ->type('email', $faker->safeEmail)
                ->type('password', $password)
                ->type('password_confirmation', $password)
                ->press('REGISTER')
                ->assertPathIs('/register');
        });
    }
}

Here is UserCanSeeDashboardTest.php (note how I'd like to use $faker->safeEmail and $password from the above test so I don't need to create new user every time).这是 UserCanSeeDashboardTest.php (注意我想如何使用上面测试中的 $faker->safeEmail 和 $password 所以我不需要每次都创建新用户)。

<?php

namespace Tests\Browser;

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

class UserCanSeeDashboardTest extends DuskTestCase
{
    use DatabaseMigrations;

    /*public function setUp()
    {
        parent::setUp();
        //$this->artisan('db:seed');
    }*/

    /** @test */
    public function test_I_can_login_successfully()
    {
        $this->browse(function ($browser) {
            //$user->roles()->attach(1); //Attach user admin role

            $browser->visit('/login')
                    ->type('email', $faker->safeEmail)
                    ->type('password', $password)
                    ->press('SIGN IN')
                    ->assertSee('Dashboard');
        });
    }
}

Ideally, I have a test that registers a user, then I have other tests that use that registered user's data to log in and test other parts of my app.理想情况下,我有一个注册用户的测试,然后我有其他测试使用该注册用户的数据登录并测试我的应用程序的其他部分。

PHPUnit doesn't have great support for tests that depend on each other. PHPUnit 对相互依赖的测试没有很好的支持。 Tests in PHPUnit should mostly be considered independent. PHPUnit 中的测试主要应该被认为是独立的。 The framework does provide the @depends annotation that you might have been able to use for you tests that depend on the registration method, but it only works for tests that are in the same class .该框架确实提供了@depends注释,您可能已经能够将其用于依赖于注册方法的测试,但它仅适用于同一中的测试。

Also, you don't need to worry about creating multiple users because you're using the DatabaseMigrations trait that refreshes your test database for you after every test.此外,您无需担心创建多个用户,因为您正在使用DatabaseMigrations特性,它会在每次测试后为您刷新测试数据库。

The way I see it, you have two options.在我看来,你有两个选择。 Either you:要么你:

  1. Move your registration code (the part starting from $browser->visit('/register') ) to a new method and then call that method in both your user_passes_registration_form test and in your other tests where you want to have a registered user, or将您的注册码(从$browser->visit('/register')开始的部分)移动到一个新方法,然后在您的user_passes_registration_form测试和您想要注册用户的其他测试中调用该方法,或者
  2. Write a new method that you can call from your other tests that registers a user directly in your database (eg using User::create ).编写一个新方法,您可以从直接在数据库中注册用户的其他测试中调用该方法(例如,使用User::create )。

The benefit of the second option is that you'll have less HTTP calls which will result in a faster test run and only your registration test would fail (instead of all your tests) when your registration endpoint is broken.第二个选项的好处是您将有更少的 HTTP 调用,这将导致更快的测试运行,并且当您的注册端点损坏时,只有您的注册测试会失败(而不是所有测试)。

So what I'd suggest is that you keep your registration test as is and use either a trait or inheritance to add a few methods that you can reuse to register or login a test user from other test methods.所以我建议您保持注册测试不变,并使用特征或继承添加一些方法,您可以重用这些方法从其他测试方法注册或登录测试用户。

You could create a class MyDuskTestCase that inherits from DuskTestCase and that contains a method to register a test user:您可以创建一个MyDuskTestCase类,它继承自DuskTestCase并包含一个注册测试用户的方法:

<?php

namespace Tests;

use Tests\DuskTestCase;
use App\User;
use Hash;

abstract class MyDuskTestCase extends DuskTestCase
{
    private $email = 'test@example.com';
    private $password = 'password';

    public function setup(): void
    {
        parent::setUp();

        // If you want to run registerTestUser for every test:
        // registerTestUser();
    }

    public function registerTestUser()
    {
        User::create([
            'email' => $this->email,
            'name' => 'My name',
            'password' => Hash::make($this->password)
        ]);

        // assign a role, etc.
    }

    public function getTestUser()
    {
        return User::where('email', $this->email)->first();
    }
}

Then you can either run the registerTestUser method in the setup method to create the test user for every test, or you can call the method from only the tests where you'll need the user.然后,您可以在setup方法中运行registerTestUser方法来为每个测试创建测试用户,也可以仅从需要用户的测试中调用该方法。 For example:例如:

<?php

namespace Tests\Browser;

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

class UserCanRegisterTest extends MyDuskTestCase
{
    use DatabaseMigrations;
    public function test_I_can_login_successfully()
    {
        $this->registerTestUser();

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                    ->type('email', $this->email)
                    ->type('password', $this->password)
                    ->press('SIGN IN')
                    ->assertSee('Dashboard');
        });
    }
}

For logins, you can either add another method to your base test class to log the test user in, or you could use the loginAs method that Dusk provides:对于登录,您可以向基测试类添加另一个方法来登录测试用户,或者您可以使用 Dusk 提供的loginAs方法:

$user = this->getTestUser();
$this->browse(function ($browser) {
    $browser->loginAs($user)
          ->visit('/home');
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM