Intereting Posts

Тестирование вставки базы данных с помощью Symfony

Всем добрый день,

За последние несколько дней я много изучал Test Driven Development и решил, что мне тоже нужно это изучить. Хотя я не могу понять, как это сделать.

Мой проект зависит от структуры Symfony2.1.6 и Doctrine, поэтому у меня есть несколько таблиц базы данных, которые необходимо заполнить.

Книга (1, n) – (0, n) Жанр

Теперь, если я хочу вставить запись в жанре, мне сначала нужно написать тест, чтобы все было вставлено так, как должно (или я ошибаюсь?)

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

Единственное, что я мог найти, было с LiipFunctionalTestBundle https://github.com/liip/LiipFunctionalTestBundle, который создает и восстанавливает временную базу данных каждый раз, когда я запускаю тест. Я настроил все в соответствии с инструкциями.

Изменить: Мое приложение / config / config_test.yml выглядит следующим образом:

imports: - { resource: config_dev.yml } framework: test: ~ session: storage_id: session.storage.filesystem liip_functional_test: ~ web_profiler: toolbar: false intercept_redirects: false swiftmailer: disable_delivery: true liip_functional_test: cache_sqlite_db: true doctrine: dbal: default_connection: default connections: default: driver: pdo_sqlite path: %kernel.cache_dir%/test.db 

Итак, теперь у меня есть класс GenreTest:
У Лиипа нет документации, поэтому я просто попробовал такой подход.

 use Liip\FunctionalTestBundle\Test\WebTestCase; class GenreTest extends WebTestCase { public function testInsert() { $container = $this->getContainer(); $registry = $container->get('doctrine'); $em = $registry->getEntityManager(null); $genre = new Genre(); $genre->setName("testGenre"); $em->persist($genre); $em->flush(); $result = $em->createQuery("SELECT g FROM QkprodMangressBundle:Genre g ". "WHERE g.name = :name") ->setParameter("name", $genre->getName()) ->getResult(); $this->assertEqual($result[0]->getName(), $genre->getName()); } } 

phpunit -c web /

PDOException: не удалось найти драйвер /…/Mangress/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:36 /…/Mangress/vendor/doctrine/dbal/lib/Doctrine/DBAL /Driver/PDOSqlite/Driver.php: 60 /…/Mangress/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php:350 /…/Mangress/vendor/doctrine/dbal/lib/Doctrine /DBAL/Connection.php:949 /…/Mangress/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:306 /…/Mangress/vendor/doctrine/orm/lib/Doctrine/ORM /EntityManager.php:355 /…/Mangress/app/cache/test/jms_diextra/doctrine/EntityManager_510128d0a5878.ph p: 362 /…/Mangress/src/Qkprod/MangressBundle/Tests/Entity/GenreTest.php: 27 НЕИСПРАВНОСТИ! Тесты: 3, Утверждения: 1, Ошибки: 1.

Большой вопрос, который у меня возникает, – это … как я могу проверить что-то подобное? Или я даже тестирую связь с базой данных? Подделка связи с базой данных через пользовательскую реализацию не кажется мне хорошей идеей, потому что она будет использовать ORM и Doctrine в производственной среде.

Извините, здесь оказался маленький роман.

Я почти полностью решил свою проблему:

  1. Установите драйверы, необходимые для db-связи;)
    PDO_SQLITE driver нет .. что делать?

     sudo apt-get install php5-sqlite 
  2. Восстановить схему на каждом тестовом прогоне
    https://stackoverflow.com/a/10463614/1177024


Это мое тестирование класса против базы данных

 namespace Qkprod\MangressBundle\Entity; use Qkprod\MangressBundle\Entity\Genre; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; private $em; /** * Sets up environment for testing * Regenerates Database schema before every test-run */ public function setUp() { static::$kernel = static::createKernel(); static::$kernel -> boot(); $this -> em = static::$kernel->getContainer() ->get('doctrine') ->getEntityManager(); $this->regenerateSchema(); } protected function tearDown() { parent::tearDown(); $this -> em -> close(); } /** * Drops current schema and creates a brand new one */ protected function regenerateSchema() { $metadatas = $this->em->getMetadataFactory()->getAllMetadata(); if (!empty($metadatas)) { $tool = new \Doctrine\ORM\Tools\SchemaTool($this->em); $tool -> dropSchema($metadatas); $tool -> createSchema($metadatas); } } public function testInsert() { $genre = new Genre(); $genre -> setName("testGenre"); $this -> em -> persist($genre); $this -> em -> flush(); $result = $this -> em -> createQuery("SELECT g " . " FROM QkprodMangressBundle:Genre g " . " WHERE g.name = :name") -> setParameter("name", $genre -> getName()) -> getResult(); $this -> assertEquals($result[0] -> getName(), $genre -> getName()); } } 

Не удалось заставить LiipBundle работать, но вы можете увеличить скорость невероятно, установив symfony, чтобы сохранить SQL-файл sqlite в памяти вместо файловой системы. https://stackoverflow.com/a/10460139/1177024

 # app/config/config_test doctrine: dbal: driver: pdo_sqlite path: :memory: memory: true 

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

Надеюсь, это сократит поиск некоторых людей, имеющих ту же проблему! Спасибо всем, кто помогает мне в пути 🙂 Вы здорово!

Попробуйте еще раз с документами symfony.

http://symfony.com/doc/2.0/cookbook/testing/doctrine.html

Или вы можете изменить конструктор TestCase с помощью:

 public function __construct() { $kernelNameClass = $this->getKernelClass(); $kernel = new $kernelNameClass('test', true); $kernel->boot(); $this->em = $kernel->getContainer()->get('doctrine.orm.entity_manager'); } 

Тогда вы будете использовать

 $this->em->createQuery($dql); 

и т.п.

Вы можете подключиться внутри метода setUp() :

 /** * @var \Doctrine\ORM\EntityManager */ private $em; /** * {@inheritDoc} */ public function setUp() { static::$kernel = static::createKernel(); static::$kernel->boot(); $this->em = static::$kernel->getContainer() ->get('doctrine') ->getManager() ; } 

Вот пример из книги Symfony 2.1