Моё знакомство с "промышленным тестированием" было описано тут - http://18delphi.blogspot.ru/2013/03/blog-post.html
И с тех пор я ничего лучшего не написал.
Но это было далеко не TDD.
И не "тестирование в широком смысле этого слова".
Итак.
Что я хочу сказать о TDD и о "тестировании вообще"?
Я сам долго и нудно "бился головой об стену" пытаясь обеспечить "стабильность разработки".
Нет... Не организации, а "своей собственной".
Чтобы "спать спокойно".
Чтобы не было того, что "что-то вчера поправил, а через три месяца оно вылезло".
Или наоборот - "сегодня поправил одно - завтра вылезло другое, послезавтра поправил другое, а на третий день вылезло первое".
Я много думал и размышлял над "всякими разными возможностями тестирования".
Подход "на коленке" кстати описан тут - http://18delphi.blogspot.ru/2013/11/5.html
Именно "на коленке".
Это было задолго до всяких там DUnit и TDD тем более.
Знаете как я тестировал свой функционал?
У меня была "развесистая" структура директорий - примерно такая - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/DraftsAndScketches/testset/
Там даже на даты интересно посмотреть:
etc.
Десять лет назад.. Примерно... А то и больше...
И были всякие "батники", а также "тулзы" и тулзочки", позволяющие как-то протестировать тот факт, что "ничего не сломалось" при очередной правке исходников.
А ещё были всякие "ToDo-списки" или "записочки приклееннные к монитору".
Ну что поделаешь. Есть люди, которые говорят, что "тестирование нам не нужно, мы и так уверены в своём коде и своей работе". Ну что же. ЕСТЬ!
Я много таких видел и вижу. Но я не из их числа. Ну не повезло мне в жизни. Не обладаю я "аналитическим умом".
Я умею решать задачи в стиле "спринта". Вдох-сделал дело-Выдох.
Ну как-то так - http://18delphi.blogspot.ru/2013/11/5.html?showComment=1384893262611#c9008430456835077997
Да и жизнь диктует "спринт" и XP (http://ru.wikipedia.org/wiki/%D0%AD%D0%BA%D1%81%D1%82%D1%80%D0%B5%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
Хотя - водопад - "самая удобная модель для программиста" - http://18delphi.blogspot.ru/2013/08/blog-post.html
Процитирую - "ТЗ — это большое БЛАГО для программиста. „Водопад“ — возможность творчески работать, не загоняя себя в угол."
ЕЩЁ РАЗ - "ТЗ — это большое БЛАГО для программиста. „Водопад“ — возможность творчески работать, не загоняя себя в угол."
И ЕЩЁ РАЗ - "ТЗ — это большое БЛАГО для программиста. „Водопад“ — возможность творчески работать, не загоняя себя в угол."
Но! Мы живём в "обычном мире". В мире "спринта", XP и Agile.
Что такое XP и Agile на мой взгляд? Скажу - "это там где кончается порядок", там "где нет договорённостей".
Как ТОЛЬКО "заказчик" начинает "уходить от ответа" - начинается XP и Agile - http://18delphi.blogspot.ru/2013/04/blog-post.html
Так "причём тут TDD"?
Ещё раз повторюсь - на TDD и DUnit я смотрел "долго и вдумчиво". (Хотя это совсем не одно и то же).
И скажем такую вещь как "атомарные тесты" (http://18delphi.blogspot.ru/2013/04/blog-post_2326.html) в DUnit - "я пропустил мимо ушей". Хотя потом и написал свои - (http://18delphi.blogspot.ru/2013/07/2_18.html - например AtomicListTest.imp.pas).
Я думал - "ЧТО ЗА ЧУШЬ" - тестировать "тот факт, что элемент добавился в список", да ещё и на правильное место.
Я думал - "да быть того не может, чтобы было иначе".
И я очень хорошо помню ТЕ ощущения. Полного идиотизма.
Но видимо это - "высшая степень дзена", когда начинаешь понимать, что атомарные и примитивные тесты - это ОЧЕНЬ ВАЖНО.
Опять - же - НИКОГО НИКУДА не тяну.
Ещё раз - НИКОГО НИКУДА не тяну.
Просто пытаюсь передать свои ощущения.
Кстати "лирическое отступление" -"Сегодня мне показалось, что я нашёл ошибку в менеджере памяти Delphi XE" (http://18delphi.blogspot.ru/2013/04/delphi-xe.html).
Глядя в ОТЛАДЧИК - я БЫЛ УВЕРЕН, что ошибка у Embarcadero.
Пока я не стал выделять "атомарный тест", чтобы отослать в Embarcadero и "поймать их за хвост". А когда я НАПИСАЛ ТЕСТ и он ПРОШЁЛ и раз, и два, и десять, и тысячу раз - я усомнился - и начал искать "проблемы на своей стороне". И таки - нашёл.
Буду банален - "практика - критерий истины".
И всё же - "ближе к теме".
Что я хочу сказать?
Тут есть одна проблема - с одной стороны - DUnit - я уже писал - первое моё впечатление о нём было - "ну не космос, я тоже так умею". А с другой стороны - TDD.
Откроем википедию и почитаем:
http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5
"
Каждой новой функциональности. Выделено мной.
Ещё раз. Каждой новой функциональности.
Когда читаешь это - мозги начинают разбегаться как тараканы.
Какой функциональности? Что считать функциональностью? Правда каждой новой?
И - ВСЁ - АЛЕС КАПУТ. Идея - ПОХОРОНЕНА заживо её же создателями.
Я сам НЕ РАЗ пытался "подступиться к TDD" и отступал.
Почему?
Скажу то, что я сам думал и слышал от бесчётного числа людей - "как же так - КАЖДУЮ новую функциональность протестировать. А работать когда?"
Резонный вопрос? Не правда ли?
Я сам себе его не ОДНУ ТЫСЯЧУ раз задавал.
Пока не понял одной банальной вещи - "Дорога в тысячу ли начинается с одного шага".
Ещё раз - "Дорога в тысячу ли начинается с одного шага".
НЕТУ "чисто объектных языков" и нету "чисто функциональных языков".
Ну может где-то есть но не в практике применения (http://18delphi.blogspot.ru/2013/11/blog-post_3004.html).
И тому подтверждение вот это - http://18delphi.blogspot.ru/2013/11/blog-post_2.html?showComment=1384183753080#c1086781562262325290
Пока я не написал ПЕРВЫЕ ДВА ТЕСТА.
А дальше жить стало "легче и веселее".
Что такое TDD на мой взгляд? Где тут Driven?
Driven это не в том, чтобы "писать тест под каждую функциональность".
Driven - оно СОВСЕМ в другом.
По-моему ВСЕ программисты вставили перед вопросом - "я это сделал - я как это протестировать".
И только ЛУЧШИЕ говорили - "мой код - безупречен - тестировать нечего".
А "менее лучшие" начинали искать "всякие разные возможности". Типа "а где в настоящей системе это протестировать"? Или "а давайте сделаем тестовое приложение".
А блин? Где? Как и почему?
Куда это тестовое приложение положить? И как оно должно работать? И вообще - "лень делать очередное тестовое приложение".
Ну и всё сводится к тому, что "протыкали пару мест и ладно". Простите, но вот это - http://18delphi.blogspot.ru/2013/05/resolved.html - тому пример.
А "с другой стороны" - TDD - "тестируйте ВСЮ функциональность".
Как из этой "вилки" выбраться?
Я для себя эту проблему решил - "просто". Вот смотрите - если мне надо что-то реализовать, или переделать, то я уточняю ТЗ - насколько это возможно, а дальше начинаю кодировать.
Но как?
Где я проверяю функциональность? В реальной системе? Далеко - не всегда! (Хотя и такое тоже случается). Я "обычно" пишу тест - ИМЕННО на ту функциональность, которую я реализую например при помощи DUnit или совсем "на коленке" - http://18delphi.blogspot.ru/2013/11/5.html.
Хотя эти "коленки" - многого стоят. Поверьте мне.
Вот тут я писал про логирование - http://18delphi.blogspot.ru/2013/11/gui-back-to-basics_22.html (банально) и "о чудо!" при помощи этих логов я нашёл аж две ошибки.
Просто глядя на логи. А не "долго и вдумчиво" курил "отладчик и брейкпоинты".
НЕ СТОИТ пытаться написать "супер-тест", который "всё покажет". Нету такого в природе.
Только цикл - тест - функционал - тест. Или функционал - тест - функционал.
В чём же Driven?
А в ТОМ, что тесты это не просто ИНСТРУМЕНТ для тестирования, и даже скажем так - это СОВСЕМ не инструменты для тестирования.
Это в ПЕРВУЮ очередь инструменты для разработки системы и "исследования её поведения".
ТЕСТЫ - это ОТЛИЧНОЕ поле для отладки. А ЛИШЬ потом - поле для "поверки регресса".
Ну в самом деле - "если тест написан - не выкидывать же его".
По крайней мере - пока он работает.
Ещё раз.
Тесты - ОБЕСПЕЧИВАЮТ в первую очередь - инфраструктуру для отладки. А уж потом - "меряют регресс".
Я наверное так долго - именно эту мысль и пытался донести.
И ещё раз. ТЕСТЫ - инфраструктура для отладки. В ПЕРВУЮ очередь.
А уж потом - "регресс" и всё остальное.
И ещё - я много видел и вижу людей, которые пытаются "создать супер-тест" и в итоге - ничего не делают. А лишь только размышляют в духе - "ах как хорошо бы было бы посторить мост".
Никого никуда не тяну.
"Лучше ОДИН кривой и косой тест, чем тысяча ИДЕАЛЬНЫХ, но ненаписанных".
А "идеологи TDD" - сами себе по-моему карму портят словами "каждая функциональность", "любой метод" и т.д и т.п.
Не надо "тестов ради тестов"...
Написали тест. Он не прошёл - потом подгоняем функциональность...
Ну бред... Затраты времени.. Бред...
Где-то может и не бред, но "где-то"...
"Не сотвори себе кумира". Как-то так.
Не "бейтесь головой об стену". Не пытайтесь "найти серебряную пулю". Напишите ПЕРВЫЙ тест. А потом ВТОРОЙ. А потом и ТРЕТИЙ.
Я УВЕРЕН - вам понравится.
И с тех пор я ничего лучшего не написал.
Но это было далеко не TDD.
И не "тестирование в широком смысле этого слова".
Итак.
Что я хочу сказать о TDD и о "тестировании вообще"?
Я сам долго и нудно "бился головой об стену" пытаясь обеспечить "стабильность разработки".
Нет... Не организации, а "своей собственной".
Чтобы "спать спокойно".
Чтобы не было того, что "что-то вчера поправил, а через три месяца оно вылезло".
Или наоборот - "сегодня поправил одно - завтра вылезло другое, послезавтра поправил другое, а на третий день вылезло первое".
Я много думал и размышлял над "всякими разными возможностями тестирования".
Подход "на коленке" кстати описан тут - http://18delphi.blogspot.ru/2013/11/5.html
Именно "на коленке".
Это было задолго до всяких там DUnit и TDD тем более.
Знаете как я тестировал свой функционал?
У меня была "развесистая" структура директорий - примерно такая - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/DraftsAndScketches/testset/
Там даже на даты интересно посмотреть:
%producer 'ЭВЕРЕСТ (lite) 1.0.0.154' date '06.11.2002' %producer 'ЭВЕРЕСТ 1.0.0.163' date '31.03.2003' %producer 'ЭВЕРЕСТ 1.0.0.714' date '02.11.2004' %producer 'ЭВЕРЕСТ 1.0.0.92' date '28.03.2001' %producer 'ЭВЕРЕСТ (lite) 1.0.0.115' date '15.01.2002' %producer 'ЭВЕРЕСТ 1.0.0.99' date '22.05.2001'
etc.
Десять лет назад.. Примерно... А то и больше...
И были всякие "батники", а также "тулзы" и тулзочки", позволяющие как-то протестировать тот факт, что "ничего не сломалось" при очередной правке исходников.
А ещё были всякие "ToDo-списки" или "записочки приклееннные к монитору".
Ну что поделаешь. Есть люди, которые говорят, что "тестирование нам не нужно, мы и так уверены в своём коде и своей работе". Ну что же. ЕСТЬ!
Я много таких видел и вижу. Но я не из их числа. Ну не повезло мне в жизни. Не обладаю я "аналитическим умом".
Я умею решать задачи в стиле "спринта". Вдох-сделал дело-Выдох.
Ну как-то так - http://18delphi.blogspot.ru/2013/11/5.html?showComment=1384893262611#c9008430456835077997
Да и жизнь диктует "спринт" и XP (http://ru.wikipedia.org/wiki/%D0%AD%D0%BA%D1%81%D1%82%D1%80%D0%B5%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
Хотя - водопад - "самая удобная модель для программиста" - http://18delphi.blogspot.ru/2013/08/blog-post.html
Процитирую - "ТЗ — это большое БЛАГО для программиста. „Водопад“ — возможность творчески работать, не загоняя себя в угол."
ЕЩЁ РАЗ - "ТЗ — это большое БЛАГО для программиста. „Водопад“ — возможность творчески работать, не загоняя себя в угол."
И ЕЩЁ РАЗ - "ТЗ — это большое БЛАГО для программиста. „Водопад“ — возможность творчески работать, не загоняя себя в угол."
Но! Мы живём в "обычном мире". В мире "спринта", XP и Agile.
Что такое XP и Agile на мой взгляд? Скажу - "это там где кончается порядок", там "где нет договорённостей".
Как ТОЛЬКО "заказчик" начинает "уходить от ответа" - начинается XP и Agile - http://18delphi.blogspot.ru/2013/04/blog-post.html
Так "причём тут TDD"?
Ещё раз повторюсь - на TDD и DUnit я смотрел "долго и вдумчиво". (Хотя это совсем не одно и то же).
И скажем такую вещь как "атомарные тесты" (http://18delphi.blogspot.ru/2013/04/blog-post_2326.html) в DUnit - "я пропустил мимо ушей". Хотя потом и написал свои - (http://18delphi.blogspot.ru/2013/07/2_18.html - например AtomicListTest.imp.pas).
Я думал - "ЧТО ЗА ЧУШЬ" - тестировать "тот факт, что элемент добавился в список", да ещё и на правильное место.
Я думал - "да быть того не может, чтобы было иначе".
И я очень хорошо помню ТЕ ощущения. Полного идиотизма.
Но видимо это - "высшая степень дзена", когда начинаешь понимать, что атомарные и примитивные тесты - это ОЧЕНЬ ВАЖНО.
Опять - же - НИКОГО НИКУДА не тяну.
Ещё раз - НИКОГО НИКУДА не тяну.
Просто пытаюсь передать свои ощущения.
Кстати "лирическое отступление" -"Сегодня мне показалось, что я нашёл ошибку в менеджере памяти Delphi XE" (http://18delphi.blogspot.ru/2013/04/delphi-xe.html).
Глядя в ОТЛАДЧИК - я БЫЛ УВЕРЕН, что ошибка у Embarcadero.
Пока я не стал выделять "атомарный тест", чтобы отослать в Embarcadero и "поймать их за хвост". А когда я НАПИСАЛ ТЕСТ и он ПРОШЁЛ и раз, и два, и десять, и тысячу раз - я усомнился - и начал искать "проблемы на своей стороне". И таки - нашёл.
Буду банален - "практика - критерий истины".
И всё же - "ближе к теме".
Что я хочу сказать?
Тут есть одна проблема - с одной стороны - DUnit - я уже писал - первое моё впечатление о нём было - "ну не космос, я тоже так умею". А с другой стороны - TDD.
Откроем википедию и почитаем:
http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_%D1%87%D0%B5%D1%80%D0%B5%D0%B7_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5
"
Добавление теста
При разработке через тестирование, добавление каждой новой функциональности (англ. feature) в программу начинается с написания теста. Неизбежно этот тест не будет проходить, поскольку соответствующий код ещё не написан. (Если же написанный тест прошёл, это означает, что либо предложенная «новая» функциональность уже существует, либо тест имеет недостатки.) Чтобы написать тест, разработчик должен чётко понимать предъявляемые к новой возможности требования. Для этого рассматриваются возможные сценарии использования и пользовательские истории. Новые требования могут также повлечь изменение существующих тестов. Это отличает разработку через тестирование от техник, когда тесты пишутся после того, как код уже написан: она заставляет разработчика сфокусироваться на требованиях до написания кода — тонкое, но важное отличие."
Ещё раз. Каждой новой функциональности.
Когда читаешь это - мозги начинают разбегаться как тараканы.
Какой функциональности? Что считать функциональностью? Правда каждой новой?
И - ВСЁ - АЛЕС КАПУТ. Идея - ПОХОРОНЕНА заживо её же создателями.
Я сам НЕ РАЗ пытался "подступиться к TDD" и отступал.
Почему?
Скажу то, что я сам думал и слышал от бесчётного числа людей - "как же так - КАЖДУЮ новую функциональность протестировать. А работать когда?"
Резонный вопрос? Не правда ли?
Я сам себе его не ОДНУ ТЫСЯЧУ раз задавал.
Пока не понял одной банальной вещи - "Дорога в тысячу ли начинается с одного шага".
Ещё раз - "Дорога в тысячу ли начинается с одного шага".
НЕТУ "чисто объектных языков" и нету "чисто функциональных языков".
Ну может где-то есть но не в практике применения (http://18delphi.blogspot.ru/2013/11/blog-post_3004.html).
И тому подтверждение вот это - http://18delphi.blogspot.ru/2013/11/blog-post_2.html?showComment=1384183753080#c1086781562262325290
Пока я не написал ПЕРВЫЕ ДВА ТЕСТА.
А дальше жить стало "легче и веселее".
Что такое TDD на мой взгляд? Где тут Driven?
Driven это не в том, чтобы "писать тест под каждую функциональность".
Driven - оно СОВСЕМ в другом.
По-моему ВСЕ программисты вставили перед вопросом - "я это сделал - я как это протестировать".
И только ЛУЧШИЕ говорили - "мой код - безупречен - тестировать нечего".
А "менее лучшие" начинали искать "всякие разные возможности". Типа "а где в настоящей системе это протестировать"? Или "а давайте сделаем тестовое приложение".
А блин? Где? Как и почему?
Куда это тестовое приложение положить? И как оно должно работать? И вообще - "лень делать очередное тестовое приложение".
Ну и всё сводится к тому, что "протыкали пару мест и ладно". Простите, но вот это - http://18delphi.blogspot.ru/2013/05/resolved.html - тому пример.
А "с другой стороны" - TDD - "тестируйте ВСЮ функциональность".
Как из этой "вилки" выбраться?
Я для себя эту проблему решил - "просто". Вот смотрите - если мне надо что-то реализовать, или переделать, то я уточняю ТЗ - насколько это возможно, а дальше начинаю кодировать.
Но как?
Где я проверяю функциональность? В реальной системе? Далеко - не всегда! (Хотя и такое тоже случается). Я "обычно" пишу тест - ИМЕННО на ту функциональность, которую я реализую например при помощи DUnit или совсем "на коленке" - http://18delphi.blogspot.ru/2013/11/5.html.
Хотя эти "коленки" - многого стоят. Поверьте мне.
Вот тут я писал про логирование - http://18delphi.blogspot.ru/2013/11/gui-back-to-basics_22.html (банально) и "о чудо!" при помощи этих логов я нашёл аж две ошибки.
Просто глядя на логи. А не "долго и вдумчиво" курил "отладчик и брейкпоинты".
НЕ СТОИТ пытаться написать "супер-тест", который "всё покажет". Нету такого в природе.
Только цикл - тест - функционал - тест. Или функционал - тест - функционал.
В чём же Driven?
А в ТОМ, что тесты это не просто ИНСТРУМЕНТ для тестирования, и даже скажем так - это СОВСЕМ не инструменты для тестирования.
Это в ПЕРВУЮ очередь инструменты для разработки системы и "исследования её поведения".
ТЕСТЫ - это ОТЛИЧНОЕ поле для отладки. А ЛИШЬ потом - поле для "поверки регресса".
Ну в самом деле - "если тест написан - не выкидывать же его".
По крайней мере - пока он работает.
Ещё раз.
Тесты - ОБЕСПЕЧИВАЮТ в первую очередь - инфраструктуру для отладки. А уж потом - "меряют регресс".
Я наверное так долго - именно эту мысль и пытался донести.
И ещё раз. ТЕСТЫ - инфраструктура для отладки. В ПЕРВУЮ очередь.
А уж потом - "регресс" и всё остальное.
И ещё - я много видел и вижу людей, которые пытаются "создать супер-тест" и в итоге - ничего не делают. А лишь только размышляют в духе - "ах как хорошо бы было бы посторить мост".
Никого никуда не тяну.
"Лучше ОДИН кривой и косой тест, чем тысяча ИДЕАЛЬНЫХ, но ненаписанных".
А "идеологи TDD" - сами себе по-моему карму портят словами "каждая функциональность", "любой метод" и т.д и т.п.
Не надо "тестов ради тестов"...
Написали тест. Он не прошёл - потом подгоняем функциональность...
Ну бред... Затраты времени.. Бред...
Где-то может и не бред, но "где-то"...
"Не сотвори себе кумира". Как-то так.
Не "бейтесь головой об стену". Не пытайтесь "найти серебряную пулю". Напишите ПЕРВЫЙ тест. А потом ВТОРОЙ. А потом и ТРЕТИЙ.
Я УВЕРЕН - вам понравится.
Комментариев нет:
Отправить комментарий