Pull to refresh

Comments 43

Вы говорите как делать, но не говорите почему выбрали именно этот способ. Такие Инструкции, на мой взгляд, понятны только тем, кто это все уже давно знает и применяет на практике.
Я делюсь с хабрасообществом лучшей практикой из своего личного опыта. Для того чтобы рассказать все в деталях, придется написать книгу =) Если есть вопросы «почему» — задавайте в комментах или в хабрапочте.
А вы не могли бы написать обзор инструментов для операций внедрения, отката и, возможно, тестирования?
Для внедрения/отката подойдет Apache Ant, CruiseControl не зависимо от того на чем разрабатываете. Автоматизация тестирования — любой удобный вам Unit-фреймворк, Selenium (ацкая хрень, сжирает кучу времени). Это что первое приходит в голову.

А вообще, специализированные инструменты для этих операций нужно использовать, если у вас действительно большой проект и много участников. Для простых проектов достаточно ручных операций с svn и стандартных системных утилит.
Во время ручных операций иногда происходят достаточно серьезные ошибки, поэтому хочется более ли менее автоматизированную систему. Спасибо.
кстати селениум не такой уж ацкий ) дело в том, что сам по себе он является лишь фреймворком, и для эффективного его использования на его основе необходимо создавать специальный отточенный инструмент, направленнный на скорость разработки тестов. готовых решений нет, на что-то более-менее близкое похож bromine, но он крив, и развивать его будут, судя по всему, очень очень медленно
Selenium, надо отметить — это функциональное тестирование.
А CruiseControl.NET мы используем для .NET. То же самое касается NAnt и NCover, у которых есть аналоги — Ant и Cover.
Кстати, еще популярным CI-сервером становится TeamCity в последнее время…
их реализация не должна отнимать больше 20% рабочего времени. Разрабатывать через тестирование – крайняя степень расточительства.

очень спорное утверждение, думаю стоит остановиться на «Разработка автотестов не всегда оправдана.»
Останавливайтесь на здоровье=) А я, пожалуй, не буду.
Все зависит от масштабов проекта. Если вы пишете сложную систему с навороченной бизнес-логикой и используете паттерн MVC (возможно MVP или нечто аналогично заранее ориентированное на юнит-тесты), то Test Driven Development сэкономит вам кучу времени, нервов и, как следствие, денег на разработку и тестирование. Если код покрыт тестами хотя бы на 80-90% и подключена система автоматического тестирования каждой ревизии проекта в репозитории, практически любая ошибка в бизнес-логике отлавливается на протяжении часа.
А не подскажете где бы подробней, с примерами посмотреть про автоматическое тестирование применительно к разработке web-приложений? Поискал — всюду общие слова, и ноль конкретики, типа «пишите набор тестов и будьте счастливы». Хотелось бы посмотреть поближе как это делается.
Вот статья на тему:
cylib.iit.nau.edu.ua/Books/ComputerScience/PhilosophyProblem/xprogramming.ru/Articles/LoveUT.html
Вкратце, тестировать нужно каждую функцию проекта (не в смысле «метод», а в смысле «действие»). К примеру мне приходилось работать с системой документооборота, в которой обрабатывались документы типа таможенных деклараций. Для декларации существовала определенная иерархия состояний, которые определяли набор действий, которые можно совершать над декларацией. Например, в состоянии Created автор декларации может вносить изменения в ее наполенение, но декларация не отображается в списке на проверку и ее нельзя заапрувить. В то же время, в состоянии Finalized ее можно заапрувить, но редактировать нельзя. Собственно для проверки соответствия состояний и разрешенных действий был написан юнит тест, который падал, если кто-либо внес изменения в вышеописанную логику.
На примере хабра можно было бы написать тест, который проверяет, что может делать юзер с отрицательным значением кармы, тест, который проверяет, скрывается ли сильно заминусованый коментарий и т. д. и т. п.
sun и microsoft проводили исследования, которые показали что замедляя на старте технология позволяет ускорить процесс разработки в целом. навскидку насколько быстрее становится разработка при разработке через тестирование, можете погуглить. если написание тестов займёт >20% процентов времени, то во сколько выльется поиск бага в нетестируемом коде. другое дело что необязательно облаживать тестами обсолютно каждый пук.
Вот именно! 20% — это просто провокационное число, которое заставит задуматься о затратах.
Примерно так же, как и любое другое число, например, 42. Для меня TDD ценно хотя бы тем, что я не боюсь что-то сломать. А уж как тут эти процентики мерять вообще непонятно.
Это был сарказм, 20% получено из практики — когда-то потребовалась это число, теперь пользуюсь. Измерялось примерно так: взял старые планы (свои и чужие), оценил объем плановых работ «Разработка автотестов», оценил потраченные по факту. Убрал те проекты, которые не смогли поддерживать изначальное покрытие тестами. Убрал те проекты, чьи качество существенно снизилось в ходе эксплуатации. Остались те, у которых соотношение разработки тестов к разработке функционала был 15%-25%. Конечно, в лоб это число применять нельзя. Нужно рассматривать каждый случай.
Спасибо. Вы бы это в статье написали ;)

