Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Программирование Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2 3 4 5 6      [все]
 Про TDD  [new]
kmaw
Member [заблокирован]

Откуда: бобруйск
Сообщений: 24786
что-то задумался над этим подходом. книги/статьи читал. но как-то не проникся. может подскажете хорошее чтиво/статьи, где не хелловорд и не про бороздят космические океаны. почему пишу? чувствую, надо быть в тренде что есть в этом подходе что-то мне нужное.
9 июл 15, 19:55    [17874300]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
TDD это забавный зверек пригодный для расчетных задач. Но в большинстве случаев мы пишем что-то работающее с пользовательскими интерфейсами, а для этого чрезвычайно сложно создать автоматический тест. Поэтому и TDD распространения не получил.
Но если у тебя задача типа взять один файл и превратить его в другой - то TDD становится чрезвычайно удобным. Можно даже утверждать что для любых конверторов TDD это наиболее естественный процесс разработки.
Но для любых приложений с GUI это уже практически неприменимо.
9 июл 15, 20:22    [17874353]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
kmaw
Member [заблокирован]

Откуда: бобруйск
Сообщений: 24786
White Owl
TDD это забавный зверек пригодный для расчетных задач. Но в большинстве случаев мы пишем что-то работающее с пользовательскими интерфейсами, а для этого чрезвычайно сложно создать автоматический тест. Поэтому и TDD распространения не получил.
Но если у тебя задача типа взять один файл и превратить его в другой - то TDD становится чрезвычайно удобным. Можно даже утверждать что для любых конверторов TDD это наиболее естественный процесс разработки.
Но для любых приложений с GUI это уже практически неприменимо.


Ваш ответ скорее против, чем за TDD, как мне кажется. меня больше интересует, как этот TDD, работает в обычных бизнес-приложениях. там все уже известно - что и как. а бизнес логика - именно то что есть "бизнес-логика" - та часть, которую надо неизбежно говнокодить - как тут это TDD имеет место быть? часто пишут в интернетах: вот контроллер, вот репозиторий. но это как-то мимо все
9 июл 15, 20:28    [17874371]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
kmaw
Ваш ответ скорее против, чем за TDD, как мне кажется. меня больше интересует, как этот TDD, работает в обычных бизнес-приложениях. там все уже известно - что и как. а бизнес логика - именно то что есть "бизнес-логика" - та часть, которую надо неизбежно говнокодить
ха-ха-ха.
Во впервых, кому нужно? Бизнес покупает готовый продукт (1С хотя бы) и подтягивает свою бизнес-логику под нее.
Разработки с нуля обычно начинаются там где бизнес-логикой и не пахнет. У них весь бизнес процесс на уровне "здесь играть, здесь не играть, здесь рыбу заворачивали". И когда такой бизнес решается на автоматизацию то жесткие рамки готовых решений не годятся и начинается своя разработка. Но под нее написать тесты практически нереально (смотри описание бизнес-логики).
Ну и во вторых, бизнес-приложения это всегда в первую очередь GUI клиенты для офисного люда. А для GUI тесты делать сложно.

У TDD расшифровка какая? Test Driven Development - уже из названия видно, что тесты стоят во главе всего. Если ты можешь написать автоматизированные тесты для всех частей своего приложения, то TDD будет хорошим выбором. А если с тестами напряг - то и опаньки.
9 июл 15, 21:56    [17874577]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ДохтаР
Member [заблокирован]

Откуда: Новоукраинск
Сообщений: 16864
White Owl
TDD это забавный зверек пригодный для расчетных задач. Но в большинстве случаев мы пишем что-то работающее с пользовательскими интерфейсами, а для этого чрезвычайно сложно создать автоматический тест. Поэтому и TDD распространения не получил.
Но если у тебя задача типа взять один файл и превратить его в другой - то TDD становится чрезвычайно удобным. Можно даже утверждать что для любых конверторов TDD это наиболее естественный процесс разработки.
Но для любых приложений с GUI это уже практически неприменимо.


Я прошу прощения , но последние бестпрактисы
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.

При таком подходе нет проблем использовать TDD для тестировани бизнеслогики.
А Гуй пусть оценивает комиссия по эстетике и морали, на качесто
работы бизнеслогики он влиять не должен.
9 июл 15, 23:19    [17874774]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Relic Hunter
Member

Откуда: AB
Сообщений: 7088
ДохтаР
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.
Протестировали CRUD бизнес логики. Все ОК. В GUI кто-то повесил на кнопку Create обработчик Delete.
9 июл 15, 23:25    [17874787]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
ДохтаР
Я прошу прощения , но последние бестпрактисы
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.
это не бестпрактикс, это идеи теоретиков.
"если текущая дата превышает ожидаемую дату оплаты, то строку поставки необходимо выделить красным цветом" - как тебе такой кейс? и таких кейсов - миллион, и все они - бизнес-логика в гуе.
10 июл 15, 02:24    [17875021]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
scf
Member

Откуда:
Сообщений: 1482
https://www.sql.ru/forum/1136882/pomogite-tankistu-s-tdd
10 июл 15, 09:30    [17875306]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
sphinx_mv
Member [заблокирован]

Откуда:
Сообщений: 1672
egorych
ДохтаР
Я прошу прощения , но последние бестпрактисы
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.
это не бестпрактикс, это идеи теоретиков.
"если текущая дата превышает ожидаемую дату оплаты, то строку поставки необходимо выделить красным цветом" - как тебе такой кейс? и таких кейсов - миллион, и все они - бизнес-логика в гуе.
Бизнес-логика в этом кейсе заканчивается на определении превышения текущей даты над датой поставки.
Раскрашивание пользовательского интерфейса во все цвета радуги к этому никакого отношения не имеет.
Ну и в каком месте находится проблема разделения бизнес-логики и гуя?
10 июл 15, 09:37    [17875337]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
sphinx_mv
Раскрашивание пользовательского интерфейса во все цвета радуги к этому никакого отношения не имеет.
да ладно, а что же это?
10 июл 15, 10:50    [17875625]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
eNose
Member

Откуда:
Сообщений: 183432
egorych
sphinx_mv
Раскрашивание пользовательского интерфейса во все цвета радуги к этому никакого отношения не имеет.
да ладно, а что же это?
информирование
10 июл 15, 10:57    [17875677]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34535
ДохтаР
Я прошу прощения , но последние бестпрактисы
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.

При таком подходе нет проблем использовать TDD для тестировани бизнеслогики.


Очень правильное замечание, но проблема в том, что далеко не всегда "последние бестпрактики" применимы на практике, и
далеко не всегда, даже если они применимы, они применяются.
Да и GUI тестировать тоже надо, ибо порядка 70% ошибок именно в нём. Ну, половина уж точно.

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

Книгу я не подскажу, а автору посоветую не фанатствовать, попадёшь в компанию, где это кровь из носа нужно -- научишься быстро, это не rocket science, там ничего сложного нет. Не попадёшь -- ну и не надо.
10 июл 15, 11:01    [17875694]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Гхостик
Guest
TDD - это про модульное тестирование. Раскрашивание по условию - это функциональное.
10 июл 15, 11:02    [17875702]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
eNose
egorych
пропущено...
да ладно, а что же это?
информирование
то есть, произошло бизнес-событие о котором программа явно должна уведомить бизнес-пользователя, и это не бизнес-логика? ну-ну, я и говорю - теоретики.
10 июл 15, 11:27    [17875835]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
Гхостик
TDD - это про модульное тестирование. Раскрашивание по условию - это функциональное.
вот с этим я согласен. Только получается, что весь проект мы не сможем написать по принципам TDD, что херит, на мой взгляд, всю идею.
10 июл 15, 11:31    [17875855]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
eNose
Member

Откуда:
Сообщений: 183432
egorych
eNose
пропущено...
информирование
то есть, произошло бизнес-событие о котором программа явно должна уведомить бизнес-пользователя, и это не бизнес-логика? ну-ну, я и говорю - теоретики.
система должна уведомить.
а как программа отобразит это - уже дело вкуса.
10 июл 15, 11:33    [17875874]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
eNose
система должна уведомить.
а как программа отобразит это - уже дело вкуса.
то есть, тестировать уже не надо, так, что ли?
10 июл 15, 11:40    [17875909]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
eNose
Member

Откуда:
Сообщений: 183432
egorych
eNose
система должна уведомить.
а как программа отобразит это - уже дело вкуса.
то есть, тестировать уже не надо, так, что ли?
конечно надо.
но это не бизнес-логика.
10 июл 15, 11:43    [17875932]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
eNose
egorych
пропущено...
то есть, тестировать уже не надо, так, что ли?
конечно надо.
но это не бизнес-логика.
опять двадцать-пять. То есть, когда было написано "система должна уведомить" - это была бизнес-логика, а когда определены все ограничения дизайна, пользовательский интерфейс, технологии и прочая-прочая, и пишется конкретный код - вдруг перестало быть бизнес-логикой. Красиво, чё. Зато отделили бизнес-логику от UI, молодцом.
10 июл 15, 11:48    [17875956]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
YesSql
Guest
egorych
ДохтаР
Я прошу прощения , но последние бестпрактисы
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.
это не бестпрактикс, это идеи теоретиков.
"если текущая дата превышает ожидаемую дату оплаты, то строку поставки необходимо выделить красным цветом" - как тебе такой кейс? и таких кейсов - миллион, и все они - бизнес-логика в гуе.

Сдесь не сказано когда. Это например может случиться при нажатии на клавишу "исполнить" - сработает бизнес логика и вернет в Гуй ошибку. по которой он (Гуй) может раскрасить поля или просто скажет боксом - Это уже информирование.
10 июл 15, 12:46    [17876292]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
YesSql
Сдесь не сказано когда. Это например может случиться при нажатии на клавишу "исполнить" - сработает бизнес логика и вернет в Гуй ошибку. по которой он (Гуй) может раскрасить поля или просто скажет боксом - Это уже информирование.
почему то вы считаете, что "информирование" - это какой то отдельный зверь. Информирование - это неотъемлемая часть бизнес-процесса, без которой этот бизнес-процесс не имеет смысла. И как оно может быть не бизнес-логикой, скажите мне пожалуйста?
Конкретная реализация мессаджбокса, грида или другого какого чёрта-в-ступе-для-вывода-сообщений-пользователю, конечно, к бизнес-логике отношения не имеют, а вот его реакция на определённое событие - является.

И вот что я не понимаю возвращаясь, всё же, к заявленной теме - как тут применить TDD, когда программируешь такие кейсы. А ведь именно здесь они и нужны больше всего.
10 июл 15, 13:07    [17876403]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
egorych
Гхостик
TDD - это про модульное тестирование. Раскрашивание по условию - это функциональное.



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

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


Это надо обосновать - почему тестирование только отдельных кусков херит всю идею.

Например в электрический чайник я наливаю воду вручную, но дальше он кипятит чай самостоятельно. Если он облегчает мне часть работы почему бы его не использовать? Так и с тестами. Если я не трогаю UI я могу быть уверен, что не сломаю все в усмерть, если я трогаю, я могу перетестировть руками только UI. Если я сломаю что-то другое, я получу нформацию о том, что именно я сломал.
10 июл 15, 13:24    [17876513]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
egorych
И вот что я не понимаю возвращаясь, всё же, к заявленной теме - как тут применить TDD, когда программируешь такие кейсы. А ведь именно здесь они и нужны больше всего.


абстрагировать UI - объекту отвечающему за бизнес логику подсовывать симуляцию пользовательского ввода, который в ответ на конкретный вопрос выдает заранее записанный ответ.

Прочитайте про MVVM и как там работают с диалогами.
10 июл 15, 13:28    [17876541]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
YesSql
Guest
egorych
YesSql
Сдесь не сказано когда. Это например может случиться при нажатии на клавишу "исполнить" - сработает бизнес логика и вернет в Гуй ошибку. по которой он (Гуй) может раскрасить поля или просто скажет боксом - Это уже информирование.
почему то вы считаете, что "информирование" - это какой то отдельный зверь. Информирование - это неотъемлемая часть бизнес-процесса, без которой этот бизнес-процесс не имеет смысла. И как оно может быть не бизнес-логикой, скажите мне пожалуйста?
Конкретная реализация мессаджбокса, грида или другого какого чёрта-в-ступе-для-вывода-сообщений-пользователю, конечно, к бизнес-логике отношения не имеют, а вот его реакция на определённое событие - является.

И вот что я не понимаю возвращаясь, всё же, к заявленной теме - как тут применить TDD, когда программируешь такие кейсы. А ведь именно здесь они и нужны больше всего.

Да, это часть бизнес логики. Я к тому что можно срезать достаточно тонкий слой Гуя который тестируется вручную.
10 июл 15, 13:35    [17876586]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
YesSql
Я к тому что можно срезать достаточно тонкий слой Гуя который тестируется вручную.
как то у меня получается наоборот. Достаточно тонкий слой вычислений уровня 2+2=4, и толстый-толстый слой гемотогена UI, потому что таких зависимостей одного от другого - до чёрта. И всё тестируется ручками. Куда тут всунуть TDD?
10 июл 15, 13:47    [17876673]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
F#
Это надо обосновать - почему тестирование только отдельных кусков херит всю идею.
Потому что TDD - это методология, сначала пишешь тест, потом рабочий код, который подтверждает, что тест прошёл. Если половина кода опирается на ручное тестирование, то от методологии остаются рожки-да-ножки. На мой взгляд.

F#
Прочитайте про MVVM и как там работают с диалогами.
вот по этому я и привёл кейс, где нет никаких диалогов. Есть большой и толстый грид, динамически меняющийся в зависимости от пользовательского ввода, времени суток, фаз луны и ещё кучи всего того, что бизнес считает важным. Как такое тестировать автоматически и дёшево я понять не могу.
10 июл 15, 13:55    [17876725]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Гхостик
Guest
egorych
Есть большой и толстый грид, динамически меняющийся в зависимости от пользовательского ввода, времени суток, фаз луны и ещё кучи всего того, что бизнес считает важным. Как такое тестировать автоматически и дёшево я понять не могу.

1. Тестируешь запросы. Проверяешь правильность расчета вычисляемого поля: case when sysdate >= pay_date then 1 else 0 end wrong_pay_date
2. Тестируешь gui на правильность отображения стиля по условию, в общем виде. expression(fields, params) -> style
3. Тестируешь результат, это уже вне рамок модульного тестирования, доп. средствами автоматизации тестирования gui либо вручную. Проверяешь, фактически, правильность настройки правила wrong_pay_pate != 0 -> font.color=red

Первые два пункта дают уверенность что отдельные части (модули) работают правильно, тестирование взаимодействия модулей - тестируется отдельно, в соответствии со спецификацией.
10 июл 15, 14:19    [17876877]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
Гхостик
2. Тестируешь gui на правильность отображения стиля по условию, в общем виде. expression(fields, params) -> style
вот это легко написать в общем виде, но очень дорого в смысле создания тестового фреймворка. И я пока не вижу выгоды от его создания. Глазами посмотреть дешевле на порядок. Вот в этом и проблема TDD. Имеет ли смысл в него ввязываться, окупится ли он в обозримом будущем, а не при жизни моих внуков ))
Это как со счётчиками газа. При текущей цене в 10р за месяц время окупаемости его установки приближается к тысячелетию ))
10 июл 15, 14:41    [17877037]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Диез
Member

Откуда: Столица Попозже.
Сообщений: 894
egorych
Гхостик
2. Тестируешь gui на правильность отображения стиля по условию, в общем виде. expression(fields, params) -> style
вот это легко написать в общем виде, но очень дорого в смысле создания тестового фреймворка. И я пока не вижу выгоды от его создания. Глазами посмотреть дешевле на порядок. Вот в этом и проблема TDD. Имеет ли смысл в него ввязываться, окупится ли он в обозримом будущем, а не при жизни моих внуков ))
...


А что тут проблемного? В случае вашего "толстого грида", к каждому объекту (строке то бишь) добавляется enum-атрибут, типа WarningLevel (SUCCESS, WARNING, ERROR...).
В тестах проверяете, что при sysdate >= pay_date значение WarningLevel выставляется в ERROR. Вот и вся бизнес-логика.

