You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行Laravel 9测试时数据库被删除的原因咨询

为什么Laravel测试会删除我的数据库?

我正在使用Laravel 9测试工具。先删除数据库、重新创建后通过SQL语句导入数据,浏览器登录用户一切正常。但执行命令php artisan test --filter HomeControllerTest后,整个数据库被删除了,这是为什么?

测试代码如下:

<?php
namespace Tests\Feature;

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

class HomeControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_home_view_requires_authentication()
    {
        
        // Log in as the created user and try to access the home page
        $response = $this->postJson('/login', [
            'email' => 'test@example.com',
            'password' => 'password',
        ]);

        $response->assertStatus(302);
        $response->assertRedirect(route('home'));

        $response = $this->get(route('home'));
        $response->assertOk();
        $response->assertViewIs('home');
        $response->assertViewHasAll(['corretora', 'propostas']);
    }


    /**
     * Test if home page can be accessed by a guest user.
     *
     * @return void
     */
    public function test_home_view_requires_guest()
    {
        $response = $this->get(route('home'));

        $response->assertStatus(302);
        $response->assertRedirect(route('login'));
    }
}

原因分析

核心问题出在你使用的RefreshDatabase特性上:

  • 这个特性是Laravel为保证测试环境干净设计的,它会在每个测试执行前后重置数据库:测试开始前自动运行所有迁移,将数据库恢复到迁移定义的初始空状态;测试结束后也会清理数据。
  • 如果你的测试环境和开发环境共用同一个数据库(.env里的数据库配置和测试时一致),测试运行时就会直接清空你手动导入的开发数据,替换成迁移后的空结构。

解决办法

  1. 配置独立的测试数据库
    在项目根目录创建.env.testing文件,设置单独的数据库连接信息,比如:

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_test
    DB_USERNAME=root
    DB_PASSWORD=
    

    这样测试只会操作这个独立的测试库,完全不会影响开发数据库的数据。

  2. 替换RefreshDatabase为DatabaseTransactions
    如果你希望测试后保留数据库数据,可以把测试类里的use RefreshDatabase;改成use Illuminate\Foundation\Testing\DatabaseTransactions;。这个特性会在测试开始时开启事务,测试结束后自动回滚,不会修改数据库的持久化数据,但只支持支持事务的数据库(如MySQL、PostgreSQL)。

  3. 用测试工厂/种子生成测试数据
    不要手动往开发库导入测试用数据,而是通过Laravel的测试工厂或者测试种子在测试代码里生成需要的初始数据,比如创建测试用户:

    $user = User::factory()->create([
        'email' => 'test@example.com',
        'password' => bcrypt('password'),
    ]);
    

    这样测试数据完全独立,不会和开发数据混淆。

内容的提问来源于stack exchange,提问作者Marcello Pato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:15:24