Laravel 5 内存测试

2024-03-31

我正在通过 behat 为我的大型 Laravel 5 项目编写测试。

我在 MySQL 中有一个 MySQL 数据库的测试副本,以及该数据库的一个播种器,它共享其他环境的一些播种器。所有这些都按预期进行。

但是,我尝试切换到使用 sqlite 内存数据库,因为它会显着加快我的自动化测试速度,并且因为我在每个行为场景开始时运行“artsian migrate:refresh ---seeder=TestDatabaseSeeder”。

我遇到的问题是我的一些种子数据导致 sqlite 抛出一个非常非描述性的语法错误,但 MySQL 完全可以处理种子数据。

我认为,理想情况下,我希望它使用内存中的 MySQL 来提高性能并保持数据库引擎的一致性。在运行测试时,有没有一种简单的方法可以在有或没有 Laravel 的情况下在内存中使用 MySQL?一个不涉及以让 sqlite 满意的方式复制和编辑迁移文件的解决方案?


截至 2019 年,这里是进行 Laravel PHPunit 测试以使用内存数据库的方法。

为 Laravel / Lumen 测试设置 SQLite 内存

您必须具备以下条件:

  1. 数据库中所有表和字段的所有数据库迁移就像您通常对实际数据库所做的那样,请参阅Laravel 迁移官方文档 https://laravel.com/docs/5.8/migrations.
  2. Use the RefreshDatabase trait (DatabaseMigrationsLumen 的特征)在你的 PHPUnit 测试类中(官方文档 https://laravel.com/docs/5.8/database-testing#resetting-the-database-after-each-test).
  3. 在您的中设置以下内容config/database.php文件输入connection setion:
    'testing' => [
        'driver' => 'sqlite',
        'database' => ':memory:',
    ],
  1. 在您的中设置以下行phpunit.xml文件输入<php>部分:
    <env name="DB_CONNECTION" value="testing"/>

因此,一旦您运行 PHPUnit 测试,PHPUnit 将读取phpunit.xml, 更换.env's DB_CONNECTION变量与testing。它将触发数据库配置testing(这是内存中的sqlite DB)要使用的。

内存数据库与磁盘数据库的测试(根据我的经验)大约快 5-30 倍。大约 200 个 CRUD 测试的小型测试套件存在 30 倍的差异,所有测试都在六个表上运行数据库查询,其中一些表hasMany and belongsToMany枢轴关系。

每次测试刷新数据库

运行数据库迁移每次测试前都有一个干净的数据库 https://laravel.com/docs/6.x/database-testing#resetting-the-database-after-each-test将以下特征添加到测试类(Laravel)的顶部:

use Illuminate\Foundation\Testing\RefreshDatabase;
// ... then in the class body:
use RefreshDatabase;

对于流明它应该是 https://lumen.laravel.com/docs/6.x/testing#working-with-databases

use Laravel\Lumen\Testing\DatabaseMigrations;
// ...then
use DatabaseMigrations;

不要忘记使用模型工厂 https://laravel.com/docs/6.x/database-testing#writing-factories如果需要,用测试数据为数据库播种。

是的,迁移将在每次测试之前和之后运行,以便在测试完成后以干净的数据库开始和结束(如果您在磁盘数据库中植入一些数据并偶尔将测试切换到在其上运行而不是在内存数据库上运行)。

修复 SQLiteCannot add a NOT NULL column with default value NULL error

现在您已经成功地为您的应用程序设置了内存数据库测试。当您尝试使用外键对某些相关表进行级联更改时,预计会出现上述错误。

如果您快速将测试切换到磁盘上的数据库(注释掉<env name="DB_CONNECTION" value="testing"/>在你的phpunit.xml文件)错误消失。切换回内存数据库后,检查磁盘数据库不为空。如果是这样运行migrate:refresh and db:seed(这里假设您已经提前准备好所需的数据库种子)artisan.

默认情况下,SQLite 禁用外键。将以下代码片段添加到您的 PHPUnit 测试类中以解决此问题:

// At the file's top to import the DB facade
use Illuminate\Support\Facades\DB;


// In the setUp() method
parent::setUp();
if (DB::connection() instanceof \Illuminate\Database\SQLiteConnection) {
    DB::statement(DB::raw('PRAGMA foreign_keys=on'));
}

See 详细的解释和更多、更好、不同解决方案在这里 https://stackoverflow.com/questions/31228950/laravel-5-1-enable-sqlite-foreign-key-constraints.

希望这足以澄清这个主题,以便顺利工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Laravel 5 内存测试 的相关文章

  • SQLAlchemy - 批量插入忽略:“重复条目”

    我有一个名为user data 列id and user id作为唯一的密钥 我想将一些历史数据导入到该表中 我用批量插入映射 http docs sqlalchemy org en rel 1 0 orm session api html
  • 删除表的重复项

    In my activity logs 它包含列 material name user id mod result 这标志着测试是否通过 失败 cert links 不知何故 用户生成了两倍的条目material name与cert lin
  • 是否可以将新表和旧表从触发器传递到 MySQL 中的过程中?

    是否可以将新表和旧表从触发器传递到 MySQL 中的过程中 我怀疑不会 因为没有过程接受的表这样的数据类型 有什么可能的解决方法吗 理想情况下它看起来像这样 CREATE TRIGGER Product log AFTER UPDATE O
  • Laravel 5.2 带有可变参数的命名路由用法

    我有这样的路线 Open New Subscription page Route get account subscriptions create menu uses gt Subscriptions SubscriptionControl
  • 在 Mysql 上使用 EntityManager JPA 运行脚本

    我正在尝试运行脚本 sql 文件 但由于我尝试了多种方法 因此出现多个错误 这是我的主要 sql 脚本 INSERT INTO Unity VALUES 11 paq 0 2013 04 15 11 41 37 Admin Paquete
  • 安装后如何使用 npm 包 (chart.js)?

    我正在制作一个练习 Laravel 站点 并且我已经通过 npm install 安装了 Chart js 这是一个愚蠢的问题 但现在我如何从这里使用它 或通过 npm 安装的任何东西 这些文件安装在节点模块文件夹中 我应该在页眉中使用标签
  • Hibernate + MySQL + rewriteBatchedStatements=true

    我有以下 Hibernate 配置
  • 何时在 mysql 中使用 Union [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 对于 Union 您会在什么现实情况下使用它 因为对我来说 对具有不同列用途 含义的两个表中的两个选择查询使用联合是没有意义的 例如
  • PHPUnit\Framework\TestCase 和 Tests\TestCase 有什么区别?

    我注意到在示例测试中 这两个类是内置的 功能测试 gt use Tests TestCase 单元测试 gt PHPUnit Framework TestCase 两者有什么区别 在什么情况下您会使用其中一种 PHPUnit Framewo
  • 如何使用wireshark清晰捕获mysql查询sql

    因为我们使用远程开发Mysql服务器 所以不能轻易检查查询sql 如果使用本地服务器可以tail f general log file查看调用某个http接口时执行了哪些sql 所以我安装了一个wireshark捕获这些从本地发送的查询sq
  • 在 Laravel 中动态设置数据库连接和语言

    我有 3 个域指向同一个Laravel应用 我想要的是每个人都连接到自己的数据库并根据 TLD 加载自己的语言文件 我可以在哪个文件中设置这些设置 我可以直接在配置文件中执行此操作 或者可以在加载配置之前执行某些事件 我拥有的是一个简短的函
  • SQLite CreateDatabase 不支持错误

    我将 Entity Framework 4 2 CF 与 SQLite 一起使用 但是当我尝试启动该应用程序时 出现 提供商不支持 CreateDatabase 错误 这是我的模型映射 protected override void OnM
  • 导入已经创建的sqlite数据库(xamarin)

    我正在使用 Xamarin 想知道如何导入我已经创建的 sqlite 数据库 到目前为止 我已将其添加到资产文件夹中 但不知道下一步从哪里开始 string localPath Path Combine System Environment
  • MySQL Python 关于重复键更新值

    我正在研究使用 python 将 JSON 数据上传到 MySQL 我需要在插入语句中包含 ON DUPLICATE KEY UPDATE VALUES 但在 Python 中遇到了问题 如果我运行以下代码 一切正常 import json
  • 从 Grib 天气模型中提取数据

    我已经下载了grib1模型数据来自GFS http en wikipedia org wiki Global Forecast System 我使用的是 Mac OS X 并且能够构建wgrib2文件来自NOAA http en wikip
  • 无法在 mysql-apt-config [Ubuntu 14.04] 中选择“确定”

    我使用的是 Ubuntu 14 04 sudo apt get update总是给我这个选项来配置 mysql apt config 我尝试选择版本 按 tab gt 在 确定 上突出显示的键 按 Enter 但没有任何反应 它再次返回并突
  • 在android中创建SQLite数据库

    我想在我的应用程序中创建一个 SQLite 数据库 其中包含三个表 我将向表中添加数据并稍后使用它们 但我喜欢保留数据库 就好像第一次安装应用程序时它会检查数据库是否存在 如果存在则更新它 否则如果不存在则创建一个新数据库 此外 我正在制作
  • PDO语法错误

    我在一个项目中使用 PDO 但提交时出现语法错误 这是我的代码
  • 获取mysql中逗号分隔行中不同值的计数

    一个表 Jobs 有 2 列 JobId 城市 当我们保存工作时 工作位置可能是多个城市 如下所示 JobId City 1 New York 2 New York Ohio Virginia 3 New York Virginia 我如何
  • 如何在查询语句之外从mysql查询中获取值?

    这是下面的函数console log function quo value value connection query SELECT role from roles where id 1 function error results fi

随机推荐