Laravel & PHPUnit : 允许进程隔离以防止 Mysql Too many connections 错误

Posted

技术标签:

【中文标题】Laravel & PHPUnit : 允许进程隔离以防止 Mysql Too many connections 错误【英文标题】:Laravel & PHPUnit : allow process isolation to prevent Mysql Too many connections error 【发布时间】:2013-07-24 00:16:49 【问题描述】:

四个月以来,我们使用 Laravel 4 构建了一个复杂的 Web 应用程序,具有良好的单元测试覆盖率。现在我们有 159 个测试和 592 个断言来防止回归并允许我们轻松地重构我们的应用程序。

图片不错,但最近几天我们在最后的测试中出现以下错误:

PDOException: SQLSTATE[HY000] [1040] Too many connections

原因很简单:所有测试都在同一个进程中运行,而 mysql 在同一时间只允许一定数量的访问。现在,我们有太多的测试。如果我在我的测试套件中间删除了几个测试,最后一个通过。

解决方案可能是像下面的配置一样在进程隔离中运行 phpUnit,但 Laravel 测试似乎没有像那样启动。我在每次测试中都遇到另一个错误:

PHPUnit_Framework_Exception: Notice: Constant LARAVEL_START already defined in /.../.../autoload.php on line 3
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
     backupStaticAttributes="false"
     bootstrap="bootstrap/autoload.php"
     colors="true"
     convertErrorsToExceptions="true"
     convertNoticesToExceptions="true"
     convertWarningsToExceptions="true"
     processIsolation="true"
     stopOnFailure="false"
     syntaxCheck="false"
>

</phpunit>

所以我的问题是:我如何配置 Laravel 测试以使用 processIsolation="true" 或者您是否看到解决我问题的其他方法?

【问题讨论】:

这个问题你解决了吗? 您可以查看此讨论:plus.google.com/107528973720672293459/posts/bBC5CdKPFQ4 了解更多信息。基本上,我无法将 Laravel 和 PHPUnit 一起配置为与 processIsolation 一起使用,所以我只需在 MySQL 配置中将 max_connections 设置为 1000。不是很漂亮,但很管用。 【参考方案1】:

您现在可以执行 DB::connection()->setPdo(null) 来关闭测试的 tearDown 中的连接,应该可以解决它。如果这不起作用,您可以在任何扩展 Laravel 的 TestCase 的测试中执行 unset($this-&gt;app['db'])

【讨论】:

这可能很棒,但 setPdo 方法只接受 PDO 的实例作为参数... 是的,泰勒似乎编辑了我的 PR,我添加了一个替代答案,这是我目前正在使用的答案。 有效!我将unset($this-&gt;app['db']) 放入我的tearDown 中,就是这样。 这个旧解决方案不适用于当前版本的 Laravel(4.2 或 5.0)。可以改用@efinal的解决方案,效果很好。【参考方案2】:

对于 Laravel 4,您可以在 tearDown() 函数中使用 \DB::disconnect('connection')。在此处查看文档:http://laravel.com/docs/database#accessing-connections

"如果由于超出了底层 PDO 实例的 max_connections 限制而需要断开与给定数据库的连接,请使用断开连接方法"

【讨论】:

【参考方案3】:

我会看看 Mocks 并删除您的 MySQL 依赖项:https://github.com/padraic/mockery#mocking-public-static-methods

接下来,我实际上建议更多地关注测试您的 SQL。我的公司最近花费了大量资金招聘 DBA,这确实扭转了我们遗留的缓慢问题。

【讨论】:

感谢您的想法,但我真的很想测试我的数据库有几个原因。我想测试迁移,我有很多需要数据库访问的功能测试,它们接近集成测试。另一点是经典 Web 应用程序 90% 的工作是保存、访问和呈现数据。如果您在测试中不检查数据库,我认为您错过了一些东西 “如果你在测试中不检查数据库,我认为你错过了一些东西......”虽然这当然是真的,但这并不意味着你有同时运行单元测试和集成测试。【参考方案4】:

根据http://www.neontsunami.com/posts/too-many-connections-using-phpunit-for-testing-laravel-51

这在 Laravel 5.1 中运行良好

public function tearDown()

    $this->beforeApplicationDestroyed(function () 
        DB::disconnect();
    );

    parent::tearDown();

【讨论】:

以上是关于Laravel & PHPUnit : 允许进程隔离以防止 Mysql Too many connections 错误的主要内容,如果未能解决你的问题,请参考以下文章

Laravel - PHPUnit 中的伪造路由

Laravel 5 PHPUnit 测试 json 帖子

phpunit,laravel:当当前类范围没有父级时不能使用“父级”

Laravel 5.5 PHPunit 测试 - “尚未设置外观根。”

使用 PhpStorm 在 Laravel 中运行单一功能测试

laravel 4 无法让 phpunit 测试工作