mrh*_*rhn 5 php phpunit laravel
Time: 1.89 minutes, Memory: 526.00MB
OK (487 tests, 2324 assertions)
Run Code Online (Sandbox Code Playgroud)
这是我测试 Laravel API 的 phpunittest 结果,内存消耗一直在增加,感觉就像我尝试了互联网上的所有帖子和答案,以了解在测试时不断增加内存的原因。从自己的调试中,应用程序被丢弃了它应该进行的每一个测试。
一切都非常标准,createApplication 方法看起来像这样。
public function createApplication()
{
// Ran out of memory
ini_set('memory_limit', '1024M');
$app = require __DIR__ . '/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
}
Run Code Online (Sandbox Code Playgroud)
得出的结论是内存泄漏在,没有得到正确清理。
$app = require __DIR__ . '/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
Run Code Online (Sandbox Code Playgroud)
这是我找到的最简单、最可靠的解决方案。它没有我之前的回答中描述的缺点。
将文件中的<phpunit>标签processIsolation属性值更改为。正确文件开头的示例:truephpunit.xmlphpunit.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="true"
stopOnFailure="false">
...
Run Code Online (Sandbox Code Playgroud)
它是如何工作的:它使 PhpUnit 为每个测试启动一个新的 PHP 进程。在单独的进程中运行测试会强制 PHP 在测试结束后释放所有内存。它会减慢测试速度,但这是低内存消耗和可靠性的代价。
或者,如果您需要在单独的进程中仅运行某些测试,则可以向测试类的文档块添加@runTestsInSeparateProcesses注释:
/**
* @runTestsInSeparateProcesses
*/
class HeavyTest extends TestCase
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的解决方案。我在 Laravel 5.5 中测试了它。将其设置为文件的内容tests/CreatesApplication.php:
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
trait CreatesApplication
{
/**
* @var \Illuminate\Foundation\Application
*/
protected static $application;
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
if (!isset(static::$application)) {
static::$application = require __DIR__ . '/../bootstrap/app.php';
static::$application->make(Kernel::class)->bootstrap();
}
return static::$application;
}
/**
* {@inheritDoc}
*/
protected function tearDown()
{
// Required if you use HTTP tests
$this->app['auth']->guard(null)->logout();
$this->app['auth']->shouldUse(null);
$this->flushSession();
// Always required
$this->app = null;
parent::tearDown();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码使测试对所有测试使用相同的 Laravel 应用程序实例,而不是为每个测试创建一个新实例。这也会导致更快的测试运行。
该解决方案有缺点:
DatabaseTransactions或DatabaseMigrations特征,则当 PHPUnit 测试运行的所有测试完成后,数据库将被重置。