Symfony Symfony2, функциональные тесты и база данных

keltanas

marty cats
Снова приветствую!

Есть необходимость написать функциональный тест на контроллер, который обновляет некую сущность и сохраняет ее в БД. Например так:
PHP:
namespace Acme\FooBundle\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DefaultControllerTest extends WebTestCase
{
    public function testUpdate()
    {
        $client = static::createClient();
        $crawler = $client->request('PUT', '/foo/1', arrar('name'=>'Vasya'));
        $this->assertTrue($crawler->filter('html:contains("All fine!")')->count() > 0);
    }
}
Ясно, что мы можем проверить ответ, который возвращает контроллер. Но, как протестировать, что он записал в БД?

1. Может стоит вернуть из контроллера в виде json все сохраненные данные и проверять их? Но, нет гарантии, что запись таки произошла?

2. Может надо сделать в тесте запрос из базы и посмотреть, что там находится? Как в таком случае лучше получить объект менеджера доктрины?
И в этом случае тоже не все чисто. Доктрина может вернуть объект из кэша.

3. Еще вопрос. Как можно запускать перед тестами загрузку фикстуры для тестовой БД вместе с --purge-with-truncate?
 

Gas

может по одной?
насколько я понимаю, данный функциональный тест не должен проверять сохранено в базе или нет, а проверить только ответ. Если хочется протестировать доменную логику - юнит тесты используй
 

keltanas

marty cats
насколько я понимаю, данный функциональный тест не должен проверять сохранено в базе или нет, а проверить только ответ. Если хочется протестировать доменную логику - юнит тесты используй
Операция сохранения скорее к функциональному тестированию относится, и уж точно не к модульному. Нужно же контролировать сам факт занесения данных в базу? Или не нужно?
Контроллер может ничего не делать, а просто ответ возвращать. Для тестов он будет рабочий, а на самом деле нет.
 

Вурдалак

Продвинутый новичок
Ну так почему бы не сделать
PHP:
$crawler = $client->request('GET', '/bar/42');
$this->assertTrue($crawler->filter('html:contains("Vasya")')->count() > 0);
 

Вурдалак

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

keltanas

marty cats
Потому что мы можем написать контроллер, который будет просто возвращать нужный ответ. Тесты будут проходить. Но в реальности в контроллере может физически не находится кода работы с доктриной. Понимаешь?
Если следовать философии TDD, то мы должны написать тест, а потом написать метод, который заставляет тест выполнятся (не падать). Собственно, писать код, который сохраняет что-то в БД для этого не обязательно. Тесты будут проходить и без него.
Вот это меня и мучает.
 

Вурдалак

Продвинутый новичок
Ты же не пишешь функциональные тесты с целью проверки того нае*****т обманывают нас или нет? Этим занимаются QA, например. Тесты очень полезны для регрессионного тестирования, к тому моменту там уже весь функционал должен быть.
 
  • Like
Реакции: WMix

keltanas

marty cats
Не согласен.
По крайней мере сейчас я пишу вот такие вот методы, которые по запросу что-то сохраняют в базу. И никак не могу проверить правильность сохранения, нежели как взять, и самому посмотреть, что в базе меняется?
Сижу сам, как QA. А я человек ленивый, и мне хочется, чтобы за меня программа это делала.

А если завтра надо будет добавить еще пару полей для сохранения, как я проверю, что все правильно написал? Опять запускать тест и смотреть тестовую базу, что там изменилось?

Нет, я верю, что доктрина правильно работает. Ну так я могу, например, перепутать при сохранении значения 2х полей (first_name и last_name например), и вроде как никто не умрет, но будет не комфортно. А если надо будет по этим данным в налоговую отчетность сдавать?

В общем, это должно тестироваться. Только пока не нашел решения, как?
 

Вурдалак

Продвинутый новичок
Не, вопрос в том почему ты не сделаешь обычный GET-запрос? Ты не веришь сам себе?
 

Вурдалак

Продвинутый новичок
Твоя красивая REST-архитектура не позволяет получать данные об объекте? Ты добавил Васю. Теперь запроси Васю — в чем проблемы?
 

AmdY

Пью пиво
Команда форума
keltanas
Что такое база данных, зачем она здесь вообще. тебе нужно убедиться что ты можешь извлечь сохранённые данные и что они соответствуют аасертам. Можешь завести отдельный энтити менеджер и таскать данные через него, либо дёргай перед проверкой метод clear дефолтного, но главное - ты работаешь с моделью не думая о базе данных.
 
  • Like
Реакции: WMix

keltanas

marty cats
keltanas
Можешь завести отдельный энтити менеджер и таскать данные через него, либо дёргай перед проверкой метод clear дефолтного, но главное - ты работаешь с моделью не думая о базе данных.
А как правильно получить в тесте экземпляр EntityManager? Там же ни контейнера нету, ни чего-нибудь похожего?
 

Tori

Новичок
Наверное вопрос давно решился... но оставлю пример решения тут.
Код:
<?php
namespace Acme\FooBundle\Tests\Controller;

require_once __DIR__.'/../../../../../app/AppKernel.php';

class DefaultControllerTest \PHPUnit_Framework_TestCase
{
  protected static $kernel;
  protected static $container;

  public static function setUpBeforeClass()
  {
  self::$kernel = new \AppKernel('development', true);
  self::$kernel->boot();

  self::$container = self::$kernel->getContainer();
  }

  public function get($serviceId)
  {
  return self::$kernel->getContainer()->get($serviceId);
  }

....
ваши тесты тут...
....
}
 
Сверху