А как грид (он же View) будет отображать этот атрибут - дело десятое. Сейчас хотим цветом, потом иконкой, потом заказчик захочет, чтоб пищало... )))
10 июл 15, 16:18    [17877707]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
ТДД - фигня
про гуй уже говорили
а как проверить - правильно ли мой метод рассчитал расписание работ на 50 станков на месяц на 10000 работ?
правильный ли я СКЛ генерирую по модели?
(а про эффективность воще молчу - расписание можно считать 10 часов и 2 минуты, СКЛ может быть компактным или 7этажным)
10 июл 15, 16:58    [17878020]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
хе, взяли тут прогера тира он будет писать автотесты
от он пытается проверить - правильную ли форму сгенерировала прога :)
10 июл 15, 17:01    [17878043]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
egorych
[Если половина кода опирается на ручное тестирование, то от методологии остаются рожки-да-ножки. На мой взгляд.


Если у вас половина кода во view, вероятно у вас там живет и часть бизнес логики или модели представления. Не говоря о том, что view тоже можно тестировать автоматически.

вот по этому я и привёл кейс, где нет никаких диалогов.


Тогда прочитайте про то как тестируют viewmodel безо всяких диалогов.
10 июл 15, 18:51    [17878636]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
ViPRos
ТДД - фигня
про гуй уже говорили


На это уже ответили.

а как проверить - правильно ли мой метод рассчитал расписание работ на 50 станков на месяц на 10000 работ?


Приведите пример функционального требования к модулю, который нельзя проверить меньшим количеством работ и станков.
правильный ли я СКЛ генерирую по модели?


Что такое СКЛ?

(а про эффективность воще молчу - расписание можно считать 10 часов и 2 минуты, СКЛ может быть компактным или 7этажным)


Прочитайте букварь какой-нибудь про TDD чем функциональные требования отличаются от нефункциональных, какие тесты хорошие, какие плохие test smells и т.д.
10 июл 15, 18:58    [17878663]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
F#,

смысл именно в том, что на больше 5 станков и 10 работ чек не сможет вручную составить "правильное" расписание
СКЛ = SQL запрос
видали мы все эти "технологии"
10 июл 15, 19:43    [17878776]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
раньше все проги сдавались на тестовом примере (контрольном), так вот проги кроме этого и не умели ничего
так что проехали это лет 40 назад
10 июл 15, 19:46    [17878786]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
ViPRos
F#,

смысл именно в том, что на больше 5 станков и 10 работ чек не сможет вручную составить "правильное" расписание


При все уважении, это не является примером функционального требования.

СКЛ = SQL запрос


Стендс фор Структуред Квери Лангведж? Ундерстанд!

Вообще говоря, трансляция вполне является классической удобной для тестирования областью. Не думаю, что ваш транслятор модели в SQL сложнее какого-нибудь компилятора C++.
11 июл 15, 09:01    [17879738]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
ViPRos
раньше все проги сдавались на тестовом примере (контрольном), так вот проги кроме этого и не умели ничего
так что проехали это лет 40 назад


А если сдавать без тестовых примеров то не работало вообще ничего?

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


Вообще, автоматическое тестирование не отменяет ручное. Ручное просто сосредатаяивается на usability, поиске новых неизведанных багов, а автомат берет на себя рутину - поиск регрессий например.

Есть интересная книжка How Google tests software - там можно почитать, как они тестируют хром. Причем именно рендеринг страничек. Так что UI тоже поддается автоматизации.
11 июл 15, 09:09    [17879744]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26807
kmaw
White Owl
TDD это забавный зверек пригодный для расчетных задач. Но в большинстве случаев мы пишем что-то работающее с пользовательскими интерфейсами, а для этого чрезвычайно сложно создать автоматический тест. Поэтому и TDD распространения не получил.
Но если у тебя задача типа взять один файл и превратить его в другой - то TDD становится чрезвычайно удобным. Можно даже утверждать что для любых конверторов TDD это наиболее естественный процесс разработки.
Но для любых приложений с GUI это уже практически неприменимо.


Ваш ответ скорее против, чем за TDD, как мне кажется. меня больше интересует, как этот TDD, работает в обычных бизнес-приложениях. там все уже известно - что и как. а бизнес логика - именно то что есть "бизнес-логика" - та часть, которую надо неизбежно говнокодить - как тут это TDD имеет место быть? часто пишут в интернетах: вот контроллер, вот репозиторий. но это как-то мимо все
в обычных бизнес-приложениях работает BDD
11 июл 15, 10:55    [17879812]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26807
egorych
ДохтаР
Я прошу прощения , но последние бестпрактисы
гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.
это не бестпрактикс, это идеи теоретиков.
"если текущая дата превышает ожидаемую дату оплаты, то строку поставки необходимо выделить красным цветом" - как тебе такой кейс? и таких кейсов - миллион, и все они - бизнес-логика в гуе.
Перевести на Gherkin и реализовать тест.

http://rsdn.ru/article/testing/WebTest.xml
11 июл 15, 10:59    [17879818]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26807
F#
egorych
пропущено...



Раскрашиваение по условию вполне тестируется модульным тесто модели представления.
используя Jasmine например
11 июл 15, 11:14    [17879842]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26807
F#
Есть интересная книжка How Google tests software - там можно почитать, как они тестируют хром. Причем именно рендеринг страничек. Так что UI тоже поддается автоматизации.
+1 за книжку :)
11 июл 15, 11:15    [17879849]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
F#, skyANA, спасибо за ссылки
11 июл 15, 18:38    [17880667]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
End-to-end тестированием через UI лучше не увлекаться.

Вот статья Фаулера о том как должна быть утра тестовая пирамида и почему: http://www.martinfowler.com/bliki/TestPyramid.html

Тесты надо уметь писать иначе это будет очень дорогое и не очень эффективное предприятие. Вот книжка про то, как писать тексты хорошо и что делать, если они написаны плохо: http://xunitpatterns.com/ предварительные версии материалов доступны онлайн.

У James Shore есть набор уроков по tdd, которые многие хвалят. Сам не смотрел http://www.jamesshore.com/Blog/Lets-Play/

Многие считают, что основная ценность тестов не собственно в проверке функциональности, а в проверке дизайна: Если трудно писать модульные тесты, значит модели плохо изолированы друг от друга и надо рефакторить.

Есть книжка на тему того, что делать с плохо структурированными программами http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 есть такое перевод книжки на русский
11 июл 15, 19:06    [17880723]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
F#
Многие считают, что основная ценность тестов не собственно в проверке функциональности, а в проверке дизайна: Если трудно писать модульные тесты, значит модели плохо изолированы друг от друга и надо рефакторить.


Именно! В итоге, в погоне за слабой связанностью возникают тысячи интерфейсов, внедряются IoC/DI-фреймворки, количество кода растёт... Иногда это к лучшему, иногда - наоборот.
11 июл 15, 22:43    [17881309]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
Конечно, все надо применять в меру.
12 июл 15, 14:57    [17882451]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

Откуда:
Сообщений: 34544
White Owl
TDD это забавный зверек пригодный для расчетных задач. Но в большинстве случаев мы пишем что-то работающее с пользовательскими интерфейсами, а для этого чрезвычайно сложно создать автоматический тест. Поэтому и TDD распространения не получил.
Но если у тебя задача типа взять один файл и превратить его в другой - то TDD становится чрезвычайно удобным. Можно даже утверждать что для любых конверторов TDD это наиболее естественный процесс разработки.
Но для любых приложений с GUI это уже практически неприменимо.

для танкистов расскажите

слово автоматический тест - это важно или нет?
а если я юнит-тесты руками пишу это тдд?
13 июл 15, 17:30    [17886900]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

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

эта. в чем разница между продуктом и сервисом, в котором тесты не надо писать?
13 июл 15, 17:33    [17886912]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
tchingiz
слово автоматический тест - это важно или нет?
а если я юнит-тесты руками пишу это тдд?
Да писать их можно хоть наемными студентами. А вот запускать эти тесты ты должен каждый раз как сделал изменение в коде. Желаешь делать это ручками? С риском забыть запустить пару-тройку тестов из всей массы подготовленных тестов? Ну вперед и с песней.
13 июл 15, 18:39    [17887172]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

Откуда:
Сообщений: 34544
ок,
не автоматический тест, а автоматически запускаемый тест после модификации кода.

а без автоматического запускания это тдд или нет?
автор
Желаешь делать это ручками? С риском забыть запустить пару-тройку тестов из всей массы подготовленных тестов?

А кому щас легко?

Ну, тут вообще предлагали не писать юнит-тесты.
13 июл 15, 22:13    [17887683]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
f#
Guest
tchingiz,

автор
эта. в чем разница между продуктом и сервисом, в котором тесты не надо писать?


Я вообще слышал что для сервисов и continuous delivery тесты - самое то. Когда надо часто модифицировать тут уж не до стадии стабилизации и автоматическое тестирование очень важно.
13 июл 15, 22:57    [17887850]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
tchingiz
ок,
не автоматический тест, а автоматически запускаемый тест после модификации кода.

а без автоматического запускания это тдд или нет?
Самое смешное, что при известно растягивании терминологии, любая разработка это TDD. Мы с самого начала хотим "чего-то" это уже можно рассматривать как "тест". Мы что-то делаем и прогоняем это через свой "тест" который держим в голове. Удовлетворяет? Не удовлетворяет? Меняем код и попутно подправляем "тест" который продолжаем держать в голове. Таким образом, мы всегда используем Test Driven Development, зачастую не замечая этого.
Но если мы хотим следовать не только духу TDD, но и его букве, то нам придется писать практические тесты. И ставить эти тесты на автомат.

И да, частенько написать действительно практически применимый тест бывает не проще чем написать то что этот тест должен тестировать. А если мы хотим сделать идеальное тестирование NP-полной проблемы то и вообще с тестом придется обломаться.
Поэтому-то TDD и не получил такого уж широкого распространения и так редко применяется.
14 июл 15, 02:33    [17888316]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
f#
Guest
White Owl
.

И да, частенько написать действительно практически применимый тест бывает не проще чем написать то что этот тест должен тестировать. А если мы хотим сделать идеальное тестирование NP-полной * то и вообще с тестом придется обломаться.
Поэтому-то TDD и не получил такого уж широкого распространения и так редко применяется.


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

Я думаю tdd е получил большого распространения потому, что:
* надо уметь их готовить - если писать плохие тесты то от них больше вреда чем пользы (например, если тестировать все сразу, то получается не тест,а "контрольная сумма" - по нему трудно понять какие требование не выполняется,а видел только, что есть какие-то изменения
* надо рефакторить под тесты
* реально внедряется tdd а автоматическое тестирование. В результате тесты пишутся после кода, на дизайн когда не влияют, не помогают в начальной разработке, не формулируют требований а просто фиксируют статус кво.
* по некоторым исследованиям тесты увеличивают время разработки на треть зато в 10 раз снижают плотность ошибок. На этапе разработки проще взять технический долг у будущего и отрапортовать что фича сделана, чем сделать ее качественно, но позже.
14 июл 15, 08:03    [17888440]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Гхостик
Guest
f#
White Owl
Поэтому-то TDD и не получил такого уж широкого распространения и так редко применяется.

надо уметь их готовить
+1.
И научиться этому посложнее чем освоить ещё один язык продолжая писать на нем в привычном старом стиле.
Да ещё и эмоциональная составляющая: отложенное вознаграждение за приложенные сейчас усилия для большинства- слабая мотивация.

Сообщение было отредактировано: 20 июл 15, 15:58
14 июл 15, 08:25    [17888463]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
вощем, в простых случаях - тесты практически не нужны, а в сложных - практически невозможны
14 июл 15, 14:28    [17890310]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
skyANA
Member

Откуда: Зеленоград
Сообщений: 26807
ViPRos
вощем, в простых случаях - тесты практически не нужны, а в сложных - практически невозможны
а между простыми и сложными существует 100500 "оттенков" :)
14 июл 15, 14:44    [17890388]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
skyANA
ViPRos
вощем, в простых случаях - тесты практически не нужны, а в сложных - практически невозможны
а между простыми и сложными существует 100500 "оттенков" :)

оттенки нас не волнуют
если на граничных точках теория дает сбой, то фигня это а не теория, так как граничные точки самые важные (и их всегда можно передвнинуть ближе к центру :)
14 июл 15, 14:49    [17890423]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

Откуда:
Сообщений: 34544
f#
White Owl
.

И да, частенько написать действительно практически применимый тест бывает не проще чем написать то что этот тест должен тестировать. А если мы хотим сделать идеальное тестирование NP-полной * то и вообще с тестом придется обломаться.
Поэтому-то TDD и не получил такого уж широкого распространения и так редко применяется.


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

Я думаю tdd е получил большого распространения потому, что:
* надо уметь их готовить -

помнится монография Майерса Искусство тестирования программ
http://publ.lib.ru/ARCHIVES/M/MAYERS_Glenford_Dj/_Mayers_G.Dj..html#004
произвела большое впечатление
20 июл 15, 16:03    [17913593]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

Откуда:
Сообщений: 34544
White Owl
tchingiz
ок,
не автоматический тест, а автоматически запускаемый тест после модификации кода.

а без автоматического запускания это тдд или нет?
Самое смешное, что при известно растягивании терминологии, любая разработка это TDD. Мы с самого начала хотим "чего-то" это уже можно рассматривать как "тест". Мы что-то делаем и прогоняем это через свой "тест" который держим в голове. Удовлетворяет? Не удовлетворяет? Меняем код и попутно подправляем "тест" который продолжаем держать в голове. Таким образом, мы всегда используем Test Driven Development, зачастую не замечая этого.
Но если мы хотим следовать не только духу TDD, но и его букве, то нам придется писать практические тесты. И ставить эти тесты на автомат.

ээээ, наверно, автоматически выполнить, сравнить и, наверное самое главное, автоматически прокукарекать если не прошел один из тестов.
мой test.cmd



rem версия приложения
app -ver >.app.txt
rem подсказка по юниттесту
app -? >>.app.txt

rem прямое использование SQLite провайдера
rem DataAdapter
app -sqlite -b >>.app.txt
rem DataReader
app -sqlite >>.app.txt

rem используем фабрику SQLite провайдера и абстрактный провайдер
rem DataAdapter
app -sqlite -db -b >>.app.txt
rem DataReader
app -sqlite -db >>.app.txt

rem используем абстрактный провайдер
rem DataAdapter
app -db -b >>.app.txt
rem DataReader
app -db >>.app.txt
не является ТДД
равно как и тулза для тестирования
using System.Data.SQLite провайдера от
Written by Robert Simpson (robert@blackcastlesoft.com)

не есть тдд

К сообщению приложен файл. Размер - 24Kb
20 июл 15, 16:18    [17913673]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
tchingiz
мой test.cmd
...
не является ТДД
TDD это не тест. TDD это метод разработки приложения. Твой тест не является TDD, он является тестом.
Если ты этот тест написал заранее, а теперь правишь свою app чтобы она удовлетворяла этому тесту - тогда можно будет говорить что ты используешь TDD.
20 июл 15, 16:49    [17913854]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

Откуда:
Сообщений: 34544
ок


автор
не является ТДД
читать как
не удовлетворяет ТДД
эээ,
ну, для точности, сначал написал нулевую версию апп.
потом тест.
потом обновляю версию апп и запускаю тест, с возможным его дописыванием
20 июл 15, 17:50    [17914152]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
tchingiz
ок


автор
не является ТДД
читать как
не удовлетворяет ТДД
Нет. Квоть правильно: тест не является TDD.
TDD это технология, это цикл жизни проекта. Это не один отдельный тест и даже не группа тестов. Это правило по которому разрабатывается приложение.

tchingiz
эээ,
ну, для точности, сначал написал нулевую версию апп.
потом тест.
Ну значит все, ты уже нарушил технологию. Начинать надо было с тестов. А теперь уже усё.
21 июл 15, 00:23    [17915091]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
tchingiz
Member

Откуда:
Сообщений: 34544
White Owl
Ну значит все, ты уже нарушил технологию. Начинать надо было с тестов. А теперь уже усё.

вся жизнь пошла прахом.
))
о, это может спасти положение.
Пишешь спецификацию и генериш юниттесты, а потом пишешь код


Fastest

Fastest is a model-based testing tool. The tool receives a Z specification and generates in an almost automatic way, test cases derived from the specification. Currently, it only provides limited functionality for test case refinement into C and Java.
10 авг 15, 12:45    [17998227]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
kmaw
книги/статьи читал. но как-то не проникся. ... есть в этом подходе что-то мне нужное.

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

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

Создать автоматический тест для интерфейса ничуть не сложнее, чем для расчётного модуля. Несильная распространённость TDD имхо вызвана в основном первой "D" - той, что driven. Дело в том, что категорическое требование создавать тесты перед разработкой годится только для хорошо формализованных областей - действительно, в частности, тех же расчётов и конверторов. Для большинства же применений это либо прямой путь к плохому дизайну - и многочисленным рефакторингам до приемлемого состояния - либо просто неудобно. Например, неудобно писать тест типа "заполни поле А и нажми кнопку Б" в тот момент, когда интерфейс ещё не спроектирован и контролы А и Б неизвестны. Если отойти от этого требования, например, в сторону подхода "прототип - тесты - рабочая версия", получается очень даже неплохо.

kmaw
именно то что есть "бизнес-логика" - та часть, которую надо неизбежно говнокодить

Неизбежного говнокода не существует. Существует молчаливое согласие программиста говнокодить в тех или других случаях.

kmaw
как тут это TDD имеет место быть?

Очень даже хорошо. Главное, что нужно понять - что хороший тест есть воплощение какого-либо требования к системе. Да, того требования, которое в теории пишут аналитики, управление требованиями итп. Та "бизнес-логика" по сути состоит из набора требований вида "при таких-то исходных система должна реагировать так-то" - значит, тест вносит эти исходные и проверяет реакцию. Всё просто.

