PHPUnit/Cypress 在 Laravel 中测试 2 个数据库

Posted

技术标签:

【中文标题】PHPUnit/Cypress 在 Laravel 中测试 2 个数据库【英文标题】:PHPUnit/Cypress Testing 2 Databases in Laravel 【发布时间】:2021-09-14 12:16:06 【问题描述】:

(来自https://laracasts.com/discuss/channels/testing/phpunitcypress-testing-2-databases的交叉帖子)

大家好,所以我正在尝试为我的项目设置测试中途(因为我很傻,没有从一开始就编写测试)

我将简要介绍一下该项目,以便提供一些背景信息...

一个社区运行一个游戏服务器,该服务器使用一个数据库来存储游戏内的持久性、日志和其他数据。 我正在编写一个实用程序站点,以便用户可以查看他们的游戏内 角色信息,管理员可以查看日志,编辑玩家,写 私人笔记等,都在网络界面上 这意味着我有两个网站数据库:游戏数据库,由游戏服务器控制,网站只需访问以读取和编辑内容......以及网站数据库,由网站及其控制迁移,并且只有网站可以访问。

所以网站数据库与用户的游戏数据库有关联...

用户使用 steam auth 登录网站,他们的 steamid 和登录令牌等保存在网站数据库中 玩家加入游戏,游戏将其 Steam ID 存储在游戏数据库中 网站数据库中的用户条目根据他们的 Steam ID 与游戏数据库玩家条目一对一关联

我有一个用于开发的游戏数据库的本地副本。对数据的更改不会影响任何实时内容。


无论如何,我希望这是有道理的...关于问题...

我的问题是当我想用这些数据库测试我的应用程序时...

网站数据库非常简单,无论我使用 SQLite :memory: 数据库还是物理数据库,我都可以使用 RefreshDatabase trait,PHPUnit/etc 将通过我的迁移来处理刷新数据库...都很好...据我所知没有问题...

当我想通过测试处理第二个(游戏)数据库更改回滚时,问题就出现了...我没有此数据库的迁移,因为它不受网站控制或管理。

我的问题是:

    如何让 PHPUnit/cypress/etc 重置由自动化测试引起的对第二个数据库(游戏数据库)的更改? 如果我必须为 #1 编写迁移或其他操作,我如何才能告诉迁移仅在应用程序环境正在测试时运行? (即,在生产环境或本地环境中运行艺术迁移时,游戏数据库的任何迁移都必须运行)

基本上,我希望最终能有一个设置,让 PHPUnit 将测试用例所需的数据插入两个本地测试数据库,然后让 PHPUnit 回滚更改。

我只是不确定如何处理通过 eloquent 访问但不由 laravel 迁移等管理的第二个数据库。它只能由 laravel 访问。

希望所有这些漫无边际的事情都是有道理的,如果有什么需要澄清的,我会尽量详细说明。

我很可能在这里遗漏了一些明显的东西。

【问题讨论】:

无论何时 phpunit 开始测试运行(不仅是单个测试),都可以重置第二个游戏数据库吗?如果是这样,您可以在 bootstrap.php 脚本中执行此操作(它是 a feature the phpunit test-runner supports)。 是否可以进行不执行任何操作的迁移?因此,迁移是定义的,因为它们是无操作的,或者可以表示未定义的迁移。 @hakre 当您说重置数据库时,您的意思是运行一些有效截断表的 PHP 吗?那当然是一个选项,我将不得不研究该 phpunit 功能。至于迁移,不确定,这是我很好奇的一件事 - 如果可以迁移数据库但通常不执行/不执行任何操作......我想我可以添加一个 'if env() = =测试'到迁移本身??? 好吧,我想说这取决于迁移库。有时它足以将其指向不同的文件夹,或者您建议仅在特定环境中运行它。迁移是按应用程序还是按数据库组织的? ATM 我所有的迁移都在一个文件夹中(因为我只有一个数据库的迁移)。我实际上不确定 Laravel 如何处理多数据库迁移......我将不得不研究它 【参考方案1】:

所以我已经通过以下方法让它工作了。

通过指定 .env.testing 文件,我有两个单独的数据库用于测试。

第一个(网站)数据库正在使用 Laravel RefreshDatabase trait 重置

正在使用以下代码重置第二个(游戏)数据库:

    public function setUp() : void 
        parent::setUp();
        \DB::connection('mysql2')->beginTransaction();
    

    public function tearDown() : void 
        parent::tearDown();
        \DB::connection('mysql2')->rollBack();
    

到目前为止,它似乎工作正常,虽然我只写了几个测试......

如果有人有“更好”或“更正确”的答案,请告诉我! :D

【讨论】:

只是一个小提示仅供参考:在拆卸方法结束时调用parent::tearDown();。这与类层次结构一致(父设置、自设置 | 自拆卸、父拆卸)

以上是关于PHPUnit/Cypress 在 Laravel 中测试 2 个数据库的主要内容,如果未能解决你的问题,请参考以下文章

Laravel源码解析--看看Lumen到底比Laravel轻在哪里

如何在 Windows 上通过 Laravel Installer 安装 Laravel?

在 Mac 上安装 Laravel 会抛出 laravel,即使在设置 PATH 后也找不到

Laravel 在控制器中使用非 Laravel Composer 包

如何在 Laravel 8 中使用 srmklive/laravel-paypal v3

laravel怎么在中间表插入数据