Pull to refresh

Comments 29

а мы делаем немного по-другому

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

итого каждый тест абсолютно независим от других
Ну мы в целом к тому варианту который вы описали тоже пришли, но потом посоветовались с вышеназванным java-developer и он нам подсказал :)
а что ж у Вас там за запросы которые требуют inmemory базу? night-тестирование сделайте, все спят — оно себе тестирует…

Да не — in memory исключительно для того что бы как можно быстрее пробегали тесты. Подправил код — запустил — если что не так опять подправил — опять запустил и так до тех пор пока не попадешь в зеленую полосу.
А ночью тесты на hudson бегут :), но этого мало
у меня тест с использованием базы выполняется менее секунды. если перевести на инмемори — опять же будет менее секунды. если учесть сколько времени тратится на все остальное, то использование инмемори базы не считаю актуальным лично для себя. и не понимаю зачем оно вам.

хотя статью считаю полезное ибо она показывает альтернативу.
Ну как бы да… in memory не ключевая фишка этого решения :) нам тоже пока не принципиально, но в предшествующих попытках время ожидания было неприемлемым, ну и тесты собственно были реализованы соответственно :)
Не всем же так везёт…

У нас тесты на одной сырой системе проходят за три минуты с гаком.

БД в памяти очень бы помогла. Но пока переводить тесты на такие моки не будем.
В нашем проекте каждый тест выполняется в отдельной транзакции, и программисты избавлены от необходимости следить за созданными объектами и их удалением.
Идея на 5 с плюсом.
Сейчас как раз планирую заняться изучением и применением BDD, TDD в ruby, но и в php было бы хорошо подобную практику перенести. Буду следить за вашими статьями :)
А для reading так разве можно делать:
$result[]['name']
?
PHP говорит FatalError
Опечатка, момент исправлю, спасибо
А почему вы коннекшин создаете в конструкторе, а не в методе getConnection(), как описано в документации. Если думаете, что сэкономите, исплняя конструктор только один раз для всего тест кейса, то вы ошибаетесь — каждый тест исполняеться на новом экземпляре.
Нет я не думал сэкономить. Он создается там с целью что бы можно было создать таблицу persons в базе.
Собственно в таком случае создается ли соединение в конструкторе или в методе — вопрос не принципиальный. А в документации тоже иногда примеры не из жизни бывают :) как собственно пример рассмотренный в статье :)
Внесу свою лепту.

«Проблема фикстур. Не все что берется из базы можно заменить моками.»
Почему это? Что такого есть в базе, чего нельзя описать в модели.
Мы для этих целей используем DDD и принципы построения domain-модели на основе репозиториев и НЕ тестируем поведение слоя, который обращается к базе (ORM).

«Связанно это с некоторой безсистемностью работы с базой.»
Что за бессистемность?

«У нас нет ORM и все функции последнего между делом выполняет модель.»
Модель — это концептуальный блок. Причем тут функции ORM? Очевидно, у вас нет «чистой модели домена» (POCO), модель «знает» о способах хранения ее самой в базе. Но ORM — это всего лишь механизм доступа к базе и превращения реляционных данных в объекты-сущности. Если ваша модель знает об этом, значит в ней так или иначе в каком-либо виде должены быт реализован паттерн Unit Of Work (но зачем, ведь ORM делают это за нас, и позволяют править запросы для оптимизации).

«Скорость прогона тестов. Последняя попытка внедрения захлебнулась
отчасти из-за этого, а отчасти и …
Поддерживаемость. … из-за неподдерживаемости причиной которой
стала проблема из п.1 решая которую мы оснастили наши тесты
многострочными инсертами и апдейтами.»

Уточните немного эти пункты?
Система долгое время (около 3 лет) разрабатывалась абы как. И это тот случай когда Фаулер писал, что лучше переписать заново, но… система в продакшне и функционала тьма и не мы решаем когда переписывать, а когда делать что-то другое.

«Что за бессистемность?»
У нас нет ORM и все функции последнего МЕЖДУ ДЕЛОМ выполняет модель. Между делом — это значит как получилось, без всякого осознанного применения шаблонов.