ДохтаР
Я прошу прощения , но последние бестпрактисы гласят что мухи ( гуй ) отдельно , а котлеты ( бизнеслогика ) отдельно.
При таком подходе нет проблем использовать TDD для тестировани бизнеслогики. А Гуй пусть оценивает комиссия по эстетике и морали,

Видите ли, ожидания пользователя от системы формулируются примерно так: "Я ввёл текст, нажал на кнопку - и письмо отправилось". Вы можете великолепно протестировать модуль smtp, но если "текст" оказался read-only, или кнопка не нажимается, или нажимается, но не вызывает нужную smtp-операцию - это провал. Функция не работает, пользователь недоволен, автоматическое тестирование провалилось, программист дурак.

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

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

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

egorych
И вот что я не понимаю возвращаясь, всё же, к заявленной теме - как тут применить TDD, когда программируешь такие кейсы. А ведь именно здесь они и нужны больше всего.

Так и применить. Ввести даты, нажать кнопку и проверить, что строка стала красного цвета. В чём проблема?

F#
Это надо обосновать - почему тестирование только отдельных кусков херит всю идею.

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

F#
Например в электрический чайник я наливаю воду вручную, но дальше он кипятит чай самостоятельно. Если он облегчает мне часть работы почему бы его не использовать?

В самом деле. Пару месяцев назад моя жена купила электрический чайник. У него оказалась клёвая фича - после того, как он вскипятил воду, он не отщёлкивает кнопку, а просто термореле отключает спираль. Минут через пятнадцать он снова включается и снова доводит воду до кипения. И так далее. Вы берёте его, тестируете кусок, вставляете в квартиру - и уезжаете, рассчитывая к возвращению иметь чайник кипячёной воды. А приезжая, обнаруживаете в лучшем случае пустой чайник, а в худшем - пожар. Профит кусочного тестирования!

F#
абстрагировать UI - объекту отвечающему за бизнес логику подсовывать симуляцию пользовательского ввода, который в ответ на конкретный вопрос выдает заранее записанный ответ.

Замечательный способ сделать огромную кучу работы, которая так ничего и не гарантирует. Всего лишь вместо вопроса "правильно ли один вывод подсовывается в интерфейс" останется вопрос "правильно ли другой вывод подсовывается в интерфейс".

ViPRos
а как проверить - правильно ли мой метод рассчитал расписание работ на 50 станков на месяц на 10000 работ?

По требованиям, которые выдвигались к математике метода. В общем так же, как Вы сейчас проверяете вручную - "на одно время и один станок не назначено две разных работы? время простоя меньше 5%? ... все критерии соблюдены? значит, правильно рассчитал"

ViPRos
правильный ли я СКЛ генерирую по модели?

А вот это - яркий и классический пример того, чего вообще не надо проверять. Именно наделав таких тестов, ламеры начинают кричать, что TDD - дерьмо.

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

Посмотрите выше про отправку письма. Пользователя интересует сценарий типа "я вбил получателя "Вася", текст "Ты козёл", нажал кнопку "Отправить" - у Васи всплыло "Ты козёл". Именно этот сценарий и нужно проверять тестом. А реализован ли он через smtp, или через icq, или через sql - пользователю наплевать.

ViPRos
хе, взяли тут прогера тира он будет писать автотесты
от он пытается проверить - правильную ли форму сгенерировала прога :)

Значит, он дурак. Выгоняйте и берите того, кто умеет писать тесты. Не нужно проверять, какую форму сгенерировала прога. Нужно проверять, выполняет ли эта форма те действия, которые от неё требуются.

ViPRos
(а про эффективность воще молчу - расписание можно считать 10 часов и 2 минуты,

Лучше не молчать, а думать. Выкатываете требование считать расписание две минуты - значит, вставьте в тест проверку "время расчёта больше двух минут". Вот не поверю, что это Вам не по силам :)

ViPRos
СКЛ может быть компактным или 7этажным)

А вот на это снова наплевать. Если модуль генерирует SQL - тот должен быть правильным (с точки зрения результатов во всяких ситуациях) и эффективным (с точки зрения выполнения в БД). Ставя критерием компактность - Вы в лучшем случае занимаетесь фигнёй, в худшем - портите программу.

ViPRos
раньше все проги сдавались на тестовом примере (контрольном), так вот проги кроме этого и не умели ничего так что проехали это лет 40 назад

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

F#
Многие считают, что основная ценность тестов не собственно в проверке функциональности, а в проверке дизайна: Если трудно писать модульные тесты, значит модели плохо изолированы друг от друга и надо рефакторить.

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

White Owl
Самое смешное, что при известно растягивании терминологии, любая разработка это TDD. Мы с самого начала хотим "чего-то" это уже можно рассматривать как "тест".

Именно так. "Хотим" - это requirement. Тест - это запрограммированная проверка requirement-а. Именно поэтому автоматические тесты позволяют нам в любой момент понять, насколько система отвечает ожиданиям заказчиков, то есть по сути насколько она близка к завершению разработки. С позиций экстремала-теоретика можно сказать, что набор формализованных требований надо сразу перевести в набор тестов, а далее в тот момент, когда все тесты покажут зелёную галочку - остановить работу и подписать акт сдачи в эксплуатацию.

White Owl
И да, частенько написать действительно практически применимый тест бывает не проще чем написать то что этот тест должен тестировать.

Это в общем не страшно. По моему опыту, хороший тест - даже из тех, что "не проще написать" - окупается уже к моменту сдачи в эксплуатацию, не говоря уже о выгодах во время сопровождения.
20 авг 15, 13:55    [18045707]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
softwarer
egorych
И вот что я не понимаю возвращаясь, всё же, к заявленной теме - как тут применить TDD, когда программируешь такие кейсы. А ведь именно здесь они и нужны больше всего.
Так и применить. Ввести даты, нажать кнопку и проверить, что строка стала красного цвета. В чём проблема?
руками это протестировать - проблем нет, проблема в автоматизации таких тестов.
Однако, мне понравилась вот эта мысль:
softwarer
Несильная распространённость TDD имхо вызвана в основном первой "D" - той, что driven. Дело в том, что категорическое требование создавать тесты перед разработкой годится только для хорошо формализованных областей - действительно, в частности, тех же расчётов и конверторов. Для большинства же применений это либо прямой путь к плохому дизайну - и многочисленным рефакторингам до приемлемого состояния - либо просто неудобно. Например, неудобно писать тест типа "заполни поле А и нажми кнопку Б" в тот момент, когда интерфейс ещё не спроектирован и контролы А и Б неизвестны. Если отойти от этого требования, например, в сторону подхода "прототип - тесты - рабочая версия", получается очень даже неплохо.
буду её обдумывать.
20 авг 15, 14:59    [18046217]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
egorych
руками это протестировать - проблем нет, проблема в автоматизации таких тестов.

Скажу так: уже лет двадцать как мне не приходилось работать с инструментами, где автоматизировать подобный тест было бы серьёзной проблемой. Наверное, такие ещё сохранились, но я с ними как-то не сталкивался.
20 авг 15, 15:30    [18046477]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
egorych
Member

Откуда: и зачем;
Сообщений: 4765
softwarer
Скажу так: уже лет двадцать как мне не приходилось работать с инструментами, где автоматизировать подобный тест было бы серьёзной проблемой.
дело не в инструментах, конечно =))
20 авг 15, 15:40    [18046573]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
White Owl
Самое смешное, что при известно растягивании терминологии, любая разработка это TDD. Мы с самого начала хотим "чего-то" это уже можно рассматривать как "тест". Мы что-то делаем и прогоняем это через свой "тест" который держим в голове. Удовлетворяет? Не удовлетворяет? Меняем код и попутно подправляем "тест" который продолжаем держать в голове. Таким образом, мы всегда используем Test Driven Development, зачастую не замечая этого.

Это слишком обобщённо. Этак можно сказать, что любой школьник использует TDD, когда только собирается начать писать программу и хочет чтобы его будущая софтина была супер-пупер. Нет, о тестах он ещё не знает, но в голове держит: "моя прога - самая крутая". Это - не TDD.
20 авг 15, 17:23    [18047415]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
На мой взгляд, главный миф о TDD - то, что тесты нужно писать раньше кода. Это теоретически невозможно!
Сейчас обосную!

В мелких статейках и бложиках многие программеры, едва познакомившиеся с юнит-тестированием, нахватавшись разных (глупых) идей, начинают кукарекать: сперва тесты, потом код!
Но ни в одной серьёзной нормальной большой статье, а тем более в книгах по тестированию я не встречал такой бред. Если кто знает такую книгу - упомяните.

Да, мне неоднократно пытались доказать, что они сперва пишут тесты, а потом код. При внимательном изучении всегда оказывалось, что это не так. Возможны два случая:
1. В прошлом этот разработчик уже писал похожий код в подобном проекте; поэтому в нынешнем проекте он автоматически переносит куски кода оттуда; в таком случае действительно можно сперва написать тесты, а потом код; но на самом-то деле код уже был написан ранее!
2. Сперва ведётся тщательнейшее проектирование, расписывается до мелочей взаимодействие модулей, всё чуть ли не до локальных переменных определено. Пример такого проектирования описан в книге Крэга Лармана "Применение UML и шаблонов проектирования". Дальнейшая работа сводится к тупому кодированию. Вот теперь, после проектирования, можно написать тесты, а потом код. Но тесты не были первыми! Сперва был проект!

Одной из культовых книг считается "Рефакторинг" Фаулера. Если её почитать, то он по ходу повествования постоянно переносит код из одного метода в другой, потом в другой класс, выносит параметры в поля, потом обратно, через несколько итераций возвращает метод в первоначальный класс, но уже с другими параметрами... Вот как тут писать тесты? Написал и тут же выкинул.
Да, если мы не уверены, что в процессе рефакторинга ничего не сломаем, то сперва нужно написать тесты. Но это на уже работающий код. А если код ещё не работает, даже не компилируется, если мы ищем способ как вообще его написать - о каких тестах может идти речь? А если тесты всё же очевидны, тот тут смотри выше два описанных случая: либо похожий проект писался раньше и поэтому код (большая его часть) заранее известен, либо было проведено тщательное проектирование (сперва проект - затем тест и тупое кодирование).

Или вот, например, презенташка http://blacksheep.parry.org/wp-content/uploads/2010/03/State-of-the-Art-Testability.ppt (Java)
Изначально было три класса. Постепенно, в ходе рефакторинга кода для улучшения тестирования (а также уменьшения связности, внедрения зависимостей и пр.) классов стало восемь. Нужно ли было писать тесты на первые три класса? При условии, что вся эта работа по написанию кода была проведена за один день? Имхо, это бессмысленно, да и невозможно: в первой версии методы внутри себя создают другие классы и их нельзя подменить/замокать.

Можно ли было написать сразу конечную версию с восемью легко тестируемыми классами? Можно! При этом сперва можно (и нужно) написать тесты. Казалось бы, я противоречу сам себе (смотрите тезис в первом абзаце). Но дело в том, что чтобы дойти до такого дизайна нужно сперва наломать кучу дров, написать тысячи строк хрупкого сильносвязанного кода, набить шишки. То есть сперва - код! И лишь затем, по прошествии месяцев или лет, набравшись опыта, научиться сходу проектировать легкотестируемый код. То есть, опять же: вначале по-любому будет код - в голове разработчика, код из предыдущих проектов, из опыта. А тесты - потом.
20 авг 15, 17:53    [18047675]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
Одной из культовых книг считается "Рефакторинг" Фаулера. Если её почитать, то он по ходу повествования постоянно переносит код из одного метода в другой, потом в другой класс, выносит параметры в поля, потом обратно, через несколько итераций возвращает метод в первоначальный класс, но уже с другими параметрами... Вот как тут писать тесты? Написал и тут же выкинул.

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

Хороший тест работает выше уровнем, он проверяет требование к проекту. Как следствие, он меняется вместе с требованиями и в минимальной степени зависит от реализации. Идея инкапсуляции говорит нам, что у объекта есть интерфейс и реализация - так вот, тест работает на уровне интерфейса, причём как правило у довольно высокоуровневых объектов. И вся эта мышиная возня в реализации его не касается; разработчик может выделять методы, классы, переименовывать, объединять, менять алгоритмы - а тест проверяет, что если подать на вход "2*2", на выходе будет "4".

petalvik
Изначально было три класса. Постепенно, в ходе рефакторинга кода для улучшения тестирования

"Рефакторинг для улучшения тестирования" уже означает кривизну тестирования. Можно дальше не смотреть.
20 авг 15, 18:25    [18047845]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
softwarer
На самом деле писать их довольно просто

Халва, халва...

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

softwarer
Хороший тест работает выше уровнем, он проверяет требование к проекту.

О как! Юнит-тесты не считаем?

softwarer
Как следствие, он меняется вместе с требованиями

Заказчик просит: сделать зашибись! Напиши тест.
Я ж говорю: сперва тщательное проектирование, обсуждение с заказчиком, выявление этих самых требований, потом тест. Но не сперва тест, а потом всё остальное.

softwarer
и в минимальной степени зависит от реализации.

Банальный калькулятор. Должен считать 2*2. Идея инкапсуляции говорит нам, что у объекта есть интерфейс и реализация - так вот, тест работает на уровне интерфейса, причём как правило у довольно высокоуровневых объектов. И вся эта мышиная возня в реализации его не касается; разработчик может выделять методы, классы, переименовывать, объединять, менять алгоритмы - а тест проверяет, что если подать на вход "2*2", на выходе будет "4".

petalvik
Изначально было три класса. Постепенно, в ходе рефакторинга кода для улучшения тестирования

"Рефакторинг для улучшения тестирования" уже означает кривизну тестирования. Можно дальше не смотреть.[/quot]
20 авг 15, 18:44    [18047954]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
petalvik
На мой взгляд, главный миф о TDD - то, что тесты нужно писать раньше кода. Это теоретически невозможно!
Сейчас обосную!
Миф? Обосновывать? Учи матчасть! В смысле читай оригинал.

petalvik
Но ни в одной серьёзной нормальной большой статье, а тем более в книгах по тестированию я не встречал такой бред. Если кто знает такую книгу - упомяните.

ISBN 9780321146533
20 авг 15, 18:45    [18047961]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
petalvik,

И вообще, ты можешь конечно спорить с удобством и практичностью TDD, но ты никак не можешь спорить о том что это есть такое.
20 авг 15, 18:48    [18047974]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
Прошу прощения. Модератор, удали, пожалуйста, предыдущее сообщение.

softwarer
На самом деле писать их довольно просто

Халва, халва...
Да, тесты писать легко. Если уже известна архитектура. А откуда она известа? Из опыта предыдущей работы, из опыта написания тысяч строк кода ранее.

softwarer
Хороший тест работает выше уровнем, он проверяет требование к проекту.

О как! Юнит-тесты не считаем?

softwarer
Как следствие, он меняется вместе с требованиями

Заказчик просит: сделать зашибись! Напиши тест.
Я ж говорю: сперва тщательное проектирование, обсуждение с заказчиком, выявление этих самых требований, потом тест. Но не сперва тест, а потом всё остальное.

softwarer
и в минимальной степени зависит от реализации.

Банальный калькулятор. Должен считать 2*2. Какого типа параметры должны быть: int, double, что-то ещё? Если ты сразу можешь это сказать, значит или имеется предыдущий опыт написания похожих проектов (код!!!) или сперва было проведено проектирование.

softwarer
"Рефакторинг для улучшения тестирования" уже означает кривизну тестирования. Можно дальше не смотреть.
В том-то и дело, что сперва было:
softwarer
тесты, слишком погруженные в реализацию
Любой джуниор напишет именно такой код, как в начале. Принципиално нетестируемый.
Мне не сложно, я повторю ещё раз: если разработчик может сходу написать легкотестируемый код, значит за плечами у него несколько лет работы и куча реализованных проектов. Вот на основе кода тех проектов и можно сперва писать тесты.
20 авг 15, 18:51    [18047989]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
White Owl
petalvik,

И вообще, ты можешь конечно спорить с удобством и практичностью TDD, но ты никак не можешь спорить о том что это есть такое.


Прочти внимательно то, что я написал.
Я не спорю с TDD, я сам его использую.

Я оспорил один тезис: то, что сперва пишутся тесты, а потом код.
20 авг 15, 18:53    [18047998]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
White Owl
ISBN 9780321146533

Раздел "Вначале тест (Test First)".
Пример кода оттуда:
Buffer reply = reader.contents();
assertTrue(reader.isClosed());

Сразу возникает вопрос: откуда автор знает, что после выполнения метода reader.contents() сокет закрывается? Значит, он уже писал код (вначале - код!), использующий сокеты, значит штудировал документацию по сокетам (вначале - проектирование!). И лишь потом - тест.

Я повторю в очередной раз: когда гуру программирования и проектирования пишет сперва тест на ещё несуществующий код, это значит, он уже писал ранее похожий код.
20 авг 15, 19:09    [18048065]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
Да, тесты писать легко. Если уже известна архитектура. А откуда она известа? Из опыта предыдущей работы, из опыта написания тысяч строк кода ранее.

