Таблица Db обработчика сеанса Zend уничтожается во время теста PHPUnit

#zend-framework #phpunit #zend-session

#zend-framework #phpunit #zend-сессия

Вопрос:

Я проводил модульное тестирование и столкнулся с этой странной проблемой.

Я провожу тесты аутентификации пользователей с некоторыми из моих сервисов / картографов.

Я запускаю все вместе около 307 тестов прямо сейчас. Это действительно происходит только тогда, когда я запускаю их все в одном пакете.

Я пытаюсь создать экземпляр только одного объекта Zend_Application и использовать его для всех моих тестов. Я создаю ее экземпляр только для того, чтобы позаботиться о подключении к БД, сеансе и автозагрузке моих классов.

Вот в чем проблема.

Где-то в строке тестов вызывается метод __destruct таблицы zend_session_savehandler_db. Я понятия не имею, ПОЧЕМУ? Но это происходит.

Метод __destruct сделает любую запись в мои объекты сеанса бесполезной, поскольку они помечены как доступные только для чтения.

Я понятия не имею, почему вызывается метод destruct.

Перед моими тестами аутентификации вызывается множество тестов. Если я запускаю каждую папку тестов по отдельности, проблем не возникает. Это происходит только тогда, когда я пытаюсь запустить все 307 тестов. У меня есть некоторые тесты, которые работают с базой данных, но мой код не закрывает соединения с БД или не уничтожает обработчик сохранения.

У кого-нибудь есть какие-либо идеи о том, почему это могло произойти и почему моя Zend_Session_SaveHandler_DbTable уничтожается? Имеет ли это какое-либо отношение к времени жизни, которое у нее есть по умолчанию?

Ответ №1:

Я думаю, что происходило то, что PHPUnit выполнял сборку мусора. Всякий раз, когда я запускал 307 тестов, должен был запускаться сборщик мусора, и он, вероятно, по какой-то причине уничтожал Zend_Session_SaveHandler_DbTable.

Это объясняет, почему она не была уничтожена при выполнении меньшего количества тестов.

Или, может быть, сборкой мусора занимался PHP, это имеет больше смысла.

В любом случае, мое текущее решение заключается в создании нового объекта Zend_Application для каждого тестового класса, чтобы у всех тестов в этом классе был новый объект zend_application для работы.

Вот некоторая интересная информация.

Я ввел оператор echo в метод __destruct обработчика сохранения.

Метод вызывался (X 1) раз, где X было количеством тестов, которые я запустил. Если я запустил 50 тестов, я получил 51 эхо-сигнал, 307 тестов, затем 308 эхо-сигналов и т.д.

Вот интересная часть. Если бы я выполнил всего несколько тестов, все эхо-сигналы пришли бы в КОНЦЕ тестового запуска. Если бы я попытался запустить все 307 тестов, после того, что я принял за 90 тестов, появилось бы 90 эхо-сигналов. Остальные эхо-сигналы будут отображаться в конце оставшихся тестов. Количество эхо-сигналов снова составило X 1, или в этом случае 308.

Итак, я предполагаю, что это как-то связано либо с методом демонтажа, который вызывает PHPUnit, либо со сборщиком мусора PHP. Возможно, PHPUnit вызывает сборщик мусора при демонтаже. Кто знает, но я рад, что у меня все заработало сейчас, поскольку все мои тесты были пройдены заранее.

Если у кого-нибудь из вас есть решение получше, дайте мне знать. Возможно, я обнаружил ошибку в моем коде, phpunit или zend, о которой раньше не было известно, и есть какой-то способ это исправить.

Комментарии:

1. Я думаю, теоретически вам нужен новый объект приложения для каждого теста. На практике, однако, часто используется один и тот же объект, когда мы уверены, что он исправен для каждого последующего теста. Все ли они находятся в одном наборе тестов? Наличие ваших тестов в разных наборах помогает в устранении подобных проблем. Если вы обнаружите, где _destruct вызывается дважды, вы, вероятно, обнаружите, что блокирует ваши тесты. Удачи, спасибо за публикацию ваших результатов.

2. Привет, у меня был загрузочный файл, создающий глобальный объект zend_application и помещающий его в переменную $ GLOBALS. Затем каждый тестовый класс будет извлекать объект приложения в своих методах setUpBeforeClass / SetUp. Я не отправлял никаких контроллеров или что-то еще. Причина, по которой я создавал ее экземпляр, заключалась в том, что приложение могло быть вызвано для настройки автозагрузки моих моделей и подключения к базе данных для тестов базы данных / аутентификации.

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

Ответ №2:

Это старый вопрос, но у меня только что была такая же проблема, и я нашел решение здесь. Я думаю, что это правильный способ решить эту проблему.

 Zend_Session::$_unitTestEnabled = true;