ЗЫ: Только это, ИМХО, средняя температура по больнице.
Приложение каждого разработчика должно использовать персональные БД и файловые хранилища.


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

В Рельсах очень удобно работать с одной базой, миграции решают проблемы с синхронизацией на лету.
Нет рассинхронизации структуры и данных, меньше времени на слияние.
Для пхп аналогичных решений пока не встречал.
Посмотрите LiquiBase, вам понравится
О, это как раз то, чего я давно уже ищу!
/me пошел писать шел для cakephp
У нас на прошлом проекте проблема решалась апгрейд скриптами для БД, которые комитились в репозиторий. Если разработчик решал изменить структуру БД, он писал SQL запрос, который меняет базу, ложил в соответствующую папку проекта под именем типа 20080930.001.sql (имена файлов в таком формате, чтоб скрипты потом выполнялись в порядке добавления в репозиторий). После свн апдейта было достаточно запустить скрипт AfterUpdate.cmd, который запускал все новые скрипты и обновлял локальную БД. Скрипты потом использовались и при деплое новой версии проекта заказчикам.
Посмотрите LiquiBase, вам понравится
В symfony вся Схема базы данных хранится в файле schema.yml или schema.xml, Изменения БД очень просто отслеживать через SVN.
Плагин www.symfony-project.org/plugins/sfPropelSqlDiffPlugin генерирует ALTER TABLE автоматически.

Также можно использовать Миграции Doctrine
www.doctrine-project.org/blog/new-to-migrations-in-1-1
> user@stable:~/httpdocs/ $ rm pro && ln –s ../apps/myproject/rel_0.5.2.1 pro

Непрофессионально: если между двумя действиями случится запрос — юзер увидит ошибку. Надо переименовывать symlink, это атомарно.
Спасибо за замечание. Но суть я надеюсь все уловили.
вы пренебрегаете необходимостью тестов — значит не работали с живыми деньгами, которые приносят пользователи и тратят на вашем сервисе. если работали — горе вам и вашим проектам. кроме того, release candidate и проведение приемочного тестирования людьми на любую типографическую ошибку — это из разряда фантастики. для таких ошибок должен существовать механизм quick-fix. он же поможет, когда сервер обваливается и правки делаются на живой релизной машине (потому что пока вы развернете еще одну версию, проверите все и запустите ее — у вас может не остаться ни одного пользователя).

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

то же самое касается указанного вами идеального случая с возможностью поддержки в старом релизе новой схемы. с учетом того, как вы об этом рассказали, это невозможно. поэтому нужно не тратить время и деньги и не поддерживать старый код новой схемой — это часто слишком накладно.