Это демагогия. Если разобрать, что обосновывает этот аргумент, то получится примерно "Он доказывает, что программист-юниор не может первым кодом в своей жизни написать тест". Но этот факт в общем малоинтересен :)

А в контексте нашей беседы он вообще не важен. Точно так же, как Вы сфокусировались на одной из деталей TDD, я в своём ответе сфокусировался на одной из деталей Вашей речи. И Ваш тезис выходит за область обсуждения.

petalvik
softwarer
Хороший тест работает выше уровнем, он проверяет требование к проекту.

О как! Юнит-тесты не считаем?

Именно так. 95% кода типичного проекта не нуждается в покрытии юнит-тестами (скорее наоборот - нуждается в их отсутствии). В оставшихся же тесты опять же сосредоточены на интерфейсной части объекта. То есть, если мы, например, хотим протестировать некий класс контейнера (классический пример для юнит-тестов, а по сути - отдельный подпроект внутри основного), мы будем тестировать методы добавления в контейнер, извлечения, поиска итп - то есть его public методы. Но только круглый идиот полезет тестировать его приватные методы, его реализацию. Интерфейс же подобных объектов опять же весьма стабилен. Рефакторинги в основном сосредотачиваются в реализации, редко добавляются или расширяются публичные методы, ещё реже удаляются. Поэтому и тест довольно стабилен и от рефакторингов существенно не ломается.

petalvik
softwarer
Как следствие, он меняется вместе с требованиями

Заказчик просит: сделать зашибись! Напиши тест.
Я ж говорю: сперва тщательное проектирование, обсуждение с заказчиком, выявление этих самых требований, потом тест. Но не сперва тест, а потом всё остальное.

Ты полез в бутылку, не понимая, на что возражаешь.

Ещё раз: при грамотном подходе к тестированию рефакторинг не приводит к постоянной переделке тестов. Что непонятного?
20 авг 15, 19:14    [18048082]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
Я не спорю с TDD, я сам его использую.
Я оспорил один тезис: то, что сперва пишутся тесты, а потом код.

Если бы чукча не был писателем, он бы увидел, что десятком сообщений раньше я оспаривал ровно тот же тезис. Но любой интеллектуально честный человек будет вынужден признать, что если из TDD убрать "tests first", это будет уже не TDD. Это будет некая "методика разработки с использованием автотестов".
20 авг 15, 19:16    [18048089]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
petalvik
White Owl
petalvik,

И вообще, ты можешь конечно спорить с удобством и практичностью TDD, но ты никак не можешь спорить о том что это есть такое.


Прочти внимательно то, что я написал.
Я не спорю с TDD, я сам его использую.

Я оспорил один тезис: то, что сперва пишутся тесты, а потом код.
Ну и зря ты с ним споришь. Этот тезис и является основополагающим принципом TDD. Если ты с этим тезисом споришь, то ты никак не можешь использовать TDD.

Ты можешь использовать тесты в разработке - никаких проблем. Но если ты сначала пишешь код, потом тесты для уже написанного и гоняешь эти тесты чтобы случайно не порушить уже отлаженный кусок, то скорее всего ты используешь IID - Interactive and Incremental Development оно-же "итеративная разработка".

Короче говоря - учи матчасть, потом приходи.
20 авг 15, 19:22    [18048100]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
petalvik
White Owl
ISBN 9780321146533

Раздел "Вначале тест (Test First)".
Пример кода оттуда:
Buffer reply = reader.contents();
assertTrue(reader.isClosed());

Сразу возникает вопрос: откуда автор знает, что после выполнения метода reader.contents() сокет закрывается? Значит, он уже писал код (вначале - код!), использующий сокеты, значит штудировал документацию по сокетам (вначале - проектирование!). И лишь потом - тест.

Я повторю в очередной раз: когда гуру программирования и проектирования пишет сперва тест на ещё несуществующий код, это значит, он уже писал ранее похожий код.
И что?
Мало-ли почему кодер решил написать "такой" тест. Главное: написал он этот тест до того как начал кодировать то что надо тестировать или после. Если ДО, то это TDD, если после, то это уже не TDD а любой другой из множества подходов к организации процесса разработки.
На, почитай: https://en.wikipedia.org/wiki/List_of_software_development_philosophies
Выбирай любой на вкус. Все они могут использовать тесты. В половине тесты обязательны. Но только в Test Driven Development и его потомках тесты надо писать до того как написан код. И совершенно не важно почему был написан именно такой тест а не какой-то другой.
20 авг 15, 19:29    [18048118]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
softwarer
"Он доказывает, что программист-юниор не может первым кодом в своей жизни написать тест".

Вот именно! Джуниор должен накопить опыт, он должен написать кучу кода, а уже потом начать писать сперва тесты. Но это будут тесты на ранее написанный код.

softwarer
Именно так. 95% кода типичного проекта не нуждается в покрытии юнит-тестами (скорее наоборот - нуждается в их отсутствии).

Но дело-то в том, что распространение TDD как раз и получил после начала активного применения юнит-тестирования.

softwarer
Но только круглый идиот полезет тестировать его приватные методы, его реализацию.

Это всё пустые слова. Суть в том, что подавляющее большинство современных языков программирования не позволяют легко и просто тестировать приватные методы. Было бы friend как в C++ - тестировали бы и приватные методы. Ну а нет - значит нет.

softwarer
Интерфейс же подобных объектов опять же весьма стабилен.

Почему он стабилен? Откуда появилась эта стабильность? Из ранее написанных проектов! То есть был написан код, потом не раз переписан, потом интерфейс устаканился. Теперь он стабилен.

softwarer
Рефакторинги в основном сосредотачиваются в реализации, редко добавляются или расширяются публичные методы, ещё реже удаляются.

Тут можно порассуждать о понятиях public (открытый) vs publish (опубликованный). Конечно, когда мы спроектировали (сперва - проект!) интерфейс и опубликовали его, то ломать его не будем. Можно его покрыть тестами.

softwarer
Ты полез в бутылку, не понимая, на что возражаешь.

Повторю в очередной раз: сперва тесты - миф.

softwarer
Ещё раз: при грамотном подходе к тестированию рефакторинг не приводит к постоянной переделке тестов. Что непонятного?

При условии предварительного проектирования, выделения и опубликования интерфейса.
20 авг 15, 19:40    [18048142]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
White Owl
И что?
Мало-ли почему кодер решил написать "такой" тест. Главное: написал он этот тест до того как начал кодировать то что надо тестировать или после. Если ДО, то это TDD, если после, то это уже не TDD а любой другой из множества подходов к организации процесса разработки.

Хорошо. Сперва написали тест. Имеем TDD. Стали писать код. Не получилось. Оказалось, нужно ввести дополнительный параметр в метод (в тесте его нет). Пришлось переписать тест. TDD сразу же исчез?
20 авг 15, 19:48    [18048170]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
Вот именно! Джуниор должен накопить опыт, он должен написать кучу кода, а уже потом начать писать сперва тесты.

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

petalvik
Но дело-то в том, что распространение TDD как раз и получил после начала активного применения юнит-тестирования.

Ошибаешься. Про TDD-подобный подход я читал ещё в книге семидесятых годов, и судя по всему, тогда он был распространённее, чем сейчас (в том числе в силу того, что задачи больше подходили под "тесты готовим заранее"). Другой вопрос, что в наш век маркетингово-активных невежд сплошь и рядом старая идея в чуть осовремененной обёртке выдаётся за новое слово и идеологический прорыв.

petalvik
Это всё пустые слова. Суть в том, что подавляющее большинство современных языков программирования не позволяют легко и просто тестировать приватные методы. Было бы friend как в C++ - тестировали бы и приватные методы. Ну а нет - значит нет.

Глупость. Тестирование реализации - идиотизм вне зависимости от её доступности. А концепция friend - одно из многих плохих проектных решений C++, отчасти перекочевавшее в другие инструменты. Скажем, в Яве, если мне не изменяет память, friend-ануты классы внутри пакета - но тестированием private классов таки вменяемые люди... не увлекаются, назовём так.

petalvik
softwarer
Интерфейс же подобных объектов опять же весьма стабилен.

Почему он стабилен? Откуда появилась эта стабильность? Из ранее написанных проектов!

Да нет, как правило из двух моментов. Во-первых, необходимость такого объекта осознаётся тогда, когда в написанной части проекта просматривается отчётливый "спрос" на него. Как следствие, понятны требования и легко и естественно проектируется интерфейс. Во-вторых, подход "не делать того, что пока не требуется" обеспечивает непоявление того, что не обеспечено спросом и как следствие, было бы первым кандидатом на рефакторинг.

petalvik
Повторю в очередной раз: сперва тесты - миф.

Ты можешь ещё миллион раз это повторить, но надеюсь, лет через пять-десять до тебя дойдёт, что с этим никто не спорит.

petalvik
softwarer
Ещё раз: при грамотном подходе к тестированию рефакторинг не приводит к постоянной переделке тестов. Что непонятного?

При условии предварительного проектирования, выделения и опубликования интерфейса.

Именно так. В той книге, о которой я выше говорил, предлагался такой подход: проектируется интерфейс высокого уровня, реализуется с заглушками, делаются тесты, начинается реализация, проектируются интерфейсы следующего уровня....
20 авг 15, 20:07    [18048226]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
Хорошо. Сперва написали тест. Имеем TDD. Стали писать код. Не получилось. Оказалось, нужно ввести дополнительный параметр в метод (в тесте его нет). Пришлось переписать тест. TDD сразу же исчез?

Да нет, просто программиста (ну или автора примера ;-) надо наказывать за некомпетентность. Описана опасная болезнь под названием "переделка интерфейса в угоду реализации".

В грамотном подходе не может быть "оказалось, что нужно ввести дополнительный параметр". Потому что список параметров - задан требованиями и меняться может только вместе с требованиями. Если согласно требованиям у метода А должен быть один параметр, а реализации в каком-то месте удобно иметь метод А с двумя параметрами - значит, нужно сделать приватный метод А-прим (с двумя параметрами), а из публичного метода А (с одним параметром) его вызывать.
20 авг 15, 20:11    [18048243]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
petalvik
White Owl
И что?
Мало-ли почему кодер решил написать "такой" тест. Главное: написал он этот тест до того как начал кодировать то что надо тестировать или после. Если ДО, то это TDD, если после, то это уже не TDD а любой другой из множества подходов к организации процесса разработки.

Хорошо. Сперва написали тест. Имеем TDD. Стали писать код. Не получилось. Оказалось, нужно ввести дополнительный параметр в метод (в тесте его нет). Пришлось переписать тест. TDD сразу же исчез?
Если этот дополнительный параметр был сначала добавлен в метод, а потом под этот параметр написали тест - то да, исчез.
Для TDD важно что сначала мы делаем тесты, потом кодируем. Если мы решили что в метод надо добавить параметр, то в духе TDD будет сначала исправить существующий тест (или написать дополнительный тест специально для этого параметра), убедиться что этот тест падает, и только потом начать изменять метод.
20 авг 15, 20:11    [18048244]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
White Owl
то в духе TDD будет сначала исправить существующий тест (или написать дополнительный тест специально для этого параметра), убедиться что этот тест падает, и только потом начать изменять метод.

Что-то мне подсказывает, что "этот тест" будет не "падать", а "не компилироваться" :)
20 авг 15, 20:13    [18048251]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
softwarer
petalvik
Хорошо. Сперва написали тест. Имеем TDD. Стали писать код. Не получилось. Оказалось, нужно ввести дополнительный параметр в метод (в тесте его нет). Пришлось переписать тест. TDD сразу же исчез?

Да нет, просто программиста (ну или автора примера ;-) надо наказывать за некомпетентность. Описана опасная болезнь под названием "переделка интерфейса в угоду реализации".
Это совершенно не важно для темы топика.

softwarer
В грамотном подходе не может быть "оказалось, что нужно ввести дополнительный параметр". Потому что список параметров - задан требованиями и меняться может только вместе с требованиями.
Ну так а требования то могут поменяться. С чего ты вдруг решил что новый параметр появился по плохим причинам?


softwarer
Если согласно требованиям у метода А должен быть один параметр, а реализации в каком-то месте удобно иметь метод А с двумя параметрами - значит, нужно сделать приватный метод А-прим (с двумя параметрами), а из публичного метода А (с одним параметром) его вызывать.
Вовсе не обязательно. Речь может идти о новой версии программы, или вообще о форке. Для рефакторинга может существовать множество причин.
20 авг 15, 20:19    [18048266]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
White Owl
Это совершенно не важно для темы топика

Но важно с точки зрения обсуждения приведённого примера - вернее, его бессмысленности.

White Owl
Ну так а требования то могут поменяться.

Конечно, могут. Но не в процессе реализации кода (то есть - не вследствие того, что программист принимает действия по реализации кода, заданного этими требованиями). Источник изменения требований должен быть внешним - заказчику пришла новая хотелка или типа того. Единственный сценарий, когда источник внутри - если в ходе реализации обнаружена ошибка в требованиях. Но это само по себе караул, это значит, что на предыдущих этапах кто-то.. хлопал ушами.
20 авг 15, 20:29    [18048289]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
softwarer
petalvik
Хорошо. Сперва написали тест. Имеем TDD. Стали писать код. Не получилось. Оказалось, нужно ввести дополнительный параметр в метод (в тесте его нет). Пришлось переписать тест. TDD сразу же исчез?

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

Я и говорю: сперва выявление требований, проектирование, затем - тесты. Но тесты не на первом месте.
Ладно, пусть не параметр. Ещё раз этот пример:
Buffer reply = reader.contents();
assertTrue(reader.isClosed());

Внезапно оказалось, что сокет не закрыт. Тест нужно переписать. TDD исчез? Если да, то я согласен: я не практикую TDD. Как и 99,(9)% разработчиков.

softwarer
проектируется интерфейс высокого уровня, ... делаются тесты, ...

Сперва - проект, потом - тесты. Я удовлетворён.
20 авг 15, 20:52    [18048343]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
White Owl
petalvik
Хорошо. Сперва написали тест. Имеем TDD. Стали писать код. Не получилось. Оказалось, нужно ввести дополнительный параметр в метод (в тесте его нет). Пришлось переписать тест. TDD сразу же исчез?
Если этот дополнительный параметр был сначала добавлен в метод, а потом под этот параметр написали тест - то да, исчез.
Для TDD важно что сначала мы делаем тесты, потом кодируем. Если мы решили что в метод надо добавить параметр, то в духе TDD будет сначала исправить существующий тест (или написать дополнительный тест специально для этого параметра), убедиться что этот тест падает, и только потом начать изменять метод.

Договорились. С такой формулировкой согласен.
20 авг 15, 20:55    [18048357]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
Ладно, пусть не параметр. Ещё раз этот пример:
Внезапно оказалось, что сокет не закрыт. Тест нужно переписать.

Это снова изменение требований. Пример в общем не отличается от предыдущего.

petalvik
TDD исчез?

Вы видите где-нибудь в описании TDD запрет на переписывание тестов? Тогда исчез.
20 авг 15, 21:56    [18048566]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
softwarer
Это снова изменение требований.

Нет, требования не изменились, остались прежними. Просто автор теста не знал досконально поведение вызываемого кода/используемой библиотеки.
Знать это поведение он может либо в том случае, когда уже писал код с ней (сперва - код!), либо проведено проектирование с тщательным изучением всего и вся (сперва - проект!). Тест в обоих случаях не первый.
20 авг 15, 22:01    [18048591]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
petalvik
softwarer
Это снова изменение требований.

Нет, требования не изменились, остались прежними. Просто автор теста не знал досконально поведение вызываемого кода/используемой библиотеки.

Всё. TDD исчез

Давайте Вы попробуете объяснить ситуацию - что за код пишет автор, что он тестирует итп? С Вашей точки зрения?
20 авг 15, 22:10    [18048628]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
kmaw
Member [заблокирован]

Откуда: бобруйск
Сообщений: 24786
petalvik
На мой взгляд, главный миф о TDD - то, что тесты нужно писать раньше кода. Это теоретически невозможно!
Сейчас обосную!

В мелких статейках и бложиках многие программеры, едва познакомившиеся с юнит-тестированием, нахватавшись разных (глупых) идей, начинают кукарекать: сперва тесты, потом код!
Но ни в одной серьёзной нормальной большой статье, а тем более в книгах по тестированию я не встречал такой бред. Если кто знает такую книгу - упомяните.

Да, мне неоднократно пытались доказать, что они сперва пишут тесты, а потом код. При внимательном изучении всегда оказывалось, что это не так. Возможны два случая:
1. В прошлом этот разработчик уже писал похожий код в подобном проекте; поэтому в нынешнем проекте он автоматически переносит куски кода оттуда; в таком случае действительно можно сперва написать тесты, а потом код; но на самом-то деле код уже был написан ранее!
2. Сперва ведётся тщательнейшее проектирование, расписывается до мелочей взаимодействие модулей, всё чуть ли не до локальных переменных определено. Пример такого проектирования описан в книге Крэга Лармана "Применение UML и шаблонов проектирования". Дальнейшая работа сводится к тупому кодированию. Вот теперь, после проектирования, можно написать тесты, а потом код. Но тесты не были первыми! Сперва был проект!

