对于 ZF3 和 Doctrine 的 PHPUnit 测试,我面临着“太多连接”的问题,因为我在每次 PHPUnit 执行时执行约 200 个测试。 我已经找到了一些关于堆栈溢出的问题和答案,但这些都不起作用。
我的设置: ZF2/ZF3、Doctrine 2 和 PHPUnit。
我有一个用于所有测试的基本测试类,setUp 和 tearDown 函数如下所示:
public function setUp()
{
$this->setApplicationConfig(Bootstrap::getConfig());
Bootstrap::loadAllFixtures();
if (!static::$em) {
echo "init em";
static::$em = Bootstrap::getEntityManager();
}
parent::setUp();
....
}
public function tearDown()
{
parent::tearDown();
static::$em->flush();
static::$em->clear();
static::$em->getConnection()->close();
$refl = new \ReflectionObject($this);
foreach ($refl->getProperties() as $prop) {
if (!$prop->isStatic() && 0 !== strpos($prop->getDeclaringClass()->getName(), 'PHPUnit_')) {
$prop->setAccessible(true);
$prop->setValue($this, null);
}
}
gc_collect_cycles();
}
public static function (Bootstrap::)loadAllFixtures()
{
static::$em->getConnection()->executeUpdate("SET foreign_key_checks = 0;");
$loader = new Loader();
foreach (self::$config['data-fixture'] as $fixtureDir) {
$loader->loadFromDirectory($fixtureDir);
}
$purger = new ORMPurger(static::$em);
$executor = new ORMExecutor(static::$em, $purger);
$executor->execute($loader->getFixtures());
$executor = null;
$purger = null;
static::$em->getConnection()->executeUpdate("SET foreign_key_checks = 1;");
static::$em->flush();
static::$em->clear();
}
我正在使用 innotop 监控我的本地 MySQL 服务器,并且连接数在增加。
你知道我遗漏了什么吗?
谢谢, 亚历山大
2017 年 2 月 14 日更新:
我已将函数更改为使用 static::$em
并添加了 Bootstrap::loadAllFixtures
方法。
如果我将 static::$em->close()
添加到 tearDown
方法,所有后续测试都会失败,并显示类似“EntityManager 已关闭”的消息。 echo "init em";
仅调用一次并在第一次测试时显示。
是否可以检查我的应用程序是否打开连接而不关闭它们?我的测试用例基于 AbstractHttpControllerTestCase
最佳答案
我也遇到了这个问题。按照 PHPUnit 文档中的建议,我做了以下事情:
final public function getConnection()
{
if ($this->conn === null) {
if (self::$pdo == null) {
//We get the EM from dependency injection container
$container = $this->getContainer();
self::$pdo = $container->get('Doctrine.EntityManager')->getConnection()->getWrappedConnection();
}
$this->conn = $this->createDefaultDBConnection(self::$pdo, 'spark_api_docker');
}
return $this->conn;
}
当 self:$pdo
被共享时,'threads_connected' 的数量,当我观察到 show status like '%onn%';
在我的数据库上时,爬行直到达到极限为止。
我找到了两个解决方案:
1)每次测试后关闭连接
public function tearDown()
{
parent::tearDown();
//You'll probably need to get hold of our entity manager another way
$this->getContainer()->get('Doctrine.EntityManager')->getConnection()->close();
}
重要的是,不要将 self::$pdo
设置为 null
。我曾在别处将此视为建议,但将其设置为静态属性并在每次测试后重新设置是没有意义的。
这可以关闭不再需要的连接。测试用例完成后,除非您关闭连接,否则它将保持打开状态,直到脚本结束(即 PHPUnit 完成运行测试)。由于您要为每个测试用例创建一个新连接,因此连接数会增加。
2) 在单独的 PHP 线程中运行每个测试
这是大锤式的方法。它可能会在某种程度上影响您的测试速度。在你的 phpunit.xml 中:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
...
processIsolation = "true"
>
...
</phpunit>
回到 PHPUnit 的建议,存储连接和 PDO 有助于避免为每个测试 创建新的连接,但当您有许多测试用例 时则无济于事。每个测试用例都在同一个线程中实例化,每个都将创建一个新连接。
关于PHPUnit 测试和 Doctrine,连接太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42188033/