«Причем тут функции ORM?» «НЕ тестируем поведение слоя, который обращается к базе (ORM).»
Вот при том :) Если бы он у нас был — мы бы могли его замокать — это значительно проще сделать чем замокать абстракцию БД вроде PDO(хотя и последний тоже реально, но неоправданно дорого). А слой который у нас обращается к базе и есть тот слой который просто необходимо тестировать, по причине того что он содержит бизнес логику.

по последнему цитированию:
Написали тесты в которых непосредственно готовили базу к асертам :) потом запутались какие данные какой тест за собой не убрал и забросили это дело.

Вообще все что Вы написали — это все правильно и так и должно быть в ИДЕАЛЕ. И мы рады бы последовать совету Мартина и переписать все, но реальный мир полон заказчиков и клиентов (пользователей сервисов заказчика) и как мы знаем из-за этого далек от идеала :)
Ну как сказать, все делается. Перевод legacy-системы «в TDD» вполне возможен, но тут должен решить тот, кто принимает решения по архитектуре и способам организации проекта.

По поводу бизнес-логики и модели — это уровень BLL или DL (Domain Logic) — он тестируется обязательно.
Остальное — базу и ORM — тестировать не нужно. Мокать их не нужно, а нужно тестировать состояние (а не поведение). Это значительно проще.

Вам реально нужно рассмотреть, как отделить уровень BLL от DAL (Data Access Level). Очень советую потихоньку внедрять DDD в процесс — сильно поможет разделить различные уровни модели. Сама бизнес-логика должна понятия не иметь о том, как она хранится — этим занимается отдельный уровень модели домена — репозитории. В итоге, можно протестировать ВСЮ логику с Fake-репозиториями, которые находятся в памяти. При этом используются тесты состояния — чтобы не «влазить» в то, как репозитории получают данные. А затем, когда все работает, пишете НЕ-Fake репозитории с тем же интерфейсом и используете готовый набор тестов как интеграционные тесты (т.е. они реально будут обращаться к базе в этот момент — но это нам и нужно, мы ведь тестируем интеграцию, тут мокать ничего не надо, а бизнес-логика уже протестирована, преследует все принципы PI (Persistence Ignorance).

Я еще об этом напишу тут на Хабре, когда сделаю статью про то, как мы создавали наш магазин, где использовали все эти методы.
Сегодня 2010-ый, обещание не выполнено :)
Сегодня 2012-ый, обещание не выполнено :)
Хаха, подловили) Ну на самом деле просто руки не дошли еще тогда в 2009м. Интересно, а почему пропустили коммент в 11-м году? :)
Извините, традиция
Хаха, круто) Ну, на самом деле намерение было тогда реально, а сейчас уже столько воды утекло — поменялось и видение, и взгляд на это дело, и подходы. И основной tech-stack.

Так что для меня это такое невыполнимое обещание. Но можете напоминать раз в год :)
2015 год. Господа, не забываем обновлять напоминалки в календаре.
Уже 2016, я внимательно слежу за темой
интересно, как можно быть увереным в работоспособности ORM, не выполняя тестов? (например в результате изменения структуры базы)

ИМХО не тестировать ORM нельзя.
1. ORM протестирована тем, кто ее разрабатывает и поддерживает. Вы принимаете ее, когда уверены в ее работоспособности.

2. У вас тестируется бизнес-логика, которая должна правильно работать и пока тесты срабатывают — все будет ок. Перестать срабатывать они могут в том числе, когда что-то нарушено на уровне DAL.

3. DAL тестируется (!!!) и это важно — вы используете тесты состояния, которые тестируют логику работы репозиториев и заодно являются интеграционными тестами. То есть, пока вы получаете нужные данные, исключения и ответы от DAL уровня — вы уверены, что все работает правильно. Если вы меняете таблицу — и ничего не ломается — все ок. Но если хотите быть уверенными — пишите интеграционные тесты, которые проверяют данные и структуру на целостность (но на практике это зачастую лишнее — вы по сути тестируете не логику, не код, а структуру — но ведь вы таковой ее и создали и если это не ломает логику — все будет ок. Ломается логика — станут красными несколько тестов, ее проверябщих). Так что никаких противоречий я тут не вижу.
Sign up to leave a comment.

Articles