Laravel:运行 phpunit 测试后删除的数据库表

Posted

技术标签:

【中文标题】Laravel:运行 phpunit 测试后删除的数据库表【英文标题】:Laravel: Database tables deleted after running phpunit test 【发布时间】:2019-02-08 19:05:51 【问题描述】:

每次我运行测试时,我的所有数据库表(迁移表除外)都会被删除,我必须再次运行迁移。例如,如果我有以下表格:

migrations
users
tableA
tableB

运行后:

phpunit --filter user_can_view_a_record ViewRecordTest 测试/功能/ViewRecordTest.php

我的表被删除了,最后我只得到了迁移表。

我使用 mysql 作为数据库,根据我设置的配置,测试正在内存中运行:

数据库.php

'connections' => [

        'sqlite' => [
            'driver' => 'sqlite',
            //'database' => env('DB_DATABASE', database_path('database.sqlite')),
            'database' => ':memory:',
            'prefix' => '',
        ],

        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
            'sticky' => true
        ],
]

phpunit.xml

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         bootstrap="vendor/autoload.php"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
    </testsuites>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <directory suffix=".php">./app</directory>
        </whitelist>
    </filter>
    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="DB_CONNECTION" value="sqlite" />
        <env name="DB_DATABASE" value=":memory:" />
    </php>
</phpunit>

谢谢

【问题讨论】:

这是什么 Laravel 版本? Laravel 版本:5.5 不能升级到5.6吗?还是更好地掌握? (5.7 很快就会发布)。你用Illuminate\Foundation\Testing\RefreshDatabase;吗?如文件所述? laravel.com/docs/5.5/… 另外写一个只显示当前环境的测试是testing吗?我认为 phpunit.xml 没有被使用。您可以通过dd(app()-&gt;environment()); 进行操作。 对不起,我刚刚查过了。不是5.5而是5.6。我跑了 dd(app()->environment());正如你所建议的那样,我得到了“本地” 【参考方案1】:

我遇到了同样的问题,这可能对某人有帮助。我正在处理 2 个不同的 Lumen 项目,它们都与同一个数据库进行交互。

问题已解决,两个项目的迁移结构相同!

一个项目的迁移文件丢失了一些列,并且由于某种原因在运行 phpunit 后具有删除所有数据库表的相同行为。

【讨论】:

【参考方案2】:

如上所述,这很可能是 Laravel 使用缓存数据库凭据的问题,该凭据指向您的本地/开发数据库,​​而不是用于您的测试。

虽然运行php artisan config:clear 解决了问题,但问题可能在未来再次发生。

永久的解决方案是编辑您的 tests\CreatesApplication 类,如下所示:

<?php

namespace Tests;

use Illuminate\Contracts\Console\Kernel;
use Illuminate\Support\Facades\Artisan;

trait CreatesApplication

    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    
        $app = require __DIR__.'/../bootstrap/app.php';

        $app->make(Kernel::class)->bootstrap();

        $this->clearCache();

        return $app;
    

    private function clearCache(): void
    
        Artisan::call('cache:clear');
    

这可确保在运行测试之前清除缓存。

从我对此回复进行调整的经验中获得了对此回复的见解:https://laracasts.com/discuss/channels/laravel/phpunit-is-deleting-my-database?page=1&replyId=700380

【讨论】:

【参考方案3】:

Michael Ameyaw 的解决方案在 PHPStorm 中对我很有效!谢谢。 我想提一下,这也可能是一个缓存问题,所以试试这个:

php artisan config:clear

【讨论】:

能否参考Michael Ameyaw 的解决方案?它在哪里?【参考方案4】:

我有一个解决方案,如果你正在使用 phpStorm 寻找测试框架。

文件 >> 设置 >> 文件和框架 >> 测试框架。

将默认配置文件设置为根文件夹中的 phpunit.xml

【讨论】:

【参考方案5】:

一般来说,您应该使用相同的表结构分离数据库,如 staging env。这是单元测试的正常行为(我的意思是删除表)。 典型的测试流程是(对于每个测试执行):

    删除所有表。 运行所有迁移(创建表、更改表等)。 加载夹具 在新数据库上执行测试。

想象一下,如果 phpunit 不删除所有数据,其中一个测试会更改用户表中的数据(更改电子邮件或名字等),下一个测试将使用不正确的数据(由另一个测试更改)。 您可以查看laravel main documentation了解更多详情。

【讨论】:

谢谢,我知道这就是为什么有两个不同的数据库(如问题中所述)一个是用于我的持久数据的mysql,另一个是用于测试的sqlite(非持久数据) 好的,那么我无法解决您的主要问题。您需要在每次运行测试时自动运行迁移吗? 不客气。您是否检查了我在答案中发布的文档链接?对你有帮助吗?

以上是关于Laravel:运行 phpunit 测试后删除的数据库表的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4 PHPUnit Sqlite 数据库,每次测试前删除项目

Laravel PHPUnit 测试运行产生异常 调度器创建后无法设置默认工厂

Laravel PHPUnit测试运行产生异常创建调度程序后无法设置默认工厂

PHPUnit 似乎没有运行 Laravel 迁移

在 Laravel 的 Homestead 中运行 PHPUnit

PHPUnit:预期状态码 200 但使用 Laravel 收到 419