Одной из культовых книг считается "Рефакторинг" Фаулера. Если её почитать, то он по ходу повествования постоянно переносит код из одного метода в другой, потом в другой класс, выносит параметры в поля, потом обратно, через несколько итераций возвращает метод в первоначальный класс, но уже с другими параметрами... Вот как тут писать тесты? Написал и тут же выкинул.
Да, если мы не уверены, что в процессе рефакторинга ничего не сломаем, то сперва нужно написать тесты. Но это на уже работающий код. А если код ещё не работает, даже не компилируется, если мы ищем способ как вообще его написать - о каких тестах может идти речь? А если тесты всё же очевидны, тот тут смотри выше два описанных случая: либо похожий проект писался раньше и поэтому код (большая его часть) заранее известен, либо было проведено тщательное проектирование (сперва проект - затем тест и тупое кодирование).

Или вот, например, презенташка http://blacksheep.parry.org/wp-content/uploads/2010/03/State-of-the-Art-Testability.ppt (Java)
Изначально было три класса. Постепенно, в ходе рефакторинга кода для улучшения тестирования (а также уменьшения связности, внедрения зависимостей и пр.) классов стало восемь. Нужно ли было писать тесты на первые три класса? При условии, что вся эта работа по написанию кода была проведена за один день? Имхо, это бессмысленно, да и невозможно: в первой версии методы внутри себя создают другие классы и их нельзя подменить/замокать.

Можно ли было написать сразу конечную версию с восемью легко тестируемыми классами? Можно! При этом сперва можно (и нужно) написать тесты. Казалось бы, я противоречу сам себе (смотрите тезис в первом абзаце). Но дело в том, что чтобы дойти до такого дизайна нужно сперва наломать кучу дров, написать тысячи строк хрупкого сильносвязанного кода, набить шишки. То есть сперва - код! И лишь затем, по прошествии месяцев или лет, набравшись опыта, научиться сходу проектировать легкотестируемый код. То есть, опять же: вначале по-любому будет код - в голове разработчика, код из предыдущих проектов, из опыта. А тесты - потом.



прям мои мысли один в один :)
20 авг 15, 22:46    [18048799]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
softwarer,

я вот работаю программистом около 40 лет
ни разу не видел ТЗ или что то еще его заменяющее, что бы можно было его прямиком перевести на язык программирования
(хотя видел, но это было тогда, когда считали количество использованных ячеек памяти - но там тестировать ничего не надо было, так как постановка практически один в один соответствовала программе на языке)
обычно ТЗ пишется по ходу или по (очередного :)) окончания проекта
обычно проект завершается только тогда, когда инициатор либо увольняется, либо вырастает
конечно я понимаю что проекты касперского или МС можно и через ТДД и через ПДД писать, так как это их Собственная кухня и понимание
но, пробовали бы они таким макаром написать что нить для росатома или алмаза или мценског спирт завода
я не знаю, где ты трудишься (думаю, где то преподавателем), но ты очень далек от народа российского, или мне всю жисть не везло с местом работы
21 авг 15, 01:00    [18049056]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
если я потребую, что надо провести обследование или не дай бог попрошу ТЗ на уровне хотя бы точных хотелок (не формализованных хоть как то , а просто список самых важных), я просто не получу проект
я могу показать ТЗ!!!, от которого ты упадешь со стула
короче - он написал 2 абзаца
я переведу одним предложением - хочу видеть МГНОВЕННО любую интересующую информацию по любому аспекту в любом разрезе
я (мы) согласился(ись)
21 авг 15, 01:14    [18049068]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
mayton
Member

Откуда: loopback
Сообщений: 42897
Мне один бизнес на митинге говорил дескыть. Надо сделать так чтоб "было круто".

Мы кивали головами...
21 авг 15, 12:15    [18050712]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
ViPRos
я вот работаю программистом около 40 лет
ни разу не видел ТЗ или что то еще его заменяющее, что бы можно было его прямиком перевести на язык программирования

Я видел. Правда, один раз, но я видел некий документ с названием "детальная спецификация", полностью и подробно описывающий проект. Так, что получил задание "делаешь пункт 2.3.4 и дальше все подряд сколько успеешь", и после этого пару месяцев по сути никого ни о чём не спрашивал, просто сидел и работал (пока соседи делали другие пункты). Заказчиком была РОСНО, если тебе интересно.

ViPRos
обычно ТЗ пишется по ходу или по (очередного :)) окончания проекта

Есть такое. Именно поэтому я очень ценю комментарии (в программном коде) и тесты. Потому что как раз они и составляют наиболее актуальную и достоверную документацию по проекту. Скажем, у меня был случай, когда клиент собирался принимать проект по галочкам - мол, такой-то пункт тз сделан, такой-то сделан, такой-то сделан. И накануне был жуткий шухер, потому что в ТЗ было написано "сделать нечто", а никто (включая клиента) не мог объяснить, что такое это "нечто" и как это должно работать, но при этом принимать он собирался по галочкам - то есть "нечто сделано? работает?" Будешь смеяться, но в итоге, грубо говоря, сделали кнопку "Сделать нечто", просто выдававшую "ОК", и в таком виде сдали проект. А вот тесты... когда есть тест, и он работает, это говорит, что этот сценарий был кому-то нужен, работающий именно так, и по коду теста обычно даже можно понять - зачем.

ViPRos
обычно проект завершается только тогда, когда инициатор либо увольняется, либо вырастает

Это ты говоришь про внутренние проекты. Когда проект на внешнего заказчика, "бесконечность" не устраивает ни одну из сторон.

ViPRos
конечно я понимаю что проекты касперского или МС можно и через ТДД и через ПДД писать, так как это их Собственная кухня

Здесь ты прав. По Бековским методикам - и по XP, и по TDD - хорошо видно, что они предназначены для внутренних разработок, в которых вопрос "уложить эту функциональность в этот бюджет" в общем не стоит. Именно этим обусловлены их широко критикуемые недостатки и провалы при попытках применить "как написано в книгах".

ViPRos
но, пробовали бы они таким макаром написать что нить для росатома или алмаза или мценског спирт завода

Фи, Сахават.

Знаешь, за последние двадцать лет я не видел ни одного хорошего и разумного подхода к разработке, про который бы те или иные "трудяги от сохи" не высказались бы в стиле "попробовали бы эти теоретики применить это на практике - лоханулись бы так же, как мы, и говнокодили бы так же, как мы". При мне так говорили и про SQL, и про ООП, и про.... в общем, не вспомню про что не говорили. Не стоит присоединяться к этому хочу неудачников.
21 авг 15, 13:16    [18051150]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
scf
Member

Откуда:
Сообщений: 1482
petalvik,

Вы правы и неправы одновременно. Да, разработка начинается с проектирования. Нет, это не означает отказ от тестов.

Тесты вовсе не обязаны быть полными, и выбор того, что именно мы тестируем - это искусство, которое приходит только с опытом.

Вот простейший пример написания куска кода по TDD:
1. Формулируем требования к этому коду. Эти требования не обязательно должны быть полными, но они должны покрывать основные кейсы, без которых этот код неспособен решать свою задачу. Да-да, это фаза проектирования и одно из главных преимуществ TDD - это встраивание явного проектирования в процесс разработки.
2. Пишем интерфейс для реализации сформулированных требований. Обычно это просто функция с параметрами и возвращаемыми значениями
3. На каждое требование готовим тестовые данные, которые его проверяют и пишем тесты
4. пишем реализацию, которая удовлетворяем этим тестам
5. Если есть желание расширить и углубить требования (например, добавить негативные кейсы и угловые случаи) - гоу ту 1.
6. Рефакторинг написанного кода

Главный смысл - итеративность. Проектирование - тесты - код. Проектирование - тесты - код. Почему не проектирование - код - тесты? Потому, что при написании кода после проектирования сложно реализовывать требования по списку, у кода другая структура. А на этапе тестов про эти требования уже все забудут.
21 авг 15, 14:02    [18051472]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ViPRos
Member

Откуда:
Сообщений: 9630
softwarer
ViPRos
но, пробовали бы они таким макаром написать что нить для росатома или алмаза или мценског спирт завода

Фи, Сахават.

Знаешь, за последние двадцать лет я не видел ни одного хорошего и разумного подхода к разработке, про который бы те или иные "трудяги от сохи" не высказались бы в стиле "попробовали бы эти теоретики применить это на практике - лоханулись бы так же, как мы, и говнокодили бы так же, как мы". При мне так говорили и про SQL, и про ООП, и про.... в общем, не вспомню про что не говорили. Не стоит присоединяться к этому хочу неудачников.

уровень заказчиков таких пещерный
с ними невозможно говорить на уровне спецификаций, целостности, непротиворечивости. доказуемости,...,
и они не готовы платить, за обследование, сбор требований. обобщение и формализацию,...,
им "все" (как раз сами не знают что это такое- надеются на красную кнопку или пытаются навязать свои "бест практикс", которое полное УГ) нужно вчера и даром
а нам надо жить и заработать тяжелым трудом на эту жисть
естественно, хотелось бы иметь точные, логичные требования и исходное состояние, а трансформацию бы мы и сами сделали если что (а иногда нужны и четкое описание методов трансформации), тогда можно было бы применить самую подходящую технологию проектирования, т.е. я не против ТДД или там ПДД, но только не с этими ОАО и ГАИ
ладно, слишком много времени на это ТДД потратили
21 авг 15, 18:37    [18053143]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
petalvik
Member

Откуда:
Сообщений: 704
scf
Да, разработка начинается с проектирования. Нет, это не означает отказ от тестов.

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

В целом было полезно пообщаться с оппонентами. За сим позвольте раскланяться.
21 авг 15, 18:56    [18053190]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
ViPRos
уровень заказчиков таких пещерный .... т.е. я не против ТДД или там ПДД, но только не с этими ОАО и ГАИ ....

Знаешь, я убеждён в одной вещи. Заказчик - источник хаоса. Просто потому, что это не профессия. Нет, не сложилось такой профессии как "грамотный заказчик программного продукта". А раз заказчик - источник хаоса, значит где-то между ним и разработчиком должна быть такая точка, где хаос останавливается и дальше - порядок. Эту точку можно называть - РП, аналитик, как угодно, не суть, но она должна быть. В команде разработки должен быть человек, одна из основных обязанностей которого - "хаос кончается на мне". И вся остальная команда работает с этим человеком так, словно он - тот самый идеальный, непещерный заказчик.

Согласен, что это редкость. Но я убеждён, что надо к этому стремиться и строить именно так. Да, нередко хаос доходит до программиста. Даже есть программисты, которые убеждены, что этот хаос - естественное и здоровое состояние, и их профессионализм определяется умением в нём работать. Тут я с тобой согласен... пещерные люди.
21 авг 15, 20:44    [18053467]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
softwarer
F#
Это надо обосновать - почему тестирование только отдельных кусков херит всю идею.

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


Из этого не следует что тестирование отдельных кусков "херит всю идею". Каждое конкретное взаимодействие заключено в каждом конкретном куске. Это раз. Во-вторых, если моя жизнь не состоит из сплошного кипячения чайника, это не значит, что электрочайник это плохая идея.

F#
Например в электрический чайник я наливаю воду вручную, но дальше он кипятит чай самостоятельно. Если он облегчает мне часть работы почему бы его не использовать?

В самом деле. Пару месяцев назад моя жена купила электрический чайник. У него оказалась клёвая фича - после того, как он вскипятил воду, он не отщёлкивает кнопку, а просто термореле отключает спираль. Минут через пятнадцать он снова включается и снова доводит воду до кипения. И так далее. Вы берёте его, тестируете кусок, вставляете в квартиру - и уезжаете, рассчитывая к возвращению иметь чайник кипячёной воды. А приезжая, обнаруживаете в лучшем случае пустой чайник, а в худшем - пожар. Профит кусочного тестирования!


Заметим что тут чайник в качестве аналогии переехал в качество тестируемого объекта из примера кусочной автоматизации.

- Я подразумевал НЕ кусочное тестирование, а кусочную автоматицацию. Не автоматизировать ту часть работы, которую по каким-то причинам сделать трудно - тестировать вручную.

- Если бы было протестировано отщелкивание кнопки отдельно от остального чайника, возможно этой ошибки не было бы.

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


Замечательный способ сделать огромную кучу работы, которая так ничего и не гарантирует. Всего лишь вместо вопроса "правильно ли один вывод подсовывается в интерфейс" останется вопрос "правильно ли другой вывод подсовывается в интерфейс".


Мне кажется, иногда модули делают что-то другое кроме подсовывания выводов.

По моему опыту, в любом случае что-то не будет гарантироваться. Или из-за того, что тестируется не все автоматически, или из за того, что тесты слишком медленные и их будут запускать редко.

Вот статья на эту тему.

Интересно было бы узнать ваш опыт - сколько тестов, как часто они запускаются, насколько часто падение тестов ловит баги, насколько много ложных срабатываний, как обрабатываются нестабильные тесты.
26 авг 15, 10:17    [18068730]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
softwarer
White Owl
то в духе TDD будет сначала исправить существующий тест (или написать дополнительный тест специально для этого параметра), убедиться что этот тест падает, и только потом начать изменять метод.

Что-то мне подсказывает, что "этот тест" будет не "падать", а "не компилироваться" :)


Вообще, TDD, началось на Смолтоке, насколько я помню.
26 авг 15, 10:20    [18068742]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
petalvik
softwarer
Это снова изменение требований.

Нет, требования не изменились, остались прежними. Просто автор теста не знал досконально поведение вызываемого кода/используемой библиотеки.


Тест это требование через пример. Если у автора была идея что сокет должен был непременно закрыт, то это было детальное техническое требование к вызываемому методу. Тест не фиксирует сложившееся положение (кроме специального случая - pinning tests при начале работы с существующем легаси кодом) тест задает требования. Если автор уточнил, что ему не нужен теперь в результате закрытый сокет, а не открытый - это изменения требований. Соответственно изменяется тест. Если автор обнаружил, что окет не закрывается, а должен, это ошибка в коде - несоответствие требованиям - значит надо исправить код.

Знать это поведение он может либо в том случае, когда уже писал код с ней (сперва - код!), либо проведено проектирование с тщательным изучением всего и вся (сперва - проект!).


Не обязаетельно всего и вся. Можно изучать кусочно, постепенно уточняя требования.

Тест в обоих случаях не первый.


Тест никогда не первый вообще. Он просто идет перед production кодом.

В XP, например, используется [url=]spikes[/url] - для изучения чего-то пишется прототип, можно без тестов и в одиночку. Который потом можно выкинуть и полученные знания использовать в production code, написанном в паре и по TDD.
26 авг 15, 10:32    [18068820]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
F#
.. используется spikes - ...
26 авг 15, 10:34    [18068829]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
F#
Из этого не следует что тестирование отдельных кусков "херит всю идею". Каждое конкретное взаимодействие заключено в каждом конкретном куске. Это раз.

Это демагогия примерно того же стиля, что и "тестирование всей программы в совокупности - это тоже вид юнит-теста".

Нет. Каждое конкретное взаимодействие не заключено в каждом конкретном куске кода. Если понимать под куском тот "юнит", который в тестировании - это просто очевидно. Если начать растягивать понимание "куска" - то и тогда ни одно взаимодействие вида "А формирует параметры и передаёт Б, тот их обрабатывает и передаёт В, тот их анализирует и передаёт половину Г, а другую Д" ни одним "куском" не покрывается. И сколько северный варвар ни будет тестировать каждый из этих кусков поотдельности, он не добьётся уверенности в том, что они сработают вместе - ровно так же, как можно до посинения тестировать кирпичи и раствор, а стена всё равно развалится.

F#
Во-вторых, если моя жизнь не состоит из сплошного кипячения чайника, это не значит, что электрочайник это плохая идея.

Электрочайник - это хорошая идея. А вот кусочное тестирование - плохая.

F#
- Если бы было протестировано отщелкивание кнопки отдельно от остального чайника, возможно этой ошибки не было бы.

А почему Вы считаете это ошибкой? Я полагаю, это фича. И тестирование покажет, что она работает.

F#
Я знаю только, что при покупке обычно делают какие-то упрощения. Например, включают и проверяют, теплая ли спираль.

В том и проблема. Покупатель купил чайник, провёл кусочный тест и доволен. А существенная особенность работы (автовключение) осталась за кадром, и поэтому взаимодействие чайника с остальной системой привело к пожару. И никакой кусочный тест предотвратить эту проблему не способен - потому что человек в здравом уме не будет придумывать тесты на "а не включается ли чайник сам", "а не шлёт ли он по ночам шпионские фотоснимки в Пентагон", "а не вылезают ли из него по ночам инопланетяне". Чтобы адекватно предотвратить эту проблему, нужно тестировать систему в совокупности - то есть, в нашей аналогии, не оставлять чайник без присмотра до тех пор, пока присмотр не покажет, что "чайник, оставленный на 8-16-24-48 часов, работает ожидаемым образом, не требуя вмешательства".

F#
Мне кажется, иногда модули делают что-то другое кроме подсовывания выводов.

