Laravel测试后重置数据库

aamkag61  于 2023-04-13  发布在  其他
关注(0)|答案(8)|浏览(165)

我刚刚开始使用Laravel Dusk来测试我的项目,需要一些指导。在我运行所有可用的测试之后,我希望能够在运行测试之前重置我的数据库。(如果在运行测试之前数据库中有任何条目,我仍然希望在运行测试之后看到它们。但是,在测试期间创建的任何条目,我不想在测试运行结束后看到它们。)有什么关于我如何实现这一点的建议吗?谢谢!
更新:

<?php

namespace Tests\Browser;

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

class UserRegisterTest extends DuskTestCase
{
    use DatabaseTransactions;
    /**
     * A test for user registration.
     * @group register
     * @return void
     */

    public function testRegisterUser()
    {
        //Register with all info filled out correctly
        $this->browse(function ($browser){
            $browser->visit('/register')
                    ->type('firstName', 'JenLogin')
                    ->type('lastName', 'Zhou')
                    ->type('email', 'testLogin@gmail.com')
                    ->type('bio', 'Hello, this user is for testing login purposes!')
                    ->type('location_zip', '11111')
                    ->type('password', '123456')
                    ->type('password_confirmation', '123456')
                    ->click('.btn-primary')
                    ->assertPathIs('/home')
                    ->click('.dropdown-toggle')
                    ->click('.dropdown-menu li:last-child');

        });

        $this->assertDatabaseHas('users', ['firstName' => 'JenLogin', 'lastName' => 'Zhou', 'email' => 'testLogin@gmail.com']);

    }

    /**
     * Register with duplicate user
     * @group register
     * @return void
     */
    public function testRegisterDuplicateUser(){

        $this->browse(function ($browser){
            $browser->visit('/register')
                ->type('firstName', 'JenLoginDup')
                ->type('lastName', 'Zhou')
                ->type('email', 'testLogin@gmail.com')
                ->type('bio', 'Hello, this user is for testing login purposes!')
                ->type('location_zip', '11111')
                ->type('password', '123456')
                ->type('password_confirmation', '123456')
                ->click('.btn-primary')
                ->assertPathIs('/register')
                ->assertSee('The email has already been taken.');
        });

        $this->assertDatabaseMissing('users', ['firstName' => 'JenLoginDup', 'lastName' => 'Zhou', 'email' => 'testLogin@gmail.com']);
    }

    /**
     * Register with incorrect password confirmation
     * @group register
     * @return void
     */
    public function testRegisterUserNoPassConfirm(){

        $this->browse(function ($browser){
            $browser->visit('/register')
                ->type('firstName', 'JenLoginPass')
                ->type('lastName', 'Zhou')
                ->type('email', 'testLoginPass@gmail.com')
                ->type('bio', 'Hello, this user is for testing login purposes!')
                ->type('location_zip', '11111')
                ->type('password', '123456')
                ->type('password_confirmation', '888888')
                ->click('.btn-primary')
                ->assertPathIs('/register')
                ->assertSee('The password confirmation does not match.');
        });

        $this->assertDatabaseMissing('users', ['firstName' => 'JenLoginPass', 'lastName' => 'Zhou', 'email' => 'testLoginPass@gmail.com']);
    }
}
svdrlsy4

svdrlsy41#

您正在寻找DatabaseTransactions trait。在您的测试类中像这样使用它,它将自动回滚在测试期间进行的所有数据库事务。

use Illuminate\Foundation\Testing\DatabaseTransactions;

class ExampleTest extends TestCase
{
    use DatabaseTransactions;

    // test methods here
}

这将跟踪测试期间进行的所有事务,并在完成时撤消它们。

注意:此trait仅适用于默认数据库连接

insrf1ej

insrf1ej2#

首先,当你运行测试时,你应该使用与你的实时(或开发)数据库完全不同的数据库。为此,你应该创建.env.dusk并在那里设置:

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=testing_database
DB_USERNAME=root
DB_PASSWORD=pass

仅用于测试的数据库。
第二件事是,对于Laravel Dusk,你不能只使用DatabaseTransactions。你应该使用DatabaseMigrations进行Dusk测试,否则你会得到意想不到的结果。

5ssjco0h

5ssjco0h3#

在live/dev数据库上运行带有数据的测试并将更改恢复回来,没有合理的工作流程,由测试完成。
因此,你的方法在这里失败了,相反,你应该:
1.为测试创建单独的测试架构/数据库
1.在运行测试之前,切换到testdb--这可以根据你在phpunit和.env. dusch中的配置以某种方式自动化,但这取决于你的本地设置。
1.然后,在测试中,您将在干净的数据库上从头开始创建(运行迁移、种子、工厂)
1.对此测试数据库运行测试
1.对于开发,切换回具有当前数据的基本数据库,这将不受测试的影响。
下一次你将运行你的测试,所有从零开始-清理数据库,这将在测试中完成:use CreatesApplication;use DatabaseMigrations;parent::setUp();
阅读更多关于这些方法…
附注:
1.通过这种方法,在CI环境中测试您的应用程序也将变得很容易。
1.永远不要写依赖于你的开发/实时数据库的测试。对于测试,所有需要的数据应该由种子或工厂提供!

d4so4syb

d4so4syb4#

您可以在测试类中使用RefreshDatabase特性。每次测试后,数据库将与测试前一样。事实上,它将删除所有表并再次迁移。如果您不想丢失数据,则可以使用一个单独的架构进行测试。

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

}
kuarbcqp

kuarbcqp5#

对于多个数据库,这帮助了我

class MyTest extends TestCase {
    // Reset the DB between tests
    use DatabaseTransactions;

    // Setting this allows both DB connections to be reset between tests
    protected $connectionsToTransact = ['mysql', 'myOtherConnection'];
}
vwoqyblh

vwoqyblh6#

我认为这是一个伟大的问题。我发现了一个工匠工具,可能是你正在寻找的。你可以用它来采取快照的数据库之前,你运行测试,然后再次使用它来加载该快照恢复您的数据库到以前的状态。我给了它一个运行(使用MYSQL),它工作得很好。希望这是你正在寻找的。这里是一个链接...
https://github.com/spatie/laravel-db-snapshots

hgqdbh6s

hgqdbh6s7#

phpunit.xml文件是你的解决方案,你可以在这个文件中设置一个.env变量,就像这样

<env name="DB_CONNECTION" value="testing_mysql"/>
    <env name="DB_DATABASE_TEST" value="test"/>

现在您可以在单独的数据库上运行测试。
另外,您可以在自动化测试之前每次运行一个.php文件,您只需要告诉它unittests

<phpunit 
     ...
     bootstrap="tests/autoload.php"
>

你可以把任何清洁剂或播种机在那里或类似的东西

echo 'Migration -begin-' . "\n";
echo shell_exec('php artisan migrate:fresh --seed');
echo 'Migration -end-' . "\n";
of1yzvn4

of1yzvn48#

我也遇到了类似的问题,我所要做的就是在phpunit.xml中取消注解这两行:

<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

相关问题