Вопрос по php, symfony, unit-testing – Практики для тестирования базы данных в Symfony2? Как изолировать?
=========================================================================================================

Каковы современные рекомендации по тестированию взаимодействия баз данных с Symfony2? У меня есть простая настройка CRUD, и я хочу убедиться, что мое тестирование в порядке. Прямо сейчас у меня есть 4 теста, каждый из которых проверяет, что действия по созданию, обновлению, удалению и списку выполняются нормально.

У меня есть два магических метода, \_\_construct и \_\_destruct, в моем тестовом случае. Внутри них я вызываю exec () с помощью «php app / console ...» чтобы создать базу данных, создайте схему, а затем удалите базу данных. Тем не менее, это МЕДЛЕННО, черт возьми, и это происходит все время, когда у меня более одного тестового случая.

Как мне действовать, когда дело доходит до тестирования базы данных и изоляции таких тестов?

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

Заметьте, что я только создаю необходимые таблицы базы данных, а я только вставляю необходимые данные. Это немного быстрее, чем загрузка большого дампа базы данных. Он также более чистый, поскольку в тестах нет общих приборов (что облегчает их обслуживание).

У меня есть базовый класс тестового случая с именем KernelAwareTest, который помогает мне в построении схемы. Вы можете найти это в сущности:<https://gist.github.com/1319290>

`setUp()` загружает ядро Symfony и сохраняет ссылку на него в свойстве класса (вместе со ссылками на DIC и диспетчер сущностей). Также призыв к`generateSchema()` сделан для генерации схемы базы данных (использует Schema Tool из Doctrine).

По умолчанию он генерирует структуру базы данных для всех сущностей, известных менеджеру сущностей. Вы можете изменить это поведение в своем тестовом классе, переопределив`getMetadatas()` метод.

П.С .: Я пытался использовать в базе данных памяти (sqlite), но она не была идеальной. В любом случае, вероятно, лучше запускать тесты для базы данных, которую вы используете в производственной среде.



Вопрос довольно старый, но все еще актуален сегодня, так что вот мой опыт и то, как я справляюсь сегодня с моими проектами Symfony.

Я начал использовать базу данных SQLite в памяти для своих тестов и перестраивал схему db + вставленные осветители перед каждым отдельным тестом. Это имело два основных недостатка:

It was still way too slow :(
On dev & prod I used Mysql which soon became a problem because SQLite simply does not have all the features needed and sometimes behaves differently
Использование MSQL для тестов и перестройка схемы + вставка осветителей перед каждым тестом просто была слишком медленной. Поэтому я искал альтернативы ...

Я наткнулся на это сообщение в блоге:<http://alexandre-salome.fr/blog/Symfony2-Isolation-Of-Tests>

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

Я взял эту идею и создал пакет для нее:<https://github.com/dmaicher/doctrine-test-bundle>

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

С помощью этого комплекта вы можете просто создать свою схему базы данных + вставить приспособления ОДИН РАЗ перед выполнением всего набора тестов (я предпочитаю делать это в пользовательском файле начальной загрузки phpunit). При использовании прослушивателя phpunit все тесты будут выполняться внутри транзакций базы данных.

Я уже давно пользуюсь этим комплектом, и для меня он прекрасно работает с использованием SQLite, MySQL или PostgreSQL.

С тех пор его также использовали в проекте symfony-demo.



тестирование на локальной машине - это боль в ..., поэтому я начал использовать ci system buddy.works (есть бесплатная автономная версия), и для этого мне нужно было решить эту проблему самостоятельно.

результат:

all tests works
tests are runing on production sql data
tests are running in separation (not in dev or production) - so i can do
anything that i want with database
all pushes to git are tested and i have notification if something is broken
all pushes/pull request to deploy branch are automatic uploaded to production
Это мое решение:

second parameters.yml in config with configuration for test
on production i'm making daily sqldump
on starting test on ci this sql backup is copied via scp to test machine
to prepare all this i'm using robo.li ( my config is below)

}

Я надеюсь, что это поможет вам создать идею, как все это организовать. Использование автономного ci сложно в настройке, но это действительно хорошая идея



Тестирование базы данных всегда медленное, так как вам нужно создавать / удалять схему до / после каждого теста. Чтобы избежать ненужных операций, вы можете:

create schema in the 'setUpBeforeClass' method;
ensure your 4 tests are launched in one thread with the '@depend' annotation;
drop schema in the 'tearDownAfterClass' method.
Схема будет создана / удалена только один раз для вашего теста.

Вы также можете настроить доктрину для использования базы данных sqlite (это очень быстро):

В любом случае, \_construct' and '\_destruct & APOS; никогда не должен использоваться в тестовых случаях phpunit, вместо этого вы должны использовать «setUp»; и «tearDown».