Здравствуйте, hrg, Вы писали:
hrg>Фишка в том, что тесты пишутся вначале, а не после того, как завершено hrg>создание модуля
Попробуй представить себе во что выльется рукопашное написание кода если даже ручная реализация является неподъемной задачей.
Что в конце концов описывать в этих стестах?
hrg>Т.е. не сидим и думаем, как будет этот класс использоваться, а сначала hrg>пишем, как он будет использоваться (такая вот тафтология ), а потом пишем hrg>реализацию. И приводим неработающий код теста к работающему..
Здорово. Представь этот процесс для парсера. Как ты себе это видишь? И не лучше ли написать (реально использовать готовый) генератор кода чем взиться с тестами.
V>> Или TDD — это не для всех?
hrg>долько для тех, у кого черный пояс по ООП Ж)
Никогда не приклонялся перед парадигмами. Те же парсеры в лучшем виде пишутся в процедурном виде. ООП там нужен только для AST (хотя разницы со структурами почти нет) и для того чтобы пускать парсер параллельно в разных потоках.
Так что это мимо.
V>> Может я чего не так понимаю в концепции TDD?
hrg>Может. Есть хорошая книжка. Не помню точно как называется. Вроде: hrg>"Разработка через тестирование". Стоит около 100р. Обложка черная
hrg> Yury Kopyl aka hrg | http://id.totem.ru | Только взял боец гитару, сразу hrg>видно — гармонист...
Да я читал несколько статей. Мне кажется, что принцыпы я понял правильно. Только вот почему-то вопросы возникают, а на них постоянно отвечают цитатами на подобии приведенных тобой "сначала пишим... самодокументирование...".
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Maxim S. Shatskih, Вы писали:
>>всеми тонкостями. И проработка этих мелочей в интерфейсе подсистем, может оказаться >>даже более высокоуровневым делом в проектировании, чем создание стройной логичной >>иерархии классов. Иерархию классов проще переделать, чем неправильную декомпозицию >>крупных частей.
MSS>Именно так дизайнят системы, основанные на COM.
Скорее КОМ использует паттерны фабрика классов и сиглтон.
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>В задачу вник. Как для таких задач эффективно использовать ТДД (и, самое главное, надо ли?) — вопрос весьма интересный.
Будет любопытно. Потому как проблемы тестирования один фиг есть.
ЗХ>Попытаюсь на него ответить, только последний уточняющий вопрос: а каким образом это все тестируется на сегодняшний день?
Есть пара тестовых задач. Первый глобальный тест который в зависимости от закоментаринности одной строчки или выводит код парсимых файлов на консоль или молча парсит в дерево и ругается если что не так.
Далее этот код натравливается на большие скопления правильных и неправильных файлов. Правильные — это средние и большие проекты вроде R#, Янус, Моно, Ротор. Непаривльные — это список ошибочных файлов из Моно (там есть специальный набор ошибок с указанием того как компилятор должен реагировать на них, к сожалению многие из них семантические и невидны парсером).
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Все эти вещи остаются в коде навсегда, потом отключаются макросами тогда, когда данный кусок уже в изменениях не нуждается. После каждого изменения там — обратно включаются макросы, и снова прогоняется сьют.
Ну, в компонентной архитектуре тестовый код можно частично вынести в отдельные модули.
Кстати, создавая код на С++ я постоянно писал ассерты. На Шарпе как-то это дело начало забываться. Отладка настолько проще, что порой ассерты и не нужны. Стандартная диагностика сама отлавливает 90% багов. Так есть автоматический контроль выхода за пределы массива. Плюс в классах проверки...
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, hrg, Вы писали:
I>> Кроме того, хорошей практикой является ситуация, когда каждый I>> зарепорченный баг от QA тоже оформляется в виде unit-теста или I>> определённого сценария.
hrg>О. А это мысль! Ж)
Это, кстати, дефствительно мысль. Вот формалять тесты в для багрепротов можно и в парсере. Более того можно скомуниздить список сообщений об ошибках чужого компилятора (референсного, например, MS C#-а) и сделать тесты для них.
Только это резко противоречит с идеей делать тесты для всего кода. Написание кода для автоматически генерируемого парсера по-моему и очень тежело и, что самое главное, глупо.
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Будет любопытно. Потому как проблемы тестирования один фиг есть.
ЗХ>>Попытаюсь на него ответить, только последний уточняющий вопрос: а каким образом это все тестируется на сегодняшний день?
VD>Есть пара тестовых задач. Первый глобальный тест который в зависимости от закоментаринности одной строчки или выводит код парсимых файлов на консоль или молча парсит в дерево и ругается если что не так.
VD>Далее этот код натравливается на большие скопления правильных и неправильных файлов. Правильные — это средние и большие проекты вроде R#, Янус, Моно, Ротор. Непаривльные — это список ошибочных файлов из Моно (там есть специальный набор ошибок с указанием того как компилятор должен реагировать на них, к сожалению многие из них семантические и невидны парсером).
держите меня, ща буду умничать
Так. Думали мы, думали... Вот чего получается:
на прикладном уровне:
. грамматику строим не всю сразу, а от простого к сложному
. на примере разбора мат. выражения это будет так:
. пишем тест, который будет принимать одну переменную (скажем, буквы + знаки подчеркивания). запускаем. он, естественно, не срабатывает. пишем код (реализацию). убеждаемся, что тест примает, что нужно (буквы+подчеркивания) и отбрасывает, чего не нужно (цифры, мат.знаки, пробелы...)
. пишем тест суммирования. потом реализацию. убеждаемся, что тест 1ой переменной все еще работает; что тест суммы на правильных последовательностях лексем строит АСТ, а на неправильных (на этом этапе "неправильные" несложно вручную набить) — пасует.
. тест на умножение. убеждаемся в правильности приоритета операций; в том, что все предыдущие тесты все еще работают.
. ... и так до посинения.
насколько такая деятельность трудоемка, я пока не знаю (поскольку сейчас берусь за похожую задачу, спроси через пару недель — расскажу). но вот то, что порожденная грамматика (при срабатывании всех тестов) будет — это не исключено
на концептуальном уровне:
данную задачу можно обобщить до задачи тестирования вообще любого кода, цель которого — принимать все "правильные" и отбрасывать все "неправильные" варианты. я, например, с аналогичной задачей давеча столкнулся при написании парсера формата .doc
история, кстати, довольно грустная. и как получить уверенность, что обрабатываются все "неправильные" варианты —
не исключено, что в тдд-шном подходе (когда каждый кусочек оттестирован отдельно, а потом каждая совокупность кусочков...) все будет . но уверенности в этом у меня нет. к тому же мне еще не вполне ясна трудоемкость подхода.
VladD2 -> "Re[4]: Рефакторинг. Нужен ли он?" :
hrg>> Фишка в том, что тесты пишутся вначале, а не после того, как hrg>> завершено создание модуля
V> Попробуй представить себе во что выльется рукопашное написание кода V> если даже ручная реализация является неподъемной задачей.
Рукопашная чего? Релизация чего?
V> Что в конце концов описывать в этих стестах?
hrg>> Т.е. не сидим и думаем, как будет этот класс использоваться, а hrg>> сначала пишем, как он будет использоваться (такая вот тафтология hrg>> ), а потом пишем реализацию. И приводим неработающий код теста hrg>> к работающему..
V> Здорово. Представь этот процесс для парсера. Как ты себе это видишь?
Я писал граммматики. И писал тесты для них. Парсер же у тебя строит дерево
разбора? Так? Тогда посовывай ему правильный и неправильный код по
возрастанию сложности. И сравнивай, что получилось в мозгах. Чтобы не
стемиться к n^m тестам, грамматику надо декомпозировать. Т.е. тестрируешь
работу, например циклов, ветвлений, разбор выражений. И в конце даешь один
большой композиционный тест.
V> И не лучше ли написать (реально использовать готовый) генератор кода V> чем взиться с тестами.
Не лучше. А нужно.
V>>> Или TDD — это не для всех?
hrg>> долько для тех, у кого черный пояс по ООП Ж)
V> Никогда не приклонялся перед парадигмами. Те же парсеры в лучшем виде V> пишутся в процедурном виде. ООП там нужен только для AST (хотя V> разницы со структурами почти нет) и для того чтобы пускать парсер V> параллельно в разных потоках.
V> Так что это мимо.
Ясно. Атрофия чувства юмора.
V>>> Может я чего не так понимаю в концепции TDD?
hrg>> Может. Есть хорошая книжка. Не помню точно как называется. Вроде: hrg>> "Разработка через тестирование". Стоит около 100р. Обложка черная hrg>>
hrg>> Yury Kopyl aka hrg | http://id.totem.ru | Только взял боец гитару, hrg>> сразу видно — гармонист...
V> Да я читал несколько статей. Мне кажется, что принцыпы я понял V> правильно. Только вот почему-то вопросы возникают, а на них постоянно V> отвечают цитатами на подобии приведенных тобой "сначала пишим... V> самодокументирование...".
Какие нафиг цитаты? Пишу как чукча — "о чем вижу о том и пою". При желании
можно покрыть тестами все. Только думать все таки надо.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Тесты делаю в таком порядке: ЗХ>- нам нужно Нечто (класс/функция/библиотека), которое будет выполнять часть функциональности. ЗХ>- совершенно не задумываясь, как Нечто будет выглядеть, пишем тест.
что такое "пишем тест" — излагаем словами что оно принимает на входе, что должно быть на выходе? или пишем утилитку, которая иммитирует эти входные воздействия и анализирует то что на выходе? или что?
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>Тесты делаю в таком порядке: ЗХ>>- нам нужно Нечто (класс/функция/библиотека), которое будет выполнять часть функциональности. ЗХ>>- совершенно не задумываясь, как Нечто будет выглядеть, пишем тест.
OE>что такое "пишем тест" — излагаем словами что оно принимает на входе, что должно быть на выходе? или пишем утилитку, которая иммитирует эти входные воздействия и анализирует то что на выходе? или что?
Здравствуйте, hrg, Вы писали:
V>> Попробуй представить себе во что выльется рукопашное написание кода V>> если даже ручная реализация является неподъемной задачей.
hrg>Рукопашная чего? Релизация чего?
Реализация тестов (1) и ручная реализация парсера (2). Видимто... контекст то потерян.
hrg>Я писал граммматики. И писал тесты для них.
Т.е. все же сначала грамматика а потом тесты для нее? Как-то не клеится с подходами ТДД.
hrg> Парсер же у тебя строит дерево hrg>разбора? Так? Тогда посовывай ему правильный и неправильный код по hrg>возрастанию сложности. И сравнивай, что получилось в мозгах. Чтобы не hrg>стемиться к n^m тестам, грамматику надо декомпозировать. Т.е. тестрируешь hrg>работу, например циклов, ветвлений, разбор выражений. И в конце даешь один hrg>большой композиционный тест.
Так и делаем. Только ТДД идет лесом.
Вот сейчас думаю хотя бы на ошибки похожую на ТДД схему навьючить.
hrg>Ясно. Атрофия чувства юмора.
Возможно. Поздно было уже.
hrg>Какие нафиг цитаты? Пишу как чукча — "о чем вижу о том и пою". При желании hrg>можно покрыть тестами все. Только думать все таки надо.
Если бы от желания что-то становилось проще...
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>. на примере разбора мат. выражения это будет так: ЗХ>. пишем тест, который будет принимать одну переменную (скажем, буквы + знаки подчеркивания). запускаем. он, естественно, не срабатывает. пишем код (реализацию). убеждаемся, что тест примает, что нужно (буквы+подчеркивания) и отбрасывает, чего не нужно (цифры, мат.знаки, пробелы...) ЗХ>. пишем тест суммирования. потом реализацию. убеждаемся, что тест 1ой переменной все еще работает; что тест суммы на правильных последовательностях лексем строит АСТ, а на неправильных (на этом этапе "неправильные" несложно вручную набить) — пасует. ЗХ>. тест на умножение. убеждаемся в правильности приоритета операций; в том, что все предыдущие тесты все еще работают.
Ты представляешь себе количество только правильных переборов которое получается даже на примитивных выражениях. А граматика Шарпа примерно в 1000 раз сложнее. И количество вариаций тестов зашкаливает за все разумные пределы.
ЗХ>. ... и так до посинения.
Во-во .
ЗХ>насколько такая деятельность трудоемка, я пока не знаю (поскольку сейчас берусь за похожую задачу, спроси через пару недель — расскажу).
Если задача подобная, то пожалуй я к тебе через пол годика подойду.
ЗХ>но вот то, что порожденная грамматика (при срабатывании всех тестов) будет — это не исключено
Сдается мне, что останется еще пару миллионов вариций которые останутся непроверенными.
ЗХ>история, кстати, довольно грустная. и как получить уверенность, что обрабатываются все "неправильные" варианты —
Мне кажется разумным было бы описать алгорим в виде граматики и возложить отлов неверных вариантов на генератор парсеров.
ЗХ>не исключено, что в тдд-шном подходе (когда каждый кусочек оттестирован отдельно, а потом каждая совокупность кусочков...) все будет . но уверенности в этом у меня нет. к тому же мне еще не вполне ясна трудоемкость подхода.
Вопрос еще в какие сроки у тебя будет все ОК?
Кстати, ты это дело вручную хочешь делать или как-то автоматизированно?
... << RSDN@Home 1.1.4 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
ЗХ>>. на примере разбора мат. выражения это будет так: ЗХ>>. пишем тест, который будет принимать одну переменную (скажем, буквы + знаки подчеркивания). запускаем. он, естественно, не срабатывает. пишем код (реализацию). убеждаемся, что тест примает, что нужно (буквы+подчеркивания) и отбрасывает, чего не нужно (цифры, мат.знаки, пробелы...) ЗХ>>. пишем тест суммирования. потом реализацию. убеждаемся, что тест 1ой переменной все еще работает; что тест суммы на правильных последовательностях лексем строит АСТ, а на неправильных (на этом этапе "неправильные" несложно вручную набить) — пасует. ЗХ>>. тест на умножение. убеждаемся в правильности приоритета операций; в том, что все предыдущие тесты все еще работают.
VD>Ты представляешь себе количество только правильных переборов которое получается даже на примитивных выражениях. А граматика Шарпа примерно в 1000 раз сложнее. И количество вариаций тестов зашкаливает за все разумные пределы.
ы! я ж тебе о чем:
если мы напишем отдельно тест на a+b*c, потом на a+c*b, a*b+c и т.п. — єто да, комбинаторное возрастание количества тестов и фигня.
Но! если удастся организовать все так, чтобы, убедившись в правильности теста a+b, мы уже больше к оператору "+" не возвращались, то ты не прав.
Фишка ж именно в предположении, что если каждый кусочек оттестирован и работает, к нему можно больше не возвращаться.
По сути, количество тестов == кол-ву правил в грамматике, а не (количество правил)!
ЗХ>>насколько такая деятельность трудоемка, я пока не знаю (поскольку сейчас берусь за похожую задачу, спроси через пару недель — расскажу). VD>Если задача подобная, то пожалуй я к тебе через пол годика подойду.
Да нет, на сто порядков проще — простенькие выражения, вроде мат. логики. Поэтому спроси через пару недель
ЗХ>>но вот то, что порожденная грамматика (при срабатывании всех тестов) будет — это не исключено VD>Сдается мне, что останется еще пару миллионов вариций которые останутся непроверенными.
А по-моему, нет.
В тестах мы перебираем не вариации, а атомы, из которых они состоят.
Рискну повториться, но все в том же примере мат. выражений наличие (и срабатывание) всего четырех тестов (переменная, +, *, скобки) — гарант того, что такая комбинация
a+b*(b+b*(a*(b+a*a))+b*a)+a*b
распарсится правильно
ЗХ>>история, кстати, довольно грустная. и как получить уверенность, что обрабатываются все "неправильные" варианты — VD>Мне кажется разумным было бы описать алгорим в виде граматики и возложить отлов неверных вариантов на генератор парсеров.
да в том и проблема, что, например, файл Ворда парсером не распарсишь. Там дальнейшие действия зависят от уже извлеченной информации.
ЗХ>>не исключено, что в тдд-шном подходе (когда каждый кусочек оттестирован отдельно, а потом каждая совокупность кусочков...) все будет . но уверенности в этом у меня нет. к тому же мне еще не вполне ясна трудоемкость подхода. VD>Вопрос еще в какие сроки у тебя будет все ОК?
Да, это вопрос. Но ответа на него нет ни у меня, ни у тебя.
VD>Кстати, ты это дело вручную хочешь делать или как-то автоматизированно?
ты про генерацию тестов?
хз... наверное, есть возможность автоматизировать. чего я боюсь, так это того, что если тесты генерятся автоматически, то ошибка в составлении правила приведет к генерации ошибочных тестов.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Фишка ж именно в предположении, что если каждый кусочек оттестирован и работает, к нему можно больше не возвращаться. ЗХ>По сути, количество тестов == кол-ву правил в грамматике, а не (количество правил)!
В первой версии шарпа был такой глюк:
Так работает:
using (...)
{
}
Так тоже работает:
if (...)
{
}
И даже так работает:
using (...)
{
if (...)
{
}
}
Так вообще классно работает:
using (...)
using (...)
{
}
А вот так не работает
using (...)
if (...)
{
}
И как в такой ситуации обойтись без (количество правил)! ?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Зверёк Харьковский, Вы писали:
OE>>что такое "пишем тест" — излагаем словами что оно принимает на входе, что должно быть на выходе? или пишем утилитку, которая иммитирует эти входные воздействия и анализирует то что на выходе? или что?
ЗХ>дык... того... юнит-тест, значить.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>Фишка ж именно в предположении, что если каждый кусочек оттестирован и работает, к нему можно больше не возвращаться. ЗХ>>По сути, количество тестов == кол-ву правил в грамматике, а не (количество правил)!
IT>В первой версии шарпа был такой глюк:
IT>Так работает:
IT>
IT>И как в такой ситуации обойтись без (количество правил)! ?
А по-моему, как раз аргумент в мою пользу!
Как раз такая проблема могла возникнуть если парсер тестировали натравливанием на много всяких файлов, а там не встретилось такой комбинации.
А вот если бы сработали тесты:
— ловящий using(...)<expr>
— и понимающий, что if(...) это есть <expr>
то такого глюка никогда не могло бы быть! при любой комбинации if и using
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Зверёк Харьковский, Вы писали:
OE>>>что такое "пишем тест" — излагаем словами что оно принимает на входе, что должно быть на выходе? или пишем утилитку, которая иммитирует эти входные воздействия и анализирует то что на выходе? или что?
ЗХ>>дык... того... юнит-тест, значить.
OE>
виноват...
я что, чушь какую-то спорол?
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>я что, чушь какую-то спорол?
OE>не, просто я так и не понял, что же все-таки из себя представляют эти самые тесты
юнит-тесты вообще или юнит-тесты применительно к ТДД?
Здравствуйте, Зверёк Харьковский, Вы писали:
OE>>не, просто я так и не понял, что же все-таки из себя представляют эти самые тесты ЗХ>юнит-тесты вообще или юнит-тесты применительно к ТДД?
те, про которые ты так красиво писал:
>Здрасьте. Пришел "апологетствовать" . >"Крутым парнем" не являюсь, но пользую ТДД давно и на весьма крупном проекте. >Тесты делаю в таком порядке: >- нам нужно Нечто (класс/функция/библиотека), которое будет выполнять часть функциональности. >- совершенно не задумываясь, как Нечто будет выглядеть, пишем тест. >Тест должен соответствовать следующим требованиям: >а) я показываю, как мне будет удобно пользовать Нечто и какие фичи мне нужны; >б) я показываю, каким ограничениям оно должно соответствовать.