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%. Конечно, в лоб это число применять нельзя. Нужно рассматривать каждый случай.
Спасибо. Вы бы это в статье написали ;)

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


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

В Рельсах очень удобно работать с одной базой, миграции решают проблемы с синхронизацией на лету.
Нет рассинхронизации структуры и данных, меньше времени на слияние.
Для пхп аналогичных решений пока не встречал.
О, это как раз то, чего я давно уже ищу!
/me пошел писать шел для cakephp
У нас на прошлом проекте проблема решалась апгрейд скриптами для БД, которые комитились в репозиторий. Если разработчик решал изменить структуру БД, он писал SQL запрос, который меняет базу, ложил в соответствующую папку проекта под именем типа 20080930.001.sql (имена файлов в таком формате, чтоб скрипты потом выполнялись в порядке добавления в репозиторий). После свн апдейта было достаточно запустить скрипт AfterUpdate.cmd, который запускал все новые скрипты и обновлял локальную БД. Скрипты потом использовались и при деплое новой версии проекта заказчикам.
> 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% покрытии всплывает то, что тесты, по сути, дублируют бизнес логику. Например тестирование контроллеров и экшенов. У нас выработалось четкое правило — если хочешь протестировать (не уверен + сложно), сделай сервис/хэлпер/еще-что-то-там.
Only those users with full accounts are able to leave comments. Log in, please.