Обновить
57
1.8

Пользователь

Отправить сообщение
у меня есть несколько opensource проектов на github — включил в резюме ссылку, и теперь не страдаю подобной фигней. :)

если серьёзно, не знаю можно-ли обобщать этот рецепт. когда текущий работодатель предложил сделать тестовое задание, настоял посмотреть реальный код, с полной ретроспективой коммитов — вместо этой ерунды. а вот прокатит-ли такое с монстрами типа яндекса? (кстати, вопрос :) ).
можно торговаться: или тестовое задание, или испытательный срок.
у меня TDD ассоциируется с en.wikipedia.org/wiki/Design_by_contract, только «вывернутым наизнанку». в обоих случаях спецификации описываются в виде пред- и пост- условий, с использованием предикатных выражений:

«assert value == false» или «value should be false», — не суть.

но в TDD система описывается «снаружи» (ака черный ящик), а в DbC — «изнутри».

BDD же отражает другой аспект — императив — т.е. требования к поведению — «в динамике». какие действия и в какой последовательности нужно делать. часто это тоже важно:

Given…

When I go google.com
And I see search field
And I type «wtf BDD»


Then…

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

термины юнит/функциональные/интеграционные тесты отражают ортогональный — системный — аспект. те же юнит тесты можно записывать и в стиле bdd и в стиле tdd — всё зависит от типа требований.
Никакого особого продумывания для классического mvc-веб-приложения не требуется

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

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

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

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

— эй, вася, что ты такое пишешь?
— еще не знаю, щаз скомпилирую, узнаю.

самое сложное при внедрении TDD это ломка программистского стереотипа: сначала быстро «накодить», ведь и так все ясно, а потом думать зачем, для чего, и исправлять ошибки. :)

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

Если смотреть со стороны управления конфигурациями проекта, то ветвление это средство, а vcs — инструмент. От vcs нужна возможность работы с бранчами, а распределенность не играет большой роли. Просто так получается, что в распределенных управление бранчами реализовано лучше. scm-notes.blogspot.com/2010/09/branch-per-task-workflow-explained.html.
Андрей, Ваши требования соблюдены во всех случаях:
Правила очень просты. Вы пишите, какую работу готовы выполнить за 1000 яндекс.рублей, мы оговариваем все детали тут, у всех на виду, и в случае согласия я сразу перевожу деньги на ваш счет, ожидая в оговоренный срок получить выполненную работу. Или обмануть меня, разбогатев на 1000 рублей и испортить свою карму (настоящую).

работа описана, детали оговорены у всех на виду, деньги переведены, ожидаение выполенной работы в оговоренный срок вы получили.

мне кажется здесь пример заказчика, который в начале не знает, что ему нужно, а в конце получает не то, что теперь хочет. ;)
Сегодня столкнулся с чудесным багом в 10.10: файл, сохраняемый на подмонтированный сервер, обрезается до 0. Уже есть патч, портированный из федоры, но пакетов ещё нет. Будьте внимательны, если пользуетесь «Соединиться с сервером».
автоэкранирование в шаблонах, например.

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

а view-функции из другой области. они предназначены для обработки http запросов. поэтому было бы просто замечательно, если бы django предоставляла аналогичные средства, так же упрощающие поддержку семантики этого протокола (в понимании rfc2616)…

в реальности все совершенно иначе. view-фукнция является точкой входа для обработки любого запроса к данному URI. и вся мудреная логика формирования ответа целиком лежит на совести пользовательского кода (в том числе соответствие ответа типу сообщения GET, POST, PUT, ..). заморчки с диспетчеризацией данных для формы, по типу запроса, это прямое следствие джанговской архитектуры. вот решение этой задачи (на что сейчас все прикладники кладут, по понятным причинам) было бы приятно видеть на уровне фреймворка. сравните:

# первая попавшаяся под руку хрень -)
$ curl -svX PUT msdn.microsoft.com/ru-ru/default.aspx > /dev/null
(HTTP/1.1 411 Length Required)

# django
$ curl -svX PUT docs.djangoproject.com/en/1.2/ > /dev/null
(HTTP/1.0 200 OK)

впрочем, не так давно, появилась определенная надежда на class-based views, ожидаемые в следующем релизе. они могли бы предоставлять нужный функционал по умолчанию… (правда это нехилый такой лисапед — классная реализация уже давно есть в django-piston).

а csrf это вообще фича уровня протокола приложения. в contrib ей самое место. :)

в принципе, я понял Вашу точку зрения, но принять не могу. :)
какие именно проблемы? я пока вижу только одну проблему — в пресловутом сниппете нужно учитывать массу плохо контролируемых нюансов внешней среды (csrf, содержание html-формы, ajax, возможности http-клиента). а это чревато появлением ошибок на этапе развития проекта (отключив csrf вы рискуете уронить бизнес-логику).

учите писать правильно, а не экономить строчки кода. даже если «все под контролем». :)

csrf же это не «наука», а инженерное решение, которое имеет вполне конкретную область применимости: работает только для html-форм, требует поддержку кук от браузера. (кстати, именно из-за привязанности к кукам, csrf не обеспечивает защиту на под-доменах). полезная штука, в своей нише, и не нужная во всех остальных случаях. не понимаю, ради чего его вытащили из contrib в core и переворотили четверть джанги. )