Иногда, возможно, описанный способ и будет адекватным решением. В данном случае.. соотношение цена-качества кажется мне удручающим.

F#
По моему опыту, в любом случае что-то не будет гарантироваться. Или из-за того, что тестируется не все автоматически, или из за того, что тесты слишком медленные и их будут запускать редко.

Что-то гарантироваться, конечно, не будет - поскольку никогда не будет стопроцентного покрытия итп. Медленные тесты имхо не являются проблемой - поскольку их можно запускать и гонять автоматически, а любой вопрос "медленности" решается масштабированием. Грубо говоря, у меня в конторе штук тридцать-сорок девелоперских компов. То есть, условно, собрав ночной билд в час ночи, скрипт может запустить тесты примерно на восемь-десять суток суммарной продолжительностью, и к моменту прихода разработчиков результаты будут готовы. Думаете, не хватит?

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

F#
Вот статья на эту тему.

Если вкратце, то я с ней не согласен. При этом вполне допускаю, что она разумна в тех условиях, для которых писалась. Скажем, условно, если проектом является разработка Chrome, то вполне очевидно, что подавляющее большинство тестов не стоит пускать через интерфейс. Грубо говоря, через интерфейс надо протестировать, что "javascript в html запускается и приводит к нужным видимым изменениям", но при этом незачем тестировать через интерфейс правильность работы каждой фичи javascript-движка.

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

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

Сколько тестов - вопрос практически бессмысленный. Просто для примера, на одном из проектов тестеры размахали сценарий, который шёл часа полтора - он был оформлен как один тест, но включал в себя добрую половину функциональности приложения. Я тогда на них зверски ругался, потому что, конечно, удобнее было бы иметь его в виде нескольких десятков более мелких, но они ответили - это основной бизнес-процесс заказчика, и мы хотим быть уверенными, что пользователь, севший за компьютер, сможет пройти его от начала до конца со всеми закоулками без единого сбоя, скажем без Out of memory в середине работы. Ответить мне оказалось нечего - собственно, это тот же самый пример про чайник. А в терминах юнит-тестов... этот единственный сценарий, наверное, равнялся нескольким тысячам.

Как часто запускается... в том самом наиболее покрытом и тяжёлом проекте полное тестирование запускалось где-то от одного до пяти раз в неделю, ну а выборочные - невозможно посчитать. Задним числом я думаю, что надо было бы внедрить ночные сборки и автоматический прогон тестов, но этого не было. В принципе, расклад был следующим:

Когда проект начинался, я настоял на недельных итерациях (руководство продавливало ежемесячные). В пятницу вечером выпускался release candidate, дальше в течение недели его мучили тестировщики и он шёл на production. Я внедрил автоматическое тестирование сначала локально в рамках разработки, потом, когда оно дошло до удовлетворительного состояния, подключили тестировщиков. Технология вышла такой: release candidate собирался в пятницу утром, прогонялось полное тестирование. Если оно находило проблемы - мелкое решалось на месте, крупное откатывалось, в общем в пятницу вечером гарантированно собирался release candidate, проходящий существующие тесты (старые и дописанные разработчиками для новых фич). В понедельник за него брались тестировщики, гоняли руками и писали тесты (новые либо дописывали и расцвечивали тесты, начатые разработчиками). Обычно, где-то к среде они давали добро на его выпуск в production и переключались на другие проекты. Если тестировщики находили что-то, что нужно было исправить до выпуска релиза - соответственно, выпускался новый кандидат и ещё раз прогонялось полное тестирование.

Насколько часто падение тестов ловит баги... вопрос ставит меня в тупик. Скажу так: я считаю ЧП случай, когда падение теста не ловит багу :) Собственно, я полагаю, что любое падение теста ловит багу либо в приложении, либо в тесте (который тоже часть приложения). Если вопрос в том, как часто ошибку ловят тесты, а как часто - другие источники... зависит от покрытия, конечно. В тех частях приложений, которые я полагаю адекватно покрытыми тестами, "проскользнувшие баги" находятся редко. Бывает в основном на начальной стадии, когда набирается опыт "что именно и как вообще надо тестировать в этой задаче".

Нестабильные тесты.... с такой проблемой я столкнулся только при использовании Selenium. Cразу скажу, при всей замечательности этого продукта использовать его "из коробки" практически невозможно. Я быстро пришёл к необходимости написать к нему оболочку, использующий его фреймворк, который предоставлял бы разработчику вменяемый и доступный к использованию интерфейс. Так вот, нестабильные тесты были следствием таких проблем, как

- проблемы самого Selenium-а (текущей версии)
- проблемы браузера (текущей версии)
- проблемы взаимодействия текущей версии Selenium-а с текущей версией браузера
- проблемы моего фреймворка-оболочки.

Особенно в этом смысле радовал Firefox, после обновления которого регулярно начинали валиться здоровые рабочие тесты. Соответственно, решалось примерно так:

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

Здесь, конечно, подразумевается не ситуция "приложение валится в новой версии браузера", а "приложение в этой версии браузера нормально работает, а вот тесты по какой-то причине стабильно либо нестабильно валятся".
26 авг 15, 13:41    [18070219]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
Короче говоря, если кому-то таки интересно про TDD :) Как раз нарисовался маленький пример, как я его понимаю.

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

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

Появляется требование (вернее, моё желание): проверить, что приложение адекватно поведёт себя, если в том или ином его месте случится неожиданная ошибка. Адекватное поведение - как минимум, означает, что после этого приложение сохранит способность обработать следующие вызовы и дать на них верные ответы.

Для этого я вставляю в клиентскую библиотеку новую команду (simulateError), вставляю в тесты её вызовы с теми параметрами, которые собираюсь использовать. Тестирование начинает ожидаемо сигнализировать о проблемах (в основном ответ сервера "команда simulate error не распознана"). Дальше я дописываю в сервер код, который по приходу этой команды взводит флажки вида "имитируй ошибку там", "имитируй ошибку здесь" итп. Соответственно, тестирование начинает падать по-крупному (довожу до того, что сервисное приложение перестаёт принимать команды вообще из-за падения одного из потоков).

Ну и наконец, вот сейчас начну дописывать приложение так, чтобы оно выдерживало подобные удары.
26 авг 15, 14:34    [18070537]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
softwarer
добьётся уверенности в том, что они сработают вместе - ровно так же, как можно до посинения тестировать кирпичи и раствор, а стена всё равно развалится.


Кирпичи, раствор и детальный чертеж постройки (т.к. у нас робот который собирает здание).


F#
Во-вторых, если моя жизнь не состоит из сплошного кипячения чайника, это не значит, что электрочайник это плохая идея.

Электрочайник - это хорошая идея. А вот кусочное тестирование - плохая.


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

F#
- Если бы было протестировано отщелкивание кнопки отдельно от остального чайника, возможно этой ошибки не было бы.

А почему Вы считаете это ошибкой? Я полагаю, это фича. И тестирование покажет, что она работает.


Если это фича - тогда чем вы недовольны?



В том и проблема. Покупатель купил чайник, провёл кусочный тест и доволен. А существенная особенность работы (автовключение) осталась за кадром, и поэтому взаимодействие чайника с остальной системой привело к пожару.


Начните тестировать каждый чайник при покупке с водой - или вы это так уже делаете? А если нет, то почему?

И никакой кусочный тест предотвратить эту проблему не способен - потому что человек в здравом уме не будет придумывать тесты на "а не включается ли чайник сам", "а не шлёт ли он по ночам шпионские фотоснимки в Пентагон", "а не вылезают ли из него по ночам инопланетяне". Чтобы адекватно предотвратить эту проблему, нужно тестировать систему в совокупности - то есть, в нашей аналогии, не оставлять чайник без присмотра до тех пор, пока присмотр не покажет, что "чайник, оставленный на 8-16-24-48 часов, работает ожидаемым образом, не требуя вмешательства".


Никто не спорит с необходимостью тестировать продукт целиком. Вопрос в том, надо ли это автоматизировать и насколько сильно.

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


Я бы предпочел, чтобы код, который рушит тесты просто не прошел gated check-in. Не хотелось бы, чтобы он был раз в 8-9 суток.
Еще хотелось бы чтобы упавший тест как можно быстрее показал, где именно произошла ошибка.

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


Я тоже за это. Плюс еще цена.

Когда проект начинался, я настоял на недельных итерациях (руководство продавливало ежемесячные).


Спасибо за рассказ, интересно.

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


Если тесты запускаются реже, чем каждый коммит, не бывает ли такого, что разработчик A внес правильное изменение, но забыл исправить и проверить тест Б. После чего прошло несколько дней и при прогоне всех тестов выявляется что тест Б красный после чего приходится исследовать причину и оказывается что софт рабочий, но надо выискивать где именно поправить тест. В результате:
1) Отсутствует уверенность в том, где баги есть, а где их нет
2) На падение тестов начинают смотреть сквозь пальцы.
26 авг 15, 15:00    [18070697]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
F#
softwarer
пропущено...

Что-то мне подсказывает, что "этот тест" будет не "падать", а "не компилироваться" :)


Вообще, TDD, началось на Смолтоке, насколько я помню.
Вообще-то, TDD началось на java.
26 авг 15, 15:45    [18071070]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
F#
Кирпичи, раствор и детальный чертеж постройки (т.к. у нас робот который собирает здание)

Чтобы протестировать "детальный чертёж постройки", надо выйти за пределы юнит-тестирования.

F#
Перечитайте ваше собственно сообщение - вы аргументировали бесполезность юнит тестирования тем,

Уже неверно. Я аргументировал "почему тестирование только отдельных кусков херит всю идею" (с) 17876513. То есть обосновываю, что в общем случае "одних юнит-тестов" принципиально и категорически недостаточно. Попутно я утверждаю, что юнит-тесты - не являются самыми важными, и упор на них основного внимания является ошибкой.

F#
Даже если это так, то оптимизировать поиск меньшего количества багов тоже может быть полезно.

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

В качестве условного примера - давайте предположим, что наше приложение должно позволить пользователю ввести две даты и если первая больше второй, зажечь красную лампочку. Приложение реализовано в виде формы, создаваемой средствами какой-нибудь стандартной библиотеки, и контроллера, сравнивающего даты и возвращающего -1, 0 или 1.

В такой ситуации тест через интерфейс имхо обязателен и эффективен. Во-первых, он позволяет проверить работоспособность двух основных интересующих пользователя сценариев: "лампочка зажглась, когда нужно" и "лампочка не зажглась, когда не нужно". Во-вторых, с минимальными усилиями проверяются, а то и вовсе случайно вскрываются мелкие проблемные ситуации, например: как приложение работает, когда одна из дат введена, а другая - нет? Как приложение работает, если дата введена в виде 1.1.15? А горит ли лампочка, если пользователь ввёл день и месяц, а год ещё не успел? Итп. Как ни странно, именно так вскрывается уйма проблем, которые реально мешают пользователю. Ну например: допустим, всё работало. Потом вышла новая версия библиотеки, или наш программист приписал новую крутую фичу - подстановку во вторую дату года из первой, если он не указан. Он её протестировал, всё хорошо и он доволен жизнью - а тест показывает, что пользователь вводит первую дату "01.01.2015", начинает вводить вторую "29.02" - и внезапно вываливается идиотское сообщение "2015-й год невисокосный, введённая дата неверна".

Давайте теперь рассмотрим варианты. Юнит-тест контроллера, может быть, и не помешает, но и не сказать, что поможет. До тех пор, пока мы не начнём развивать его в нечто крутое, умеющее сравнивать юлианские, григорианские, японские, еврейские и прочие календари, смысла в нём практически нет. Ошибку он почти наверняка не найдёт никогда, даже если найдёт - её вес будет мал, а те случаи, которые таки надо проверить - несложно вставить и в интерфейсный тест и протестировать в боевых условиях в совокупности.

А самое интересное - взаимодействие. Да, Вы можете, как предлагаете, написать заглушку, которая будет имитировать интерфейс. Да, Вы можете через неё подать введённые даты и проверить, появляется ли true в поле "горит лампочка". Да, возможно, Вам даже удастся сделать тесты на моменты типа отличия дат 1.1.15 и 01.01.2015. Но во-первых, писать такую заглушку - нехилая трудоёмкость (на фоне общей для этого приложения и его тестов). Во-вторых, когда программист припишет свою крутую фичу - заглушку придётся модифицировать, чтобы она её учитывала. А в-третьих - багу с "дата неверна" заглушка всё равно не отловит! Просто потому, что её автор - в отличие от автора визуальной библиотеки - эту ситуацию не проверяет или проверяет иначе. То есть, с одной стороны потратили кучу сил, с другой - бага таки доехала до пользователя.

Поэтому я и полагаю, что надо соразмерять широту отлавливаемых проблем, усилия на написание теста и усилия на его дальнейшее сопровождение. И в том, что касается юнит-тестов - я считаю, что ими стоит покрывать более-менее стандартные, переиспользуемые модули. Те, в которых рано или поздно возникнут все кривые ситуации, какие только могут быть. Если же код прикладной, используется один раз по месту, обкладывать его юнит-тестами - сизифов труд. То, что в нём работает "маршрут, которым он используется в приложении" - покажет интегральный тест, а никакие другие в нём и не нужны - этот код будет выброшен либо переработан (вместе с тестами) в тот самый момент, когда эти другие маршруты потребуются.

F#
Если это фича - тогда чем вы недовольны?

Я недоволен? Я как раз доволен.

F#
Начните тестировать каждый чайник при покупке с водой - или вы это так уже делаете? А если нет, то почему?

Так и тест с водой не избавит от описанного пожара.

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

F#
Никто не спорит с необходимостью тестировать продукт целиком. Вопрос в том, надо ли это автоматизировать и насколько сильно.

(Пожимая плечами) Надо ли автоматизировать основную и наиболее важную часть тестирования? Этот вопрос эквивалентен вопросу "надо ли автоматизировать тестирование вообще". Мой ответ - уверенное "да". То есть даже при наличии тестировщиков, потенциально готовых руками гонять регрессии, я полагаю это неэффективным.

F#
Я бы предпочел, чтобы код, который рушит тесты просто не прошел gated check-in. Не хотелось бы, чтобы он был раз в 8-9 суток.

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

F#
Еще хотелось бы чтобы упавший тест как можно быстрее показал, где именно произошла ошибка.

Это несерьёзно. Где именно произошла ошибка - и так видно по логу и/или стектрейсу. Почему она произошла - в мало-мальски нетривиальных случаях придётся садиться в отладчик и смотреть. В любом случае, если тест прошёл ассерт номер N и свалился на ассерте N+1 - работа скорее всего начнётся с "поставить брейкпоинт на N-й ассерт и начать разбираться", и от формы и размера теста это практически не зависит.

F#
Если тесты запускаются реже, чем каждый коммит, не бывает ли такого, что ..... В результате:
1) Отсутствует уверенность в том, где баги есть, а где их нет
2) На падение тестов начинают смотреть сквозь пальцы.

Как минимум я никогда не буду смотреть на падение тестов сквозь пальцы. Одна из причин "временного исключения нестабильных тестов", о котором я говорил - как раз в том, что "тесты должны быть зелёными".

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

А бывает ли такое... я не совсем понял вопрос, попробую ответить так. Если речь идёт об области ответственности программиста А - его модуле, его тестах итп - то, в общем, его дело, что и как запускать, от него ожидается проверенный результат. Тесты перед билдом подстрахуют от его забывчивости, но сама по себе ситуация маловероятная. Не скажу, бывало такое или нет, не помню. Может, когда и было.

Если речь о том, что изменение программиста А обваливает какие-то тесты в зоне ответственности программиста Б - то тут в любом случае надо разбираться. Вовсе не факт, что это ошибка А, что она в модуле А и что исправлять должен именно А. Но вообще тут возможны два случая:

а) Ошибка достаточно близко, к примеру, один из модулей вызывает другой. Тогда срабатывает интегральность тестов - скажем, у них будет просто общий тест и, соответственно, А его проверит и обнаружит проблему.

б) Ошибка далеко, срабатывает какая-то мерзкая нетривиальная бяка. В этот момент я возношу хвалу своей предусмотрительности за то, что тесты перед билдом не пропустили её к пользователю. При этом отмечу, что никакие "быстрые автотесты в момент коммита" отловить такую заведомо не способны.
26 авг 15, 16:09    [18071291]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
White Owl
I often hear, "Of course. How else could you program?"

ну, да.

Сообщение было отредактировано: 27 авг 15, 21:56
26 авг 15, 16:51    [18071625]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
White Owl
Member

Откуда:
Сообщений: 12418
F#
White Owl
Вообще-то, TDD началось на java.


Википедия ссылается на

http://www.quora.com/Why-does-Kent-Beck-refer-to-the-rediscovery-of-test-driven-development

