krivochenko
@krivochenko
Программист Yii Framework

Как правильно писать тесты для приложения на Yii2?

Всем доброго времени суток. Есть сложности с пониманием того, что нужно тестировать с помощью различного вида тестов. Сложности порождают различные классификации тестов, встречающиеся в Интернете. Где-то можно встретить фразы "функциональные/приёмочные", где-то "функциональные/интеграционные".

Если взглянуть на тесты, которые идут с yii2-advanced и yii2-basic, встаёт вопрос, зачем, при наличии acceptance, нужны functional. По сути они просто проверяют наличие определённых строк в ответах сервера. В приёмочных тестах можно делать то же самое, да ещё и с возможностью указывать CSS-селекторы для строк, наличие которых необходимо проверить.

Дополнительные вопросы порождает статья. В Yii даже банальное
$model = \Mockery::mock(News::className())->shouldReceive('save')->once()->andReturn(true)->getMock();
$model->title = 'Первый пост';

порождает запрос к базе данных, для получения структуры таблицы news. "ЗамОчить" все обращения к базе, я так понимаю, не удастся. Тем более так, чтобы тесты сохранили читаемый вид. Что в этом случае остаётся тестировать с помощью модульных тестов?

В указанной выше статье автор называет тесты, в работе которых присутствует взаимодействие с базой данных, интеграционными. В шаблонах yii2-advanced и yii2-basic есть unit, functional, acceptance. Стоит выделить отдельную группу тестов - integration?

По сумме всего вышесказанного, складывается ощущение, что integration==functional, и к этим тестам относятся всё же не те, что идут в шаблонах приложений Yii2. В моём понимании интеграционные тесты должны, как и модульные, тестировать отдельные методы классов, но уже без всяких моков, а с использованием базы данных, заполняемой через фикстуры. На сколько я прав?

Всем спасибо за ответы.

UPD:
Допустим, у модели есть метод:
public function setSuccessStatus()
{
    $this->status = self::STATUS_SUCCESS;
    return $this->save();
}


В тесте этого метода убедимся, что он задаёт верный статус модели:
public function testSetSuccessStatus()
{
    $post = $this->getMockBuilder('\app\model\Post')->setMethods(['save'])->getMock();
    $post->method('save')->willReturn(true);
    $post->setSuccessStatus();
    $this->assertEquals($post->status, Post::STATUS_SUCCESS);
}


Сохранение модели мы заглушили, но при обращении $post->status тест полезет в базу, чтобы узнать, есть ли в ней поле status. Я что-то не верно понял?
  • Вопрос задан
  • 1700 просмотров
Решения вопроса 1
SamDark
@SamDark
Yii2 core team
В Yii даже банальное ... порождает запрос к базе данных, для получения структуры таблицы news.


Смокать вполне реально. Не знаю, как через Mockery, но через PHPUnit у меня вполне получалось.

В шаблонах yii2-advanced и yii2-basic есть unit, functional, acceptance. Стоит выделить отдельную группу тестов - integration?

Это название означает, что тесты не строго модульные. Реализованы они могут быть тем же PHPUnit.

integration==functional

Нет. integration = тестирует реальную базу, но всё ещё в терминах кода. functional = тестирует в терминах конечного пользователя: страницы, URL-ы, парсинг тела ответа. При этом реальный браузер не запускается. acceptance = то же, но с реальным браузером.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы