Comments 29
а мы делаем немного по-другому
создан класс который умеет создавать базу данных, наполнять ее и удалять базу данных. создание идет в setUp, каждый тест может наполнить ее теми данными которые ему нужны, протестировать работу, удаление в tearDown.
итого каждый тест абсолютно независим от других
создан класс который умеет создавать базу данных, наполнять ее и удалять базу данных. создание идет в setUp, каждый тест может наполнить ее теми данными которые ему нужны, протестировать работу, удаление в tearDown.
итого каждый тест абсолютно независим от других
Ну мы в целом к тому варианту который вы описали тоже пришли, но потом посоветовались с вышеназванным java-developer и он нам подсказал :)
а что ж у Вас там за запросы которые требуют inmemory базу? night-тестирование сделайте, все спят — оно себе тестирует…
Да не — in memory исключительно для того что бы как можно быстрее пробегали тесты. Подправил код — запустил — если что не так опять подправил — опять запустил и так до тех пор пока не попадешь в зеленую полосу.
А ночью тесты на hudson бегут :), но этого мало
А ночью тесты на hudson бегут :), но этого мало
у меня тест с использованием базы выполняется менее секунды. если перевести на инмемори — опять же будет менее секунды. если учесть сколько времени тратится на все остальное, то использование инмемори базы не считаю актуальным лично для себя. и не понимаю зачем оно вам.
хотя статью считаю полезное ибо она показывает альтернативу.
хотя статью считаю полезное ибо она показывает альтернативу.
Ну как бы да… in memory не ключевая фишка этого решения :) нам тоже пока не принципиально, но в предшествующих попытках время ожидания было неприемлемым, ну и тесты собственно были реализованы соответственно :)
Не всем же так везёт…
У нас тесты на одной сырой системе проходят за три минуты с гаком.
БД в памяти очень бы помогла. Но пока переводить тесты на такие моки не будем.
У нас тесты на одной сырой системе проходят за три минуты с гаком.
БД в памяти очень бы помогла. Но пока переводить тесты на такие моки не будем.
В нашем проекте каждый тест выполняется в отдельной транзакции, и программисты избавлены от необходимости следить за созданными объектами и их удалением.
Сейчас как раз планирую заняться изучением и применением BDD, TDD в ruby, но и в php было бы хорошо подобную практику перенести. Буду следить за вашими статьями :)
А для reading так разве можно делать:
$result[]['name']
?
PHP говорит FatalError
$result[]['name']
?
PHP говорит FatalError
А почему вы коннекшин создаете в конструкторе, а не в методе getConnection(), как описано в документации. Если думаете, что сэкономите, исплняя конструктор только один раз для всего тест кейса, то вы ошибаетесь — каждый тест исполняеться на новом экземпляре.
Нет я не думал сэкономить. Он создается там с целью что бы можно было создать таблицу persons в базе.
Собственно в таком случае создается ли соединение в конструкторе или в методе — вопрос не принципиальный. А в документации тоже иногда примеры не из жизни бывают :) как собственно пример рассмотренный в статье :)
Собственно в таком случае создается ли соединение в конструкторе или в методе — вопрос не принципиальный. А в документации тоже иногда примеры не из жизни бывают :) как собственно пример рассмотренный в статье :)
Внесу свою лепту.
Внесу свою лепту.
«Проблема фикстур. Не все что берется из базы можно заменить моками.»
Почему это? Что такого есть в базе, чего нельзя описать в модели.
Мы для этих целей используем DDD и принципы построения domain-модели на основе репозиториев и НЕ тестируем поведение слоя, который обращается к базе (ORM).
«Связанно это с некоторой безсистемностью работы с базой.»
Что за бессистемность?
«У нас нет ORM и все функции последнего между делом выполняет модель.»
Модель — это концептуальный блок. Причем тут функции ORM? Очевидно, у вас нет «чистой модели домена» (POCO), модель «знает» о способах хранения ее самой в базе. Но ORM — это всего лишь механизм доступа к базе и превращения реляционных данных в объекты-сущности. Если ваша модель знает об этом, значит в ней так или иначе в каком-либо виде должены быт реализован паттерн Unit Of Work (но зачем, ведь ORM делают это за нас, и позволяют править запросы для оптимизации).
«Скорость прогона тестов. Последняя попытка внедрения захлебнулась
отчасти из-за этого, а отчасти и …
Поддерживаемость. … из-за неподдерживаемости причиной которой
стала проблема из п.1 решая которую мы оснастили наши тесты
многострочными инсертами и апдейтами.»
Уточните немного эти пункты?
«Проблема фикстур. Не все что берется из базы можно заменить моками.»
Почему это? Что такого есть в базе, чего нельзя описать в модели.
Мы для этих целей используем DDD и принципы построения domain-модели на основе репозиториев и НЕ тестируем поведение слоя, который обращается к базе (ORM).
«Связанно это с некоторой безсистемностью работы с базой.»
Что за бессистемность?
«У нас нет ORM и все функции последнего между делом выполняет модель.»
Модель — это концептуальный блок. Причем тут функции ORM? Очевидно, у вас нет «чистой модели домена» (POCO), модель «знает» о способах хранения ее самой в базе. Но ORM — это всего лишь механизм доступа к базе и превращения реляционных данных в объекты-сущности. Если ваша модель знает об этом, значит в ней так или иначе в каком-либо виде должены быт реализован паттерн Unit Of Work (но зачем, ведь ORM делают это за нас, и позволяют править запросы для оптимизации).
«Скорость прогона тестов. Последняя попытка внедрения захлебнулась
отчасти из-за этого, а отчасти и …
Поддерживаемость. … из-за неподдерживаемости причиной которой
стала проблема из п.1 решая которую мы оснастили наши тесты
многострочными инсертами и апдейтами.»
Уточните немного эти пункты?
Система долгое время (около 3 лет) разрабатывалась абы как. И это тот случай когда Фаулер писал, что лучше переписать заново, но… система в продакшне и функционала тьма и не мы решаем когда переписывать, а когда делать что-то другое.
«Что за бессистемность?»
У нас нет ORM и все функции последнего МЕЖДУ ДЕЛОМ выполняет модель. Между делом — это значит как получилось, без всякого осознанного применения шаблонов.
«Причем тут функции ORM?» «НЕ тестируем поведение слоя, который обращается к базе (ORM).»
Вот при том :) Если бы он у нас был — мы бы могли его замокать — это значительно проще сделать чем замокать абстракцию БД вроде PDO(хотя и последний тоже реально, но неоправданно дорого). А слой который у нас обращается к базе и есть тот слой который просто необходимо тестировать, по причине того что он содержит бизнес логику.
по последнему цитированию:
Написали тесты в которых непосредственно готовили базу к асертам :) потом запутались какие данные какой тест за собой не убрал и забросили это дело.
Вообще все что Вы написали — это все правильно и так и должно быть в ИДЕАЛЕ. И мы рады бы последовать совету Мартина и переписать все, но реальный мир полон заказчиков и клиентов (пользователей сервисов заказчика) и как мы знаем из-за этого далек от идеала :)
«Что за бессистемность?»
У нас нет ORM и все функции последнего МЕЖДУ ДЕЛОМ выполняет модель. Между делом — это значит как получилось, без всякого осознанного применения шаблонов.
«Причем тут функции ORM?» «НЕ тестируем поведение слоя, который обращается к базе (ORM).»
Вот при том :) Если бы он у нас был — мы бы могли его замокать — это значительно проще сделать чем замокать абстракцию БД вроде PDO(хотя и последний тоже реально, но неоправданно дорого). А слой который у нас обращается к базе и есть тот слой который просто необходимо тестировать, по причине того что он содержит бизнес логику.
по последнему цитированию:
Написали тесты в которых непосредственно готовили базу к асертам :) потом запутались какие данные какой тест за собой не убрал и забросили это дело.
Вообще все что Вы написали — это все правильно и так и должно быть в ИДЕАЛЕ. И мы рады бы последовать совету Мартина и переписать все, но реальный мир полон заказчиков и клиентов (пользователей сервисов заказчика) и как мы знаем из-за этого далек от идеала :)
Ну как сказать, все делается. Перевод legacy-системы «в TDD» вполне возможен, но тут должен решить тот, кто принимает решения по архитектуре и способам организации проекта.
По поводу бизнес-логики и модели — это уровень BLL или DL (Domain Logic) — он тестируется обязательно.
Остальное — базу и ORM — тестировать не нужно. Мокать их не нужно, а нужно тестировать состояние (а не поведение). Это значительно проще.
Вам реально нужно рассмотреть, как отделить уровень BLL от DAL (Data Access Level). Очень советую потихоньку внедрять DDD в процесс — сильно поможет разделить различные уровни модели. Сама бизнес-логика должна понятия не иметь о том, как она хранится — этим занимается отдельный уровень модели домена — репозитории. В итоге, можно протестировать ВСЮ логику с Fake-репозиториями, которые находятся в памяти. При этом используются тесты состояния — чтобы не «влазить» в то, как репозитории получают данные. А затем, когда все работает, пишете НЕ-Fake репозитории с тем же интерфейсом и используете готовый набор тестов как интеграционные тесты (т.е. они реально будут обращаться к базе в этот момент — но это нам и нужно, мы ведь тестируем интеграцию, тут мокать ничего не надо, а бизнес-логика уже протестирована, преследует все принципы PI (Persistence Ignorance).
Я еще об этом напишу тут на Хабре, когда сделаю статью про то, как мы создавали наш магазин, где использовали все эти методы.
По поводу бизнес-логики и модели — это уровень BLL или DL (Domain Logic) — он тестируется обязательно.
Остальное — базу и ORM — тестировать не нужно. Мокать их не нужно, а нужно тестировать состояние (а не поведение). Это значительно проще.
Вам реально нужно рассмотреть, как отделить уровень BLL от DAL (Data Access Level). Очень советую потихоньку внедрять DDD в процесс — сильно поможет разделить различные уровни модели. Сама бизнес-логика должна понятия не иметь о том, как она хранится — этим занимается отдельный уровень модели домена — репозитории. В итоге, можно протестировать ВСЮ логику с Fake-репозиториями, которые находятся в памяти. При этом используются тесты состояния — чтобы не «влазить» в то, как репозитории получают данные. А затем, когда все работает, пишете НЕ-Fake репозитории с тем же интерфейсом и используете готовый набор тестов как интеграционные тесты (т.е. они реально будут обращаться к базе в этот момент — но это нам и нужно, мы ведь тестируем интеграцию, тут мокать ничего не надо, а бизнес-логика уже протестирована, преследует все принципы PI (Persistence Ignorance).
Я еще об этом напишу тут на Хабре, когда сделаю статью про то, как мы создавали наш магазин, где использовали все эти методы.
Сегодня 2010-ый, обещание не выполнено :)
Сегодня 2012-ый, обещание не выполнено :)
Сегодня 2013-ый, обещание не выполнено :)
Сегодня 2014…
2015 год. Господа, не забываем обновлять напоминалки в календаре.
Уже 2016, я внимательно слежу за темой
интересно, как можно быть увереным в работоспособности ORM, не выполняя тестов? (например в результате изменения структуры базы)
ИМХО не тестировать ORM нельзя.
ИМХО не тестировать ORM нельзя.
1. ORM протестирована тем, кто ее разрабатывает и поддерживает. Вы принимаете ее, когда уверены в ее работоспособности.
2. У вас тестируется бизнес-логика, которая должна правильно работать и пока тесты срабатывают — все будет ок. Перестать срабатывать они могут в том числе, когда что-то нарушено на уровне DAL.
3. DAL тестируется (!!!) и это важно — вы используете тесты состояния, которые тестируют логику работы репозиториев и заодно являются интеграционными тестами. То есть, пока вы получаете нужные данные, исключения и ответы от DAL уровня — вы уверены, что все работает правильно. Если вы меняете таблицу — и ничего не ломается — все ок. Но если хотите быть уверенными — пишите интеграционные тесты, которые проверяют данные и структуру на целостность (но на практике это зачастую лишнее — вы по сути тестируете не логику, не код, а структуру — но ведь вы таковой ее и создали и если это не ломает логику — все будет ок. Ломается логика — станут красными несколько тестов, ее проверябщих). Так что никаких противоречий я тут не вижу.
2. У вас тестируется бизнес-логика, которая должна правильно работать и пока тесты срабатывают — все будет ок. Перестать срабатывать они могут в том числе, когда что-то нарушено на уровне DAL.
3. DAL тестируется (!!!) и это важно — вы используете тесты состояния, которые тестируют логику работы репозиториев и заодно являются интеграционными тестами. То есть, пока вы получаете нужные данные, исключения и ответы от DAL уровня — вы уверены, что все работает правильно. Если вы меняете таблицу — и ничего не ломается — все ок. Но если хотите быть уверенными — пишите интеграционные тесты, которые проверяют данные и структуру на целостность (но на практике это зачастую лишнее — вы по сути тестируете не логику, не код, а структуру — но ведь вы таковой ее и создали и если это не ломает логику — все будет ок. Ломается логика — станут красными несколько тестов, ее проверябщих). Так что никаких противоречий я тут не вижу.
Sign up to leave a comment.
PHPUnit и его Database Extension. Беглый взгляд