The original description of TDD was in an ancient book about programming. It said you take the input tape, manually type in the output tape you expect, then program until the actual output tape matches the expected output. After I'd written the first xUnit framework in Smalltalk I remembered reading this and tried it out. That was the origin of TDD for me. When describing TDD to older programmers, I often hear, "Of course. How else could you program?" Therefore I refer to my role as "rediscovering" TDD.
Забавно.... Ну Ок.
26 авг 15, 18:20    [18072275]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
softwarer
В качестве условного примера - давайте предположим, что наше приложение должно позволить пользователю ввести две даты и если первая больше второй, зажечь красную лампочку. Приложение реализовано в виде формы, создаваемой средствами какой-нибудь стандартной библиотеки, и контроллера, сравнивающего даты и возвращающего -1, 0 или 1.
В такой ситуации тест через интерфейс имхо обязателен и эффективен.


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

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


Во-первых, мы будем знать, что контроллер уж точно работает.
Во-вторых, есть масса идиотских ошибок/описок которые он будет вылавливать и так.

Можно также сделать тест на viewmodel и focused integration tests на view.

Если End2End написать достаточно просто, то конечно, можно начать и с него.

А самое интересное - взаимодействие. Да, Вы можете, как предлагаете, написать заглушку, которая будет имитировать интерфейс. Да, Вы можете через неё подать введённые даты и проверить, появляется ли true в поле "горит лампочка". Да, возможно, Вам даже удастся сделать тесты на моменты типа отличия дат 1.1.15 и 01.01.2015. Но во-первых, писать такую заглушку - нехилая трудоёмкость (на фоне общей для этого приложения и его тестов).


Как только мы начнем переиспользовать преобразование строки в дату, эти отдельные тесты начнут окупаться. Нам не надо будет в каждом конкретном случае проверять как действует 1.1.12 и 01.01.2015 - мы просто будем знать, что преобразование дат работает как положено и не тестировать UI framework во всех местах, где он применяется.

Во-вторых, когда программист припишет свою крутую фичу - заглушку придётся модифицировать, чтобы она её учитывала. А в-третьих - багу с "дата неверна" заглушка всё равно не отловит! Просто потому, что её автор - в отличие от автора визуальной библиотеки - эту ситуацию не проверяет или проверяет иначе. То есть, с одной стороны потратили кучу сил, с другой - бага таки доехала до пользователя.


Для тестирования таких ситуаций, наверное, можно использовать интеграционные тесты например пристегнув временное хранилище. Хотя по моему опыту такие штуки (связанные с UI в динамике и не отловленные при первом ручном прогоне) скорее находят при exploratory тестировании просто потому, что они обычно находятся вдали от основных сценариев.

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


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

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


Я в магазине это не узнаю, просто покупаю и несу домой - а дальше test in production :)

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


Я думаю, то тут вопрос в соотношении вероятностей - все не протестируешь. Если тесты гоняются раз в несколько дней, то есть вероятность, что после последнего прогона закоммитили что-то ломающее тесты. К тому же end-to-end тесты неточно показывают место, где произошла ошибка и поиск конкретного место может занять время. Проще не коммитить ошибок чем их потом искать.

С другой стороны, если сделать UI очень тонким, то вероятность сделать в нем ошибку сильно уменьшается. Особенно сделать регрессию. Например после связывания кнопки "Назад" с командой "Назад" маловероятно, что ее кто-то поменяет на "Вперед".

Возможно вам встречалось больше кода, связаного именно с логикой пользовательского интерфейса, чем мне.

Это несерьёзно. Где именно произошла ошибка - и так видно по логу и/или стектрейсу.


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

Почему она произошла - в мало-мальски нетривиальных случаях придётся садиться в отладчик и смотреть. В любом случае, если тест прошёл ассерт номер N и свалился на ассерте N+1 - работа скорее всего начнётся с "поставить брейкпоинт на N-й ассерт и начать разбираться", и от формы и размера теста это практически не зависит.


Зависит. Если есть включает в себя много последовательных шагов, то, очевидно, ошибку найти труднее чем если там 1 шаг с подготовленными данными. Хороший юнит тест не валится, если ошибка произошла в другом юните. А так как их можно запускать очень часто (посмотрите, например, ролик на http://www.ncrunch.net/ - там прямо в процессе написания, они гоняются фоном) и они детально показывают какие ожидания не оправдались, то иногда не надо даже отладки - просто сопоставить, что делал недавно и какой тест упал.

Как минимум я никогда не буду смотреть на падение тестов сквозь пальцы. Одна из причин "временного исключения нестабильных тестов", о котором я говорил - как раз в том, что "тесты должны быть зелёными".

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


Тут мне видится противоречие - либо мы не исключаем нестабильные тесты и не говорим что 100% гарантии не может дать никто, либо таки мы немного беременны. И еще надо запускать все тесты перед каждым изменением - иначе в промежутке междц запуском мы тоже не можем быть уверены.

В-общем, вашу точку я понимаю, но сам склоняюсь, скорее к тестовой пирамиде - немного End-to-end тестов с основными сценариями, некоторое количество integration и много детальных unit - как описано у Фаулера и Шора.
27 авг 15, 00:26    [18073942]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
White Owl
Забавно.... Ну Ок.


Закономерно - в динамических языках нет проверки типов при компиляции, которая ловит много глупых ошибок, при этом цикл red-green-refactor может быть гораздо короче (из за того же отсутствия компиляции).
27 авг 15, 00:29    [18073954]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
F#
С моей точки зрения, ответ на этот вопрос зависит от того, сколько будет стоить поддержка UI теста.

Пожму плечами.

public class ДвеДаты extends AbstractWebTest {
  @Test public void Лампочка() {
    Selenium.inputString('date-from', '01.01.2000');
    Selenium.inputString('date-to', '01.01.2001');
    assertTrue("Лампочка горит когда не надо", !Selenium.get('bulb').isVisible());
    Selenium.inputString('date-from', '01.01.2002');
    assertTrue("Лампочка не горит когда надо", Selenium.get('bulb').isVisible());
  }
}

По-моему, не очень дорого.

F#
Если фреймворк такой, что это дорого и неудобно, вполне возможно обойтись и юнит тестом.

Честно говоря, я не представляю себе настолько ужасного фреймворка, чтобы юнит-тесты хоть как-то конкурировали по "дёшево и удобно". Впрочем... пример выше, конечно, не является достаточно полным тестированием нашего условного приложения, но представление даёт. Если хотите - набросайте код юнит-тестов, которые дадут сравнимую с этими пятью строками уверенность в его работоспособности :)

F#
Так же интересно знать во скольких еще местах используется этот контроллер.

В одном, конечно. У нас приложение из одной формы, больше просто негде. Но раз уж хотите идти в эту степь - обратите внимание, что юнит-тесты придётся переделывать при рефакторингах, а приведённый выше тест останется неизменным. В этом его гигантское с моей точки зрения достоинство - не столько в трудоёмкости (хотя и это тоже), но в первую очередь в том, что его стабильность подтверждает - новое приложение работает не хуже старого, проходит тесты старого. После переделки тестов такой уверенности нет - есть лишь уверенность в том, что оно проходит переделанные, возможно неполные или ошибочные тесты.

F#
UI тесты для всех них будут зазря гонять одно и то же.

(Пожимая плечами) Вы бьётесь за экономию электричества?

F#
Во-первых, мы будем знать, что контроллер уж точно работает.

Это знание не несёт практической ценности. Когда клиент приходит и говорит "Ваша программа, вашу мать, не работает", слова "ну контроллер-то точно работает" как-то не утешают.

F#
Во-вторых, есть масса идиотских ошибок/описок которые он будет вылавливать и так.

Например?

F#
Можно также сделать тест на viewmodel и focused integration tests на view.

Можно всё. Но прикиньте трудоёмкость и сравните уверенность после. Честно говоря, я почти уверен, что если напишете пример - мы посмотрим в портянку и я назову парочку случаев, которые мой сценарий покрывает, а она - нет.

F#
Если End2End написать достаточно просто, то конечно, можно начать и с него.

В данном случае я не вижу причин писать что-либо кроме него.

F#
Как только мы начнем переиспользовать преобразование строки в дату, эти отдельные тесты начнут окупаться.

Какие "эти"?

Если Вы напишете преобразование строки в дату и протестируете его, это не даст Вам вообще ничего, потому что в интерфейсных библиотеках им обычно занимается визуальный компонент (предположительно, написанный не вами). Более того, довольно часто в ходе разработки и сопровождения визуальная библиотека обновляется, расширяется или даже заменяется. Поэтому расклад очень прост: если в проекте продуманная архитектура и строгая дисциплина - такие вещи достаточно протестировать "визуально через компонент" в одном месте. Если дисциплины недостаточно - любое применение компонента, не закрытое проверками, потенциально дыряво.

F#
Для тестирования таких ситуаций, наверное, можно использовать интеграционные тесты например пристегнув временное хранилище.

А смысл? "Пристегнув временное хранилище" - это куча трудоёмкости, а проблему оно всё равно не отловит - потому что временное хранилище работает "как его написали Вы", а не "как работает используемый в приложении компонент".

F#
Хотя по моему опыту такие штуки (связанные с UI в динамике и не отловленные при первом ручном прогоне) скорее находят при exploratory тестировании просто потому, что они обычно находятся вдали от основных сценариев.

Когда бы и как бы их ни находили, от них надо защищаться. Скажем, опытный тестировщик такой тест вставит сразу - потому что уже напарывался и знает, что с этим может быть проблема, да и вообще, что особые случаи всегда надо проверять. Но! Вопрос в том, что этот тест через интерфейс проблему отловит всегда - как только она появится, например, после смены версии библиотеки компонент. "Временное хранилище" эту проблему не отловит вообще никогда, просто потому, что в нём нельзя закодировать "работай как вот такой компонент".

F#
Имхо, если бизнес-логика смоделированна в терминах близких к предметной области, то после разработки бизнес объектов получается достаточно устойчивый набор модулей для которого просто писать тестовые сценарии, причем как при подготовке тестовых предусловий, так и для проверки результатов.

Проблема в том, что эти тесты мало что покрывают. Они проверяют, что бизнес-объект правильно работает, если его правильно вызвать, но они нисколько не гарантируют, что он будет правильно вызван.

F#
Поэтому писать Unit и интеграционные тесты как правило проще.

Чем что? Скажу так: это утверждение представляется мне очень сомнительным. Было бы интересно, если бы Вы привели пример стиля примера с лампочкой - задача, её реализация, тесты к ней, которые "писать проще". В общем, вменяемый по размерам пример, на котором можно было бы сравнить. Можно и на примере лампочки, если считаете его достаточно удобным для демонстрации преимуществ подхода.

F#
Программная модель UI обычно перегружена несущественными для теста подробностями и пользоваться ей напрямую сложнее и усилий требуется больше.

В этой фразе моё изумление вызывает сразу всё. Что такое программная модель UI, какими подробностями она перегружена, зачем ей пользоваться и почему это требует больше усилий.

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

F#
В первую очередь я бы хотел, чтобы "код, который рушит" встретился с "тестом, который он обрушит" прежде, чем с пользователем. У юнит-тестов с этим большие проблемы. Когда эта задача решена - можно говорить о желаемой скорости обратной связи.

Я думаю, то тут вопрос в соотношении вероятностей - все не протестируешь.

Именно так, в соотношении. У интерфейсного теста широчайшее возможное покрытие. Если сесть и тщательно записать всё, что он ненароком проверяет - выходят десятки, а то и сотни юнит-тестов и того, что описать юнит-тестами практически невозможно.

Опять же пример из практики: из-за ошибки при установке размера часть формы оказалась недоступна (форма оказалась меньше, чем содержимое этой формы). В результате пользователь просто не мог ввести некоторые поля. Интерфейсный тест тут же встал на уши. Вот скажите - каким "юнит-интеграционным-временным-хранилищем" Вы бы такое отловили? Причём - ключевой момент - не думая об этом заранее, не пытаясь написать теста специально на проверку такой дикой ситуации?

Интерфейсный тест максимально близко воспроизводит действия пользователя и потому натыкается на те проблемы, на которые наткнётся реальный пользователь. В отличие от него, любые тесты, о которых говорите Вы, тестируют не реальное приложение, а модель, и заведомо не могут отловить проблемы, связанные с несоответствием модели реальности. Скажем, тупо: программист написал Application.MainForm.setVisible(false). Всё, приложение полностью неработоспособно. Но ни один Ваш тест этого не обнаружит.

F#
Если тесты гоняются раз в несколько дней, то есть вероятность, что после последнего прогона закоммитили что-то ломающее тесты.

Гоняйте чаще, я только за :)

Если тесты мало что покрывают, то есть вероятность, что закоммитили что-то не ломающее тесты, но и не работающее. Но к этому случаю такого же простого рецепта лечения не припишешь. Поэтому я не вижу причины ставить во главу угла критерий третьестепенной важности. В коммите "чего-то, ломающего тесты" нет ничего страшного. Страшно - пропустить ошибку к пользователю.

F#
К тому же end-to-end тесты неточно показывают место, где произошла ошибка и поиск конкретного место может занять время. Проще не коммитить ошибок чем их потом искать.

Демагогия. Поиск ошибок никак не связан с коммитом. Сделал ошибку - придётся искать. А до коммита или после - вопрос технический.

F#
С другой стороны, если сделать UI очень тонким, то вероятность сделать в нем ошибку сильно уменьшается.

UI нужно делать не толстым и не тонким, а соответствующим задаче. Дизайн интерфейса не должен зависеть от того, что разработчик не умеет что-то хорошо тестировать.

F#
Особенно сделать регрессию. Например после связывания кнопки "Назад" с командой "Назад" маловероятно, что ее кто-то поменяет на "Вперед".

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

F#
Возможно вам встречалось больше кода, связаного именно с логикой пользовательского интерфейса, чем мне.

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

F#
Обычно по стектрейсу видно место где последствия ошибки обнаружились. Это может быть далеко от места, где находится ошибочный код.

"Средняя длина пути" определяется тем, какую часть кода покрывает тест.

F#
Зависит. Если есть включает в себя много последовательных шагов, то, очевидно, ошибку найти труднее чем если там 1 шаг с подготовленными данными.

Как говорил один мой друг - "если попробовать доказать очевидный факт, он часто становится вовсе не очевидным, а иногда - вовсе и не фактом". В данном случае прежде всего бросаются в глаза "подготовленные данные" - на привычных мне задачах это уже убивает идею, потому что "подготовка данных для каждого из тестов" по трудоёмкости уже многократно превосходит выигрыш от этого теста за всю историю. Становится дешевле тестировать руками. Во-вторых же, если мы рассмотрим два варианта кода:

public class TestMyObj1 {
  @Test public void total() {
    obj.method1();
    assert("method1", ...);
    obj.method2();
    assert("method2", ...);
    obj.method3();
    assert("method3", ...);
  }
}

public class TestMyObj2 {
  @Test public void method1() {
    obj.method1();
    assert("method1", ...);
  }

  @Test public void method2() {
    obj.method2();
    assert("method2", ...);
  }

  @Test public void method3() {
    obj.method3();
    assert("method3", ...);
  }
}


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

F#
Хороший юнит тест не валится, если ошибка произошла в другом юните.

Верно. Поэтому его полезность редко отличается от нулевой.

F#
А так как их можно запускать очень часто

Я не понимаю, зачем Вы так упорно цепляетесь к частоте. Любые тесты можно запускать так часто, как хочется. Другой вопрос, что частые запуски приложения - один из признаков плохого программиста.

F#
Тут мне видится противоречие - либо мы не исключаем нестабильные тесты и не говорим что 100% гарантии не может дать никто, либо таки мы немного беременны.

Наверное, стоит договориться, о какой сценарии вообще речь и с какой целью мы его анализируем. Я задумался о том, какое же противоречие Вы увидели, и предположил, что Вы восприняли формулировку более категорично, чем я имел в виду. Исключая нестабильные тесты, мы ухудшаем покрытие приложения тестами, соответственно, уменьшаем уверенность в нём, но кардинально ничего не меняется. Если бы у нас было идеальное стопроцентное покрытие - да, это разрушало бы идеал и мы бы становились немного беременными. Но поскольку стопроцентное покрытие - скорее идеал, чем практика, то изменение покрытости с, допустим, 98% на 96%... не является зачатием, имхо :)

F#
И еще надо запускать все тесты перед каждым изменением - иначе в промежутке междц запуском мы тоже не можем быть уверены.

Я ничуть не против дополнительной уверенности но не понимаю религиозного к ней стремления. Наверное, я поражу Вас, но в принципе я не считаю ужасным коммитить неработающий и даже не компилирующийся код. Я вижу расклад таким: допустим, я делаю некоторую задачу, которую делать неделю. Я ухожу вечером домой и перед этим я хочу закоммитить свои изменения. Почему? Да хотя бы потому, что мой винт может грохнуться и я потеряю неделю работы. Другой вопрос, что эти мои изменения не должны попадать ни к кому, кроме меня, пока я их не выпущу. Но это уже вопрос к технологии процесса разработки и сборки.

Надеюсь, я пояснил, почему Ваше внимание к коммиту представляется мне удивительным.

F#
В-общем, вашу точку я понимаю, но сам склоняюсь, скорее к тестовой пирамиде - немного End-to-end тестов с основными сценариями, некоторое количество integration и много детальных unit - как описано у Фаулера и Шора.

