Intereting Posts
Как я могу использовать CodeIgniter для загрузки определенных страниц с использованием SSL? не удалось открыть поток: не найдено подходящей обертки Как получить доступ к элементу массива внутри другого массива Ранжирование значений столбцов в базе данных MySQL Загруженное имя файла отправляется через Ajax Преобразование даты в день в php PHP json_encode не удаляет все управляющие символы JSON Петля PHP; как распечатать каждый результат и задержать его на секунду, прежде чем повторить другой результат? Использовать переменные внутри анонимной функции, которая определяется где-то еще PHP и MYSQL: как я могу игнорировать пустые переменные из Где я могу найти хороший парсер MediaWiki Markup в PHP? PHPUnit тестовый и абстрактный класс с помощью метода «Метод» строка поиска синтаксического анализа для фраз и ключевых слов Неверный параметр привязки PHP / MySQL / PDO не работает как лучше всего предотвратить доступ к определенным каталогам веб-сайта?

Очистить память, используемую PHP

У меня возникает интересная проблема. Я использую PHPUnit, и мои тесты занимают больше памяти каждый раз, когда я их запускаю. То есть …

2,25 МБ

2,5 МБ

3,0 МБ

3,5 МБ …….

Кто-нибудь знает, как очистить память, которая потребляется, и может ли кто-нибудь посоветовать мне изучить это подробно? Непосредственная проблема заключается в том, что некоторые из моих более крупных тестов заканчиваются из памяти, и просто продолжая увеличивать максимальный объем выделения памяти в PHP, недостаточно. Мне нужно знать, почему тест PHPUnit, запущенный из командной строки, будет иметь память которое «прилипает» между прогонами.

Calvin, как обсуждалось в чате , из-за отсутствия функций сброса.

При тестировании мы должны обеспечить, чтобы тестовая среда была последовательной, чтобы мы могли получать точные результаты. Computing – это Input / Output, поэтому мы должны использовать Fixtures в PHPUnit для сброса памяти, чтобы предотвратить утечку памяти.

Увеличение памяти имеет три-четыре причины:

1) PHPUnit собирает данные покрытия кода

Вы ничего не можете с этим сделать, кроме как отключить покрытие кода.

2) PHPUnit кэширует токены файлов для покрытия кода

Вы можете использовать <phpunit cacheTokens="false"> в вашем PHPUnit xml. См. Примечание об этом в http://phpunit.de/manual/current/en/installation.html#installing.upgrading

3) PHPUnit неправильно очищает после себя

В текущей реализации он хранит тестовые примеры, потому что это то, где хранятся данные результата. В будущем это будет изменено, чтобы быть более эффективным, но на данный момент это то, как все работает.

4) Приведение к «4»: вам нужно очистить себя

Так как экземпляры TestCase хранятся вокруг ваших переменных-членов, они тоже обходятся.

Это означает, что вы можете сэкономить много памяти, используя

 public function tearDown() { unset($this->whatever); } с public function tearDown() { unset($this->whatever); } 

но делать это очень утомительно.

Мое предложение состоит в том, чтобы иметь базовый тестовый класс для всех ваших тестовых примеров и использовать его:

 class MyBaseTest extends \PHPUnit_Framework_TestCase { protected function tearDown() { $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); } } } } 

Это будет автоматически очищаться после вас.

(реквизит для фрагмента перейдите по адресу : http://kriswallsmith.net/post/18029585104/faster-phpunit )


PHPUnit не может сделать это в сопоставимом обратном пути, который не нарушил бы проекты людей, поэтому вы должны добавить его для себя 🙂

Технические подробности сборки мусора PHPUnit уже были покрыты @edorian и @mauris, но я хотел добавить, что PHPUnit (по крайней мере, в версии 3.7.21, который я запускаю) дает вам возможность добавить комментарий:

 /** * @backupGlobals disabled */ class MyClassTests extends PHPUnit_Framework_TestCase{} 

Прежде чем добавлять аннотацию, я почти удвоил использование памяти в каждом прогоне моего тестового набора, последний из которых достиг 1100 МБ. Теперь они работают на 15 МБ.

Если вы используете PDO (или аналогичную абстракцию базы данных), вы можете использовать «sqlite :: memory:» как вы DSN. Это имеет три больших преимущества:

  1. Автоматическая очистка после каждого теста
  2. Отсутствие возможности случайного касания производственной базы данных (например, даже при выполнении модульных тестов на вашем производственном сервере).
  3. Все в памяти, поэтому тесты могут работать быстрее

Недостатком является то, что ваш SQL должен быть переносимым между MySQL и SQLite. Это может оказаться довольно большой работой (для больших проектов это часто стоит не только для тестов, но и для того, как это улучшит дизайн вашего кода). В вашем случае вы можете упомянуть использование Doctrine в стенограмме чата , поэтому у вас может быть хорошая абстракция, и поэтому она может запускаться без изменений в SQLite.