некоторое количество кода, пользующегося хаком в виде разбора стектрейса для доступа к рантайм значениям переменных в вызывающем коде, перестанет работать.
и поделом =) «вызывающий код» для рекурсивной функции это та же самая функция. в этом случае есть более очевидные способы передать значения переменных, нежели стектрейс. :)
Да, так и есть: другое решение, нужно описывать заново — я периодически попадаю в такие ситуации. По-моему, это в порядке вещей — все равно нормальное решение получается лишь с третьего раза. :)
Отнюдь не претендую на абсолютную истинность или новизну суждений — просто мнение, которое у меня сложилось к данному моменту. Я занимаюсь web-программированием и активно использую автоматические тесты лишь последние пол. года. Раз уж согласились с тезисом о требованиях, может быть проясните и спорный момент с проектированием? =)
Я рассуждаю так. Допустим, есть некоторая задача, которая стоит того, чтобы её решить. Допустим — найти ответ на Главный вопрос жизни, вселенной и всего такого. Задача сложная и как писать код вообще совсем не понятно. Однако, это уже какая-то информация. Данные факты — то, что задача уже поставлена, и то, что непонятно как писать код — можно записать в виде теста на всем понятном языке:
void testShouldAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything() {
throw new SkipTest()
}
Профит в том, что данная конструкция уже одним своим существованием будет напоминать о необходимости что-то так-и родить, при каждом запуске тестов. Можно пойти дальше, и сочинить сценарий решения, например с участием суперкомпьютера и удивительным ответом в конце:
И так, реализации ещё нет, но тест уже есть. Все в рамках ТДД. Вот только не поняно — я все правильно спроектировал, или нет? Может быть решатель нужно было представить в виде простой функции, а не объекта с методом? И не на с++ а на lisp? Верен-ли ответ? Как проверить?
Получается, что тесты являются лишь способом записи решений, принятых в процессе проектирования. Но каким образом они устраняют ошибки проектирования? — Мне не понятно.
Тесты, это такой хитрый способ записи требований, который одновременно понятен и нормальному человеку (не программисту) и машине. В идеале — с первого раза ни у кого не получается. ;) Поэтому тесты в ТДД пишутся раньше, чем код, как blueprint того, что ты должен сделать.
Покрытие кода тестами это, по сути, реверс-инжениринг требований по имеющейся реализации. Это не основная практика ТДД. Такими вещами обычно занимаются провинившиеся — из-за разгильдяйства на предыдущих этапах разработки, или там от безысходности — постфактум. ;)
Что должен делать «Бункер»? Обработать нажатие мыши — требование раз. Сохранить себя в xml — требование два,… Записать это на языке тестов не составит труда. А после этого, их можно запускать — в любом количестве, в любое время, вручную поштучно и автоматически по over 9k за раз, на всем протяжении жизни проекта. Что там еще было? — не открывать внутренней информации другим классам — хрень, а не требование, оно не формализуется. Есть расхожее мнение, мол ТДД обеспечивает правильность проектирования — это миф. Тесты сами — по себе, проектирование — само по себе.
в самом деле, удобно. но функциональность CapsLock иногда нужна. можно-ли повесить её на другое сочетание клавиш (например, одновременное нажатие левого и правого Shift)?
плохо спроектированный код почти невозможно автоматически тестировать, и наоборот — намерение тестировать код вынуждает более грамотно проектировать архитектуру
Кажется, это очередной миф. Формально, тест работает с реализацией как с черным ящиком: для теста все равно — хоть там архитектурное чудо, хоть путанное-перепутанное «спагетти».
К слову, ГОСТ 34.601-90 «техническое задание» идет аж 3-м пунктом. До ТЗ есть ещё 2 равноценные стадии: «формирование требований» и «разработка концепции», а после — «эскизный проект», «технический проект» и т.п. ТЗ составляется совместно с заказчиком. А в 34.003-90 перечисляются отдельные компоненты. Например (2.9) как раз призвано решать проблему с лексиконом.
Нет, я не предлагаю оформлять отношения с заказчиком по ГОСТам. Просто хочу отметить тот факт, что на ТЗ свет клином не сошёлся. В простых случаях, отдельные стадии создания можно совмещать или даже пропускать целиком. Но чем крупнее проект, тем лучше обращать внимание на чужой опыт. Все-таки автоматизированные системы, тоже сложные штуки, и закономерно полагать, что разработчики на все эти грабли уже наступали, и выработали какую-то стратегию для достижения результата.
вот такое суровое ООП. интересно это как-то связано с увеличением числа «core developers (людей, которые могут принимать решения и коммитить код)» в 2 раза? ))
Мя че-то коробит от Class Based Views. Такое ощущение, что разработчики вытащили весь бардак из generic-views и AdminModel наружу. Не понимаю восторга… 31337' блин, перед php'шниками не стыдно?
Пока это безобразие находилось в contrib и особо не афишировалось, было пофик. А теперь оно стало частью фреймворчного API. API это серьёзная вещь, которая предопределяет судьбу проектов, построенных с его использованием, на долгое время. Поэтому его нужно проектировать, а не фигачить с похмелья в с состоянии аффекта.
Я давно не видел таких идиотских интерфейсов как у новых mixin. Если процедурную «лапшу» запихать в объявление class, она так и остается лапшой. Как сказал оратор выше: «это апофигей объектно-ориентированного подхода». :( А «Date-based Mixins» это вообще кульминация. Парсинг дат, как часть интерфейса view — зачем мешать все в одну кучу?
Лучше бы не страдали фигней, а смержили наработки из внешних проектов, где косяки django постепенно исправляются. Например, из django-piston. Здесь уже тыщу лет есть и нормальные абстракции для представлений ресурсов с помощью объектов, и правильная обработка http-запросов, и сериализация/десериализация контента сообщений по Content-type (а не только multipart/form-data как в джанге).
простая и понятная рутина, которой обычно лень заниматься, мне помогает войти в ритм, когда становится лень заниматься творчеством и принимать решения.
кажется, что прок.., короче subj, может быть тупо следствием защитной реакции организма. творческие «запои», сопровождающиеся нарушением сна, режима, питания, нехваткой витаминов и т.п. «творческой» атрибутикой, выматывают. не сразу, но надолго. мозг начинает требовать разгрузку. становится сложно удерживать концентрацию — хочется переключиться на другое, более простое занятие.
проблема соц.сетями, форумами, СМИ, прогулками по музеям и т.п. состоит в том, что они сами по себе создают мощнейший поток информации. поэтому такое переключение лишь окончательно «добивает» мозг.
при первых же симптомах, стараюсь переключиться на деятельность, которая не требует постоянной концентрации внимания. кстати, с первым авто я проводил дни напролет в гараже: шиномонтаж, ремонт и апгрейд доставляли уйму фана. :)
у меня есть несколько 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.
и поделом =) «вызывающий код» для рекурсивной функции это та же самая функция. в этом случае есть более очевидные способы передать значения переменных, нежели стектрейс. :)
Я рассуждаю так. Допустим, есть некоторая задача, которая стоит того, чтобы её решить. Допустим — найти ответ на Главный вопрос жизни, вселенной и всего такого. Задача сложная и как писать код вообще совсем не понятно. Однако, это уже какая-то информация. Данные факты — то, что задача уже поставлена, и то, что непонятно как писать код — можно записать в виде теста на всем понятном языке:
Профит в том, что данная конструкция уже одним своим существованием будет напоминать о необходимости что-то так-и родить, при каждом запуске тестов. Можно пойти дальше, и сочинить сценарий решения, например с участием суперкомпьютера и удивительным ответом в конце:
И так, реализации ещё нет, но тест уже есть. Все в рамках ТДД. Вот только не поняно — я все правильно спроектировал, или нет? Может быть решатель нужно было представить в виде простой функции, а не объекта с методом? И не на с++ а на lisp? Верен-ли ответ? Как проверить?
Получается, что тесты являются лишь способом записи решений, принятых в процессе проектирования. Но каким образом они устраняют ошибки проектирования? — Мне не понятно.
Покрытие кода тестами это, по сути, реверс-инжениринг требований по имеющейся реализации. Это не основная практика ТДД. Такими вещами обычно занимаются провинившиеся — из-за разгильдяйства на предыдущих этапах разработки, или там от безысходности — постфактум. ;)
Что должен делать «Бункер»? Обработать нажатие мыши — требование раз. Сохранить себя в xml — требование два,… Записать это на языке тестов не составит труда. А после этого, их можно запускать — в любом количестве, в любое время, вручную поштучно и автоматически по over 9k за раз, на всем протяжении жизни проекта. Что там еще было? — не открывать внутренней информации другим классам — хрень, а не требование, оно не формализуется. Есть расхожее мнение, мол ТДД обеспечивает правильность проектирования — это миф. Тесты сами — по себе, проектирование — само по себе.
Кажется, это очередной миф. Формально, тест работает с реализацией как с черным ящиком: для теста все равно — хоть там архитектурное чудо, хоть путанное-перепутанное «спагетти».
Нет, я не предлагаю оформлять отношения с заказчиком по ГОСТам. Просто хочу отметить тот факт, что на ТЗ свет клином не сошёлся. В простых случаях, отдельные стадии создания можно совмещать или даже пропускать целиком. Но чем крупнее проект, тем лучше обращать внимание на чужой опыт. Все-таки автоматизированные системы, тоже сложные штуки, и закономерно полагать, что разработчики на все эти грабли уже наступали, и выработали какую-то стратегию для достижения результата.
Собственно, вся C-B-V магия заключена здесь:
Т.е. с точки зрения urlconf, view как были функциями так и остались.
ps: любопытна, реализация метода dispatch. Здесь данные сначала икапсулируются в объект, а затем передаются его же методу через сигнатуру.
вот такое суровое ООП. интересно это как-то связано с увеличением числа «core developers (людей, которые могут принимать решения и коммитить код)» в 2 раза? ))
Пока это безобразие находилось в contrib и особо не афишировалось, было пофик. А теперь оно стало частью фреймворчного API. API это серьёзная вещь, которая предопределяет судьбу проектов, построенных с его использованием, на долгое время. Поэтому его нужно проектировать, а не фигачить с похмелья в с состоянии аффекта.
Я давно не видел таких идиотских интерфейсов как у новых mixin. Если процедурную «лапшу» запихать в объявление class, она так и остается лапшой. Как сказал оратор выше: «это апофигей объектно-ориентированного подхода». :( А «Date-based Mixins» это вообще кульминация. Парсинг дат, как часть интерфейса view — зачем мешать все в одну кучу?
Лучше бы не страдали фигней, а смержили наработки из внешних проектов, где косяки django постепенно исправляются. Например, из django-piston. Здесь уже тыщу лет есть и нормальные абстракции для представлений ресурсов с помощью объектов, и правильная обработка http-запросов, и сериализация/десериализация контента сообщений по Content-type (а не только multipart/form-data как в джанге).
кажется, что прок.., короче subj, может быть тупо следствием защитной реакции организма. творческие «запои», сопровождающиеся нарушением сна, режима, питания, нехваткой витаминов и т.п. «творческой» атрибутикой, выматывают. не сразу, но надолго. мозг начинает требовать разгрузку. становится сложно удерживать концентрацию — хочется переключиться на другое, более простое занятие.
проблема соц.сетями, форумами, СМИ, прогулками по музеям и т.п. состоит в том, что они сами по себе создают мощнейший поток информации. поэтому такое переключение лишь окончательно «добивает» мозг.
при первых же симптомах, стараюсь переключиться на деятельность, которая не требует постоянной концентрации внимания. кстати, с первым авто я проводил дни напролет в гараже: шиномонтаж, ремонт и апгрейд доставляли уйму фана. :)
если серьёзно, не знаю можно-ли обобщать этот рецепт. когда текущий работодатель предложил сделать тестовое задание, настоял посмотреть реальный код, с полной ретроспективой коммитов — вместо этой ерунды. а вот прокатит-ли такое с монстрами типа яндекса? (кстати, вопрос :) ).
«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 — всё зависит от типа требований.
когда глючит программный код, и архитектура трещит по швам, многие пытаются искать спасения в TDD. проблема в том, что автоматические тесты, это тоже программный код. поэтому его в равной степени можно писать не_правильно, — точно с таким же исходом. :)
у тестов нет задачи «ловить ошибки». ошибки — это лишь следствие — суть, отклонение поведения программы от требуемого (если поведение программного кода отличается от заданного требованием/спецификацией, значит он содержит ошибку). вообще, во главе угла стоят не ошибки, а требования и спецификации.
требования могут быть лишь в вашем воображении, описаны на словах, выражены в схемах и графиках. но лучше, если вы можете сформулировать требование в виде алгоритма: тогда есть возможность выразить его с помощью языка программирования — т.е. написать тест. основное преимущество, которое даёт именно такой способ записи требований — возможность в любой момент и практически *мгновенно* проверить продукт на соответствие (просто «запустив» соответствующий тест). разумеется не каждое требование можно описать в таком виде. существует целый класс нефункциональных требований, которые даны лишь в человеческих ощущениях — и для проверки продукта на соответствие вы будете по-прежнему использовать тестировщиков, пользователей, заказчиков и т.п. медленные и плохо предсказуемые инструменты.
требования могут быть как осмысленными, так и абсолютно бессмысленными (в контексте решаемой задачи). спецификации могут быть недостаточными, избыточными, противоречивыми. а значит всё тоже самое касается и тестов. если нет чёткого представления о том, что вы хотите получить в итоге — нет ни какого смысла писать тест. еще меньше смысла браться что-то «программировать». хотя последнее для «программиста» привычнее.
— эй, вася, что ты такое пишешь?
— еще не знаю, щаз скомпилирую, узнаю.
самое сложное при внедрении TDD это ломка программистского стереотипа: сначала быстро «накодить», ведь и так все ясно, а потом думать зачем, для чего, и исправлять ошибки. :)
как-то так. прошу прощения за дайджест.
Если смотреть со стороны управления конфигурациями проекта, то ветвление это средство, а vcs — инструмент. От vcs нужна возможность работы с бранчами, а распределенность не играет большой роли. Просто так получается, что в распределенных управление бранчами реализовано лучше. scm-notes.blogspot.com/2010/09/branch-per-task-workflow-explained.html.