Cкажу так. Мне было бы интересно попробовать действительно сравнить подходы на каком-нибудь примере вменяемой трудоёмкости. Но не приходит в голову подходящего как по размеру, так и по сложности.
27 авг 15, 14:11    [18076589]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
softwarer
Честно говоря, я не представляю себе настолько ужасного фреймворка, чтобы юнит-тесты хоть как-то конкурировали по "дёшево и удобно".


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

Я видел как из-за ошибки очистки базы данных при прогоне ~1000 тестов, тест номер 200 начинал падать из за ошибки в тесте номер 122 и это было очень трудно выяснить и даже воспроизвести и т.д.

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


При рефакторингах рефакторятся так же и тесты - да. Вопрос насколько чаще переделывается UI и бизнеслогика, это раз. Во-вторых, насколько грамотно сфоромулированы сами тесты, это два и поддержка инструментов, это три. Например, в приведенном селениум-тесте я вижу, что связывание с формой осуществляется по строчкам - насколько формально контроллируется соответстие описания формы и теста? Есть статическая проверка этого соответствия? При переименовании контрола в IDE переименуется ли описание в тесте?

Если приложение из одной формы, над которым работает один человек этим все можно принебречь, как и быстродействием.

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


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

(Пожимая плечами) Вы бьётесь за экономию электричества?


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

Это знание не несёт практической ценности. Когда клиент приходит и говорит "Ваша программа, вашу мать, не работает", слова "ну контроллер-то точно работает" как-то не утешают.


Всегда будет какая-то разница между окружением клиента и вашим и всегда будет какая-то степень неуверенности. Если у вас UI тесты стабильны и требуют мало обслуживания, то хорошо. Можно оставить их, можно пойти дальше по концепции тестовой пирамиды (например, в приведенном примере оставить один UI тест, который будет проверять, что контроллер правильно присоединили к форме, а всякие вырианты оставить на UT)


F#
Во-вторых, есть масса идиотских ошибок/описок которые он будет вылавливать и так.

Например?


Ну всякие мелочи типа неинициализированных переменных в конкретных ветках и прочее.

F#
Можно также сделать тест на viewmodel и focused integration tests на view.

Можно всё. Но прикиньте трудоёмкость и сравните уверенность после. Честно говоря, я почти уверен, что если напишете пример - мы посмотрим в портянку и я назову парочку случаев, которые мой сценарий покрывает, а она - нет.


Давайте я в последующих сообщениях разовью ваш пример.

F#
Как только мы начнем переиспользовать преобразование строки в дату, эти отдельные тесты начнут окупаться.

Какие "эти"?

Если Вы напишете преобразование строки в дату и протестируете его, это не даст Вам вообще ничего, потому что в интерфейсных библиотеках им обычно занимается визуальный компонент (предположительно, написанный не вами). Более того, довольно часто в ходе разработки и сопровождения визуальная библиотека обновляется, расширяется или даже заменяется. Поэтому расклад очень прост: если в проекте продуманная архитектура и строгая дисциплина - такие вещи достаточно протестировать "визуально через компонент" в одном месте. Если дисциплины недостаточно - любое применение компонента, не закрытое проверками, потенциально дыряво.


Если не мы пишем это, можно написать тесты, проверяющие наши предположения относительно компонентов это раз. Можно оставить ограниченное количество UI тестов именно на визуальную составляющую. В любом случае, подумать над вариантами преобразования строки в дату проще отдельно, чем вместе с какими-то бизнес сценариями.


"Пристегнув временное хранилище" - это куча трудоёмкости, а проблему оно всё равно не отловит - потому что временное хранилище работает "как его написали Вы", а не "как работает используемый в приложении компонент".


Эта разница вполне может быть несущественной в контексте функционального тестирования. (Скажем в конкретных тестах может быть не важно fault tolerance и изоляция транзакций и in memory база данных вполне себе покажет достаточную точность тестирования при большем быстродействии).

Вопрос в том, что этот тест через интерфейс проблему отловит всегда - как только она появится, например, после смены версии библиотеки компонент. "Временное хранилище" эту проблему не отловит вообще никогда, просто потому, что в нём нельзя закодировать "работай как вот такой компонент".


Можно написать сфокусированные интеграционные тесты, при некотором количестве повторного использования они будут окупаться. Еще раз, я не против UI тестов - я просто считаю допустимым отказаться от них в случае, если по какой-то причине они дороги и нестабильны. Также не по-моему не стоит отказываться от UT

Проблема в том, что эти тесты мало что покрывают. Они проверяют, что бизнес-объект правильно работает, если его правильно вызвать, но они нисколько не гарантируют, что он будет правильно вызван.


Правильность вызова проверяется либо вручную, либо отдельным интеграционным тестом.

Можно и на примере лампочки, если считаете его достаточно удобным для демонстрации преимуществ подхода.


Ок, в последующих сообщениях.

Что такое программная модель UI,


Приведенный вами тест оперирует не с тем, что видит пользователь (картинка на экране, мышка, клавиатура ) а обращается к копмонентам по внутренним именам - эту совокупность, я называю "программная модель UI"

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

"Ввёл одну дату - ввёл вторую дату - зажглась лампочка" - это то, как мыслит пользователь, это то, как мыслит тестировщик, это то, как мыслит руководитель проекта, и даже разработчик начинает именно с этой мысли.


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

Опять же пример из практики: из-за ошибки при установке размера часть формы оказалась недоступна (форма оказалась меньше, чем содержимое этой формы). В результате пользователь просто не мог ввести некоторые поля. Интерфейсный тест тут же встал на уши. Вот скажите - каким "юнит-интеграционным-временным-хранилищем" Вы бы такое отловили? Причём - ключевой момент - не думая об этом заранее, не пытаясь написать теста специально на проверку такой дикой ситуации?


Очевидно, ошибка в UI не может быть найдена без задействования UI. Ее может найти только Eend2End или интеграционный тест (например, не обязательно использовать полный backend для проверки этого).

Интерфейсный тест максимально близко воспроизводит действия пользователя и потому натыкается на те проблемы, на которые наткнётся реальный пользователь.


С этим я согласен.

Гоняйте чаще, я только за :)


Я использовал вашу оценку продолжительности прогона тестов :)

Если тесты мало что покрывают, то есть вероятность, что закоммитили что-то не ломающее тесты, но и не работающее. Но к этому случаю такого же простого рецепта лечения не припишешь. Поэтому я не вижу причины ставить во главу угла критерий третьестепенной важности. В коммите "чего-то, ломающего тесты" нет ничего страшного. Страшно - пропустить ошибку к пользователю.


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



Демагогия. Поиск ошибок никак не связан с коммитом.


Проще искать иголку не стогу сена а в той щепотке, которая добавлена недавно
- во-первых, потому, что она меньше
- во-вторых, потому, что она сделана недавно и тобой (помните, это вечное "попробуй понять этот код через год")

UI нужно делать не толстым и не тонким, а соответствующим задаче. Дизайн интерфейса не должен зависеть от того, что разработчик не умеет что-то хорошо тестировать.


Я имею ввиду чисто программный дизайн - тонкий слой, относящийся именно к View.

"Средняя длина пути" определяется тем, какую часть кода покрывает тест.


Я тоже про это. У UT такая длина минимальна и связана с логической труктурой приложения.

потому что "подготовка данных для каждого из тестов" по трудоёмкости уже многократно превосходит выигрыш от этого теста за всю историю. Становится дешевле тестировать руками. Во-вторых же, если мы рассмотрим два варианта кода:


Аргументация здесь http://xunitpatterns.com/Principles of Test Automation.html#Verify One Condition per Test

Надеюсь продолжить с примером.
1 сен 15, 13:40    [18095060]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
F
Надеюсь продолжить с примером.


Начну потихонечку.

Понятно, что этот тест написан чтобы продемонстрировать технологию, а не логическое оформление тестов.

По тесту должны быть понятны требования. Так как по этому тесту требования не понятны, я их придумаю.

Мы видим, что здесь лампочка зажигается, когда "дата с" > "дата по". Давайте пусть лампочка горит когда интервал дат неправильный.

Для начала перепишем тест чтобы это требования было очевидно. Еще мне привычнее C#

[TestClass]
public class DateIntervalInputFormTest : AbstractWebTest {
  [TestMethod]
  public void correctnessIndicatorShouldBeVisibleOnlyIfIntervalIsIncorrect() {
    const string correctDateFrom =  "01.01.2000";
    const string correctDateTo = "01.01.2001";
    Selenium.inputString("date-from", correctDateFrom);
    Selenium.inputString("date-to", correctDateTo);
    
    Assert.IsTrue("Лампочка не должна гореть, если интервал корректный", !Selenium.get("bulb").isVisible());
    
    const string dateGreaterThenDateTo = "01.01.2002";
    Selenium.inputString("date-from", dateGreaterThanDateTo);
    Assert.IsTrue("Лампочка должна гореть, когда дата c > дата по", Selenium.get("bulb").isVisible());
  }
}


Итого: требования сталии более понятны из теста.

Продолжение следует...
8 сен 15, 15:48    [18123780]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
Давайте теперь рассмотрим требования. Я бы их составил в таком виде:

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

Если посмотреть структуру требований, то обычно отделяют проблему от решения.

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

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

Итого, проанализировав требования и применив к ним объектную декомпозицию (а так же уточнив все интуитивно понятия типа "интервала дат") получаем:

Есть ИнтервалДат состоящий из ДатыС и ДатыПо. У него есть булевское свойтство ЯвляетсяВалидным, которое должно быть Истиным тогда и только тогда, когда ДатаС <= ДатаПо

Нужна ФормаВводаИнтервалаДат на которой:
1. Есть два элемента управления для ввода дат
2. Лампочка, индикатор алидности

Которые должны отображать соответствующие свойства ИнтервалаДат.

Соответственно тесты:

[EndToEnd] ФормаВводаИнтервалов:
- индикаторВалидностиДолженБытьВключенЕслиИнтервалВалиден
- индикаторВалидностиДолженБытьВыключенЕслиИнтервалНевалиден

[UnitTest] ИнтервалДат:
- интервалДолженБытьВалиденЕслиДатаСНеБольшеДатыПо
- интервалДолженБытьНевалиденЕслиДатаСБольшеДатыПо

При таком наборе тестов есть некоторая избыточность, обычно, она окупается при несколько более усложненных требованиях. Например, если мы добавим новые условия невалидности для интервала (например даты интервала должны принадлежать одному году) мы дорабатываем только UnitTest на интервалы дат, но само по себе отображение остается тем же.

С UT нам легче работать:
- Он работает через программный интерфейс, поэтому:
- нам не надо связываться с элементами управления через и строковые идентификаторы
- нас поддерживает intellisence и компилятор
- нас поддерживают всяческие инструменты для рефакторинга

- Он быстрее

- Модуль можно использовать в других контекстах (как только мы создадим вебсервис, для ввода интервалов, нам не надо будет дублировать тесты - главное создать по одному примеру валидного и невалидного интервала)

- Юнит-тесты так же проверяют, что существует по крайней мере второй (тестовый) контекст использования модуля и помогают нам разделять нашу программу не независимые кусочки. Т.е. некоторой степени способствует пониманию программы по принципу "разделяй и властвуй"

Дальше будет процесс...
15 сен 15, 12:40    [18150727]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Иммануил Кант
Member [заблокирован]

Откуда:
Сообщений: 3490
egorych
YesSql
Сдесь не сказано когда. Это например может случиться при нажатии на клавишу "исполнить" - сработает бизнес логика и вернет в Гуй ошибку. по которой он (Гуй) может раскрасить поля или просто скажет боксом - Это уже информирование.
почему то вы считаете, что "информирование" - это какой то отдельный зверь. Информирование - это неотъемлемая часть бизнес-процесса, без которой этот бизнес-процесс не имеет смысла. И как оно может быть не бизнес-логикой, скажите мне пожалуйста?
Конкретная реализация мессаджбокса, грида или другого какого чёрта-в-ступе-для-вывода-сообщений-пользователю, конечно, к бизнес-логике отношения не имеют, а вот его реакция на определённое событие - является.

И вот что я не понимаю возвращаясь, всё же, к заявленной теме - как тут применить TDD, когда программируешь такие кейсы. А ведь именно здесь они и нужны больше всего.


1. даешь тестовый вход, заведомо содержащий данные, на которые должна быть предсказуемая реакция
2. проверяшь, была ли реакция
11 мар 16, 19:41    [18921504]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
Иммануил Кант
Member [заблокирован]

Откуда:
Сообщений: 3490
ViPRos
если на граничных точках теория дает сбой, то фигня это а не теория, так как граничные точки самые важные


обычно на них и концентрируется тестирование.
11 мар 16, 19:45    [18921516]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ioc_ioc
Member [заблокирован]

Откуда:
Сообщений: 44
А как гуру делают тест с обращением к БД. Я сейчас, для себя, принял такое решение:
- такой тест на мок БД (например, когда для одного контекста используется SQL SERVER, или Sql Lite) не сильно интересен
- на БД, с которой работает приложение, для теста, просто не регистрировать АОП [Transaction] для методов, которые пишут в БД. нет коммита - нет косяка
5 авг 16, 19:49    [19507621]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ioc_ioc
Member [заблокирован]

Откуда:
Сообщений: 44
ioc_ioc
нет косяка


то есть состояние БД не испортил. профит
5 авг 16, 19:51    [19507628]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
scf
Member

Откуда:
Сообщений: 1482
ioc_ioc,

https://github.com/yandex-qatools
https://flywaydb.org/

И, разумеется, роллбэк после каждого теста.
5 авг 16, 20:13    [19507687]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
ioc_ioc
Member [заблокирован]

Откуда:
Сообщений: 44
scf
ioc_ioc,

https://github.com/yandex-qatools
https://flywaydb.org/

И, разумеется, роллбэк после каждого теста.


что-то я от Ваших ссылок ничего не понял. это вообще на что ссылки?
5 авг 16, 20:44    [19507789]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
mini.weblab
Member

Откуда:
Сообщений: 687
кстати, тдд можно попробовать на практике, участвуя в онлайн турнирах по программированию
=)
8 янв 17, 15:59    [20082055]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
mayton
Member

Откуда: loopback
Сообщений: 42897
Насколько я понимаю в турнирах дают ограниченное время на решение задачи.

И как это согласуется с ТДД?
8 янв 17, 16:19    [20082102]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 59366
Блог
mayton
Насколько я понимаю в турнирах дают ограниченное время на решение задачи.

И как это согласуется с ТДД?

1. Насколько я понимаю, Вы демонстрируете любимое заблуждение "практиков от сохи", которые говорят, что "теория - оно конечно правильно, но нам нужно быстро и чтоб работало". Ибо не понимают, что теория - это как раз "чтоб работало и сколь возможно быстро", а их практика - это "долго и чтоб работало очень плохо".

2. Замечательно согласуется.

3. Я крайне сомневаюсь в том, что на турнирах можно показать сколько-нибудь приличный результат без ТДД. Просто потому, что во-первых, любое решение проверяется именно подготовленным организаторами набором тестов, а во-вторых, организаторы тщательно стараются как раз найти "завихрастые" случаи, на которых программы, написанные "по наитию" будут отваливаться.
8 янв 17, 16:23    [20082122]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
mini.weblab
Member

Откуда:
Сообщений: 687
по сути мне нечего добавить к тому, что сказал softwarer
я имела в виду именно пункт 3, когда говорила о возможности попробовать тдд на практике.

хотела бы так же заметить, что вы mayton - разработчик-эгоцентрист, и это мешает вам увидеть картину в целом
=)
8 янв 17, 19:17    [20082619]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
mayton
Member

Откуда: loopback
Сообщений: 42897
Ого. Центрист...
8 янв 17, 21:55    [20083027]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
F#
Guest
mayton
Насколько я понимаю в турнирах дают ограниченное время на решение задачи.

И как это согласуется с ТДД?


Я в турнирах не участвовал, но возможность побыстренькому проверить кусочек кода - весьма удобен в codingame, например - фактически записаный REPL.

А потом становится проще сначала добавлять тест, а потом писать реализацию.
20 янв 17, 18:40    [20128715]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
test_task
Member

Откуда:
Сообщений: 51
а как приватными методами? как их тестировать? их кто-то тестирует?
24 авг 17, 18:25    [20747742]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
scf
Member

Откуда:
Сообщений: 1482
test_task,

конечно тестируют, или на groovy, или меня visibility на default
24 авг 17, 22:01    [20748022]     Ответить | Цитировать Сообщить модератору
 Re: Про TDD  [new]
WebSharper
Member

Откуда:
Сообщений: 487
test_task
а как приватными методами? как их тестировать? их кто-то тестирует?


Приватные методы нужны для того, чтобы реализовать публичные требования.

Если хочется тестировать приватные методы, надо подумать:
- Для выполнения каких требований они нужны и протестировать их
- Не стоит ли вынести функциональность в отдельный класс и протестировать ее отдельно
25 авг 17, 08:52    [20748325]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2 3 4 5 6      [все]
Все форумы / Программирование Ответить