поэтому, перед выкладкой новой версии сервис полностью останавливается (с показом maintenance mode — пользователи нормально относятся к нему, а вот к ошибкам — не очень), все данные и базы бэкапятся, также бэкапятся библиотеки (в том числе и системные, от которых проект зависит) и только тогда начинаем выкатывать новую версию проекта.

хранение всяких файлов (userdata) отдельно от проекта тоже выдает в вас не очень опытного разработчика — формат самих файлов может меняться. и это значит, что пользовательские файлы обязаны быть частью текущей версии и частью директории проекта. то есть для их обновления нужно скопировать старые файлы в новую директорию и запустить скрипт обновления.

«…проект инсталлируется (настраиваются конфиги, права, стартовые данные) и тестируется рядом с работающим релизом…» — просто чудовищно. все конфигурации, права, стартовые данные обязаны уже быть в файлах инсталляции боевого сервера. если вы не можете поднять новый сервер одной командой или у вас есть на сервере несохраненная конфигурация — ждите беды, когда важный файлик потрется, которого у вас не было нигде, кроме как в рабочей инсталляции.
Ну вот правда, не хотелось вступать в полемику, максимум ответить на вопросы по своей точке зрения. Но тут человек старался, столько много написал про мое разоблачение… Придется тоже что-нибудь ответить.

вы пренебрегаете необходимостью тестов

Я считаю, что тесты — необходимость. Не знаю, где вы вычитали что я ими пренебрегаю. Тесты позволяют разработчику сдать проект в приемочное тестирование в нормальном состоянии. Делать же оценку качества по автотестам нельзя. Говоря о верхней планке затрат, я затрагиваю две проблемы. Первая — тесты, это тоже код, который пишут люди, а значит оттуда растут баги. Вторая — в своем стремлении создать идеальную систему разработчики настолько тверды, что готовы потратить громадное количество времени на покрытие кода тестами. Но реальная потребность покрытия тестами возникает только в важных и серьезных местах приложения. Менеджеры, которые вписывают громадные затраты на работы класса «Разработка unit-тестов», либо не умеют считать деньги, либо доверчивые идиоты, либо искусственно завышают бюджет.

кроме того, release candidate и проведение приемочного тестирования людьми на любую типографическую ошибку

Говорите какие-то глупости, о чем вообще не было написано.

для таких ошибок должен существовать механизм quick-fix

Чтобы делать quick-fix, нужно еще найти корень зла, на что уйдет больше времени, чем сделать мгновенный откат до предыдущей версии — переключить контекст веб-сервера на предыдущий релиз.

никогда нельзя выкатывать и проверять инсталляцию на машину

Гораздо круче все застопить, запустить новый процесс и посмотреть что получится — заведется или не заведется?

перед выкладкой новой версии сервис полностью останавливается

Расскажите об этом ребятам из любого высоконагруженного проекта (Яндекс, Рамблер, РБК). Подсчитывать бабло и смеятся будем все вместе.

пользовательские файлы обязаны быть частью текущей версии и частью директории проекта

Расскажите об этом ребятам из фотофайла или любого видеосервиса. Будет в два раза смешней!

Как- то так. Про остальное глупо писать — человек просто не понял сути. Либо я дал слишком мало информации о приемах.
соглашусь, про тесты не совсем внимательно прочитал

«Говорите какие-то глупости, о чем вообще не было написано.»
«Релиз-кандидат – это конечный монолитный продукт, в который нельзя вносить изменения. Если необходимо исправить ошибки, доработать функционал – необходимо начинать с начала и делать нового кандидата.»
«Чтобы делать quick-fix, нужно еще найти корень зла, на что уйдет больше времени, чем сделать мгновенный откат до предыдущей версии — переключить контекст веб-сервера на предыдущий релиз.»

всегда есть ситуации, когда типографическая ошибка или неверное условие работают правильно до тех пор, пока не встретится условие, вскрывающее проблему. по этому принципу работают же и sql инъекции. для множества таких ситуаций есть возможность быстро исправить ситуацию. и нужно иметь возможность быстро ее исправить.

«Гораздо круче все застопить, запустить новый процесс и посмотреть что получится — заведется или не заведется?»

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

«Расскажите об этом ребятам из любого высоконагруженного проекта (Яндекс, Рамблер, РБК). Подсчитывать бабло и смеятся будем все вместе.»

да, давайте посмеемся. я работал в яндексе и выкладывал код на главную страницу яндекса. яндекс, рбк, фотофайл и тому подобные сервисы сильно вырождены и сегментированы — они выполняют одну функцию и на нее заточены. большинство сетевых мультисервисов имеют в своем основании сразу множество функций. и до тех пор, пока сервис не вырождается в функцию, имеет смысл позаботиться о сохранности (и копировании) данных.
Реально, в этом то и проблема, что проекты медиа-холдингов жутко сегментированы. Зачастую, внедрения сателлитных систем, переплетенных со всем наборов веб-проектов, происходят самостоятельно. Именно поэтому необходимы тесты на интеграцию при внедрении, именно поэтому цена работоспособности маленького субпроекта Яндекса выше, чем цена работоспособности модуля нишевого веб-проекта.
> Разработка автотестов не всегда оправдана: их реализация не должна отнимать больше 20% рабочего времени. Разрабатывать через тестирование – крайняя степень расточительства.

Можно подробнее, почему TDD — это крайняя степень расточительства?
Здесь habrahabr.ru/blogs/webdev/43643/#comment_1084963 я ответил человеку про проблемы модульного тестирования и почему я предлагаю рамки.

За свою практику я манагерил 3 веб-проекта в соответствии с TDD — все провалились по одной и той же причине: на сопровождение (актуализацию) пространства тестов требовалось слишком много времени. В итоге, все 3 проекта разного размера (Java, Java, PHP), сделанные разными командами, перешли в классическую схему — частично покрытый тестами код. Веб-проекты требуют слишком частых и значительных изменений =(

И хотелось бы предостеречь от неправильных выводов — все вышесказанное относится только к веб-проектам. Я сам — экс-фанат методологии TDD. Возможно, TDD оправдан в разработке банковским систем или систем автоматического управления поездами метро. Но я лично пока не нашел TDD практического применения.
Шикарно, спасибо большое. Мне, как чайнику в этих делах, статья очень помогла разобраться с вопросом.
Вас также хочется предостеречь. Описанное в хабратопике — не панацея. Это всего лишь срез наилучшего, что я видел за 8 лет в разработке веб-проектов и применял на практике. Импровизируйте, делайте свои уникальные солюшены для своих проектов. Если у вас есть сомнения по поводу написанного — это даже лучше!
по поводу «необходимо контролировать версии библиотек сторонних разработчиков. Чтобы быть уверенным, что в бою используется поддерживаемая версия библиотеки Zend Framework, необходимо либо включить библиотеку в структуру папок приложения (и держать ее в svn)»…

Рекомендую к прочтению тем, кто использует Subversion: Externals definitions. Цитата: «An externals definition is a mapping of a local directory to the URL—and possibly a particular revision—of a versioned resource»
спасибо за статью, очень полезно и доступно!
Классная статья. Только вот несходяться ваши взгляды с опытом легендарных гуру (Фаулер, Поль Дюваль), насчет непрерывной интеграции и разработкой путем тестирования
Это нормально, ибо сферы разные. Веб очень часто меняется, тут при 100% покрытии всплывает то, что тесты, по сути, дублируют бизнес логику. Например тестирование контроллеров и экшенов. У нас выработалось четкое правило — если хочешь протестировать (не уверен + сложно), сделай сервис/хэлпер/еще-что-то-там.
а кнопу «в избранное» создатели сайта сделать забыли что-ли?
Sign up to leave a comment.

Articles