«общий случай», где используются Forms (кстати, намеренно абстрагированные от request) — гораздо шире. forms часто используются для обработки данных, полученных через ajax — здесь csrf бесполезен, в принципе (кстати, и не обрабатывается django); с помощью forms удобно делать валидацию при создании api сайта. здесь csrf так же не нужен…
Я согласен с Иваном, в том плане, что @render_to скорее вреден, чем полезен. Хотя в django и есть аналогичная безделушка, в api шаблонизатора simple_tag

Но в общем случае, декораторы часто используются в качестве адаптеров, поэтому отличие сигнатуры декорируемой функции это не аргумент. :)
Если после этого сразу непонятно, как работает код ContactForm(request.POST or None), то разберитесь в качестве упражнения, расписывать не буду. Это простая и полезная идиома.

я с вами согласен в том плане, что описание контроллеров для форм, своей однотипностью и многословностью вызывает уныние. но делать так, как вы предлагаете, тоже нельзя. :)

если контоллерная логика такая же простая как в примере — используйте create-update-delete-generic-views — будет еще короче. :)

ваш же код это грязный хак, а не «полезная идеома», т.к. в корне меняет семантику проверки. проверяя request.POST, вы делаете допущение, что при POST запросе (request.method == 'POST'), тело HTTP сообщения (request.POST) не может быть пустым. это так:

допустим, форма предлагает выбрать один из вариантов контактов (список полей type=«radio»). если не выбрать ни одного и сделать POST, то тело POST запроса будет пустым и после перезагрузки страницы посетитель увидит снова оригинальную форму, вместо формы с сообщением об ошибке.

т.е. для какой-то конкретной формы, при данных условиях это может работать. но в общем случае — нет. вот поэтому
В документации и обучающих примерах по django обычно пишут вьюхи вот так
Главная — ГЛАВА 19. ОТПУСКА — Статья 125. ТК РФ. Разделение ежегодного оплачиваемого отпуска на части. Отзыв из отпуска
Статья 125. ТК РФ. Разделение ежегодного оплачиваемого отпуска на части. Отзыв из отпуска

По соглашению между работником и работодателем ежегодный оплачиваемый отпуск может быть разделен на части. При этом хотя бы одна из частей этого отпуска должна быть не менее 14 календарных дней. ...
Правильный 
дизайн
ускоряет 
чтение 
текста
....
Казалось
бы,
довольно
очевидно,
да? 
Но 
я 
не
задумывался 
об 
этом 
ранее.
в репозитарий затесался оригинальный бинарный файл для макоси… теперь просто наберите make.
ни чем — это элемент автоматизации. :) при выходе из режима вставки (insert mode) плагин автоматически дергает за системный переключатель и переключает раскладку на английскую. при входе — восстанавливает в прежнее состояние.
А чем лучше? Мы не будем говорить про вычисления на калькуляторе, где «программа» живет лишь до получения первого результата. Давайте рассмотрим более привычную для разработчиков ситуацию ситуацию, когда программа должна использоваться и поддерживаться в течении продолжительного времени. Как это часто бывает, проходит полгода, и цены на яблоки вырастают на на 1 рубль. Этот факт нужно отразить в чудо-программе. Разумеется, предыдущего гения-программиста уже месяц, как схантил йандекс, и задачу предстоит решать другому. Что он видит? Он видит в коде две волшебные константы: что из них цена, которую нужно менять «1» или «3»? В исходнике нет ответа, поэтому он идет выяснять состояние прайса на яблоки в предыдущем периоде, проклиная всех долбаных гениев, решивших (уж не знаю чем вам этот код приглянулся) — допустим, сэкономить 10 секунд на написание 2 строчек проясняющего суть текста. :)
мне показалось, что упоминание Оккама/П.Д.О. было бы уместнее в предыдущей статье — про модульность. здесь же он ясности не добавил). в программировании нередко приходится добавлять обозначения для того, чтобы повысить ясность. сравните:

print 1 * 3

и

price_of_apples = 1
number_of_apples = 3
print price_of_apples * number_of_apples

первый пример несомненно короче. но где больше ясность?

Кроме того:
Последующее развитие логики показало, однако, что отнесение Принципа Достаточного Основания к числу логических законов лишено /достаточных/ оснований.
wiki: Принцип достаточного основания) иными словами, бритва Оккама не нужна))
Исключения должны проектироваться не от кода, а от ситуаций,
которые вы хотите по-особенному обработать.

Исключения являются частью внешнего интерфейса. Т.е. это то, с чем будет
взаимодействовать _клиенсткий_ код (чужой — а не ваш). Вы не можете заранее предугадать, какие ситуации клиентский код «захочет»
обрабатывать «по-особенному». Соответственно — проектировать исключения исходя
из какой-то особенной обработки нет ни какого резона. Вы можете лишь обозначать
исключительные ситуации в той мере, в которой сочтете нужным
это требуется для обеспечения полноты модели предметной области.

Информация

В рейтинге
1 554-й
Зарегистрирован
Активность