Php 为Laravel测试在数据库中播种和删除数据的正确方法?

Php 为Laravel测试在数据库中播种和删除数据的正确方法?,php,laravel,phpunit,Php,Laravel,Phpunit,我是Laravel测试的新手,我目前正在构建我的测试,以便他们使用我数据库中的某些数据来检查HTTP请求是否完成了相应的工作。 我试图弄清楚如何在运行测试之前将数据“种子”到数据库中,但在所有测试完成后也删除这些数据(成功或失败,无论如何都应该删除) 通过阅读互联网上的一些文章,我试图理解如何正确地做到这一点,但就是找不到适合我的解决方案 我知道在node.js中,Mocha测试有一个“beforeach”来在每次测试之前操作数据,PHP Laravel中是否有类似的选项?如果Laravel版本

我是Laravel测试的新手,我目前正在构建我的测试,以便他们使用我数据库中的某些数据来检查HTTP请求是否完成了相应的工作。 我试图弄清楚如何在运行测试之前将数据“种子”到数据库中,但在所有测试完成后也删除这些数据(成功或失败,无论如何都应该删除)

通过阅读互联网上的一些文章,我试图理解如何正确地做到这一点,但就是找不到适合我的解决方案


我知道在node.js中,Mocha测试有一个“beforeach”来在每次测试之前操作数据,PHP Laravel中是否有类似的选项?

如果Laravel版本大于5.5,您可以在测试中使用
刷新数据库
特性,该特性将在测试运行后重置数据库。你所要做的就是将它添加到测试的顶部,如下面所示

namespace Tests\Feature;

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

class YourModelNameTest extends TestCase
{
    use RefreshDatabase;


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

        // This will run all your migration
        Artisan::call('migrate');

        // This will seed your database
        Artisan::call('db:seed');

        // If you wan to seed a specific table
        Artisan::call('db:seed', ['--class' => 'TableNameSeeder ', '--database' => 'testing']);
    }

}
RefreshDatabase
特性具有定义
RefreshDatabase
,用于在每次测试前后迁移数据库。你可以在这里看到代码


虽然Yves answer应该可以工作(单独的数据库),但我发现了一套方法可以帮助实现我所需要的: “设置”和“拆卸”

“setUp”方法将在运行测试集(测试类)之前执行某些操作,“tearDown”将在执行所有这些测试之后执行某些操作

我在这里附上我的测试类,作为我如何使用它们的示例:

<?php

namespace Tests\Feature;

use App\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class UserTest extends TestCase
{
    private $token;

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

        $userData = [
            'email' => 'mytestemail@email.com',
            'password' => '123456'
        ];

        $response = json_decode($this->post('/register', $userData)->baseResponse->getContent());

        $this->token = $response->token;
    }
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testRegister()
    {
        $validData = [
            'email' => 'testrerere@email.com',
            'password' => '123456'
        ];

        $invalidEmail = [
            'email' => 'not_a_real_email',
            'password' => '123456'
        ];

        $invalidPassword = [
            'email' => 'test2@email.com',
            'password' => '12'
        ];

        $emptyData = [];

        $goodResponse = $this->post('/register', $validData);

        $goodResponse->assertStatus(201);
        $goodResponse->assertJsonStructure(['token']);

        User::where('email', 'testrerere@email.com')->delete();

        $invalidEmailResponse = $this->post('/register', $invalidEmail);
        $invalidEmailResponse->assertStatus(400);

        $invalidPasswordResponse = $this->post('/register', $invalidPassword);
        $invalidPasswordResponse->assertStatus(400);

        $emptyDataResponse = $this->post('/register', $emptyData);
        $emptyDataResponse->assertStatus(400);
    }

    public function testToken()
    {
        $validData = [
            'email' => 'mytestemail@email.com',
            'password' => '123456'
        ];

        $invalidData = [
            'email' => 'nonexistingemail@test.com',
            'password' => '123456'
        ];

        $validDataResponse = $this->post('/token', $validData);
        $validDataResponse->assertStatus(200);
        $validDataResponse->assertJsonStructure(['token']);

        $invalidDataResponse = $this->post('/token', $invalidData);
        $invalidDataResponse->assertStatus(400);
    }

    //get an account object based on a token
    public function testAccount()
    {
        $goodResponse = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->token,
        ])->json('GET', '/account');

        $goodResponse
            ->assertStatus(200)
            ->assertJsonStructure([
                'user',
            ]);

        //altering the token to get an invalid token error
        $badResponse = $this->withHeaders([
            'Authorization' => 'Bearer L' . $this->token,
        ])->json('GET', '/account');

//        print_r($badResponse->baseResponse->getContent());

        $badResponse->assertJson(['status' => 'Token is Invalid']);
    }

    public function tearDown()
    {
        User::where('email', 'mytestemail@email.com')->delete();
        User::where('email', 'testrerere@email.com')->delete();

        parent::tearDown();
    }
}

你能再详细一点吗?这实际上是如何服务于我在这个问题中的请求的目的的?这只是帮助在运行测试后恢复数据库的状态,我修改了答案,在测试之前添加了其他部分来种子数据库。我刚刚尝试了它,它删除了数据库中的所有数据,不好。你应该有两个数据库,一个用于测试,另一个用于生产,但不在真实数据上运行测试,请在测试数据库上使用假数据。指定测试数据库加载项
phpunit.xml
文件