Pull to refresh

Comments 114

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

Каждый сам решает сколько усилий потратить на свою идею.
Какое отношение имеет код? Код никто не видит. Нужен результат. Выпускайте версию за версиями. Правьте баги. На рефакторинг будет время когда будет хотя бы работающий продукт
Проект внешне может выглядеть одинаково, но что у него под капотом может и напугать временами.
Но не так влияет на успех стартапа. Если это глупо, но работает — значит это не глупо.
Успех стартапа нужно закрепить, а закрепляется он развитием продукта, его усовершенствованием. И тут на первый план выходит код и архитектура.
Код и архитектура может выглядеть как угодно, сталкивался много раз. И на успех это не влияло
UFO just landed and posted this here
Далеко ходить не нужно. Можно смотреть не на стартапы а на open source проекты на гитхабе.
Каждый день вижу проекты из 200 коммитов и пары тысяч строчке. Их можно написать за пару недель. Я не смотрю код, просто смотрю issues. Волосы дыбом встают от того как вообще разработчик такое наприсал, и допустил такие баги. Не подумав о edge cases, не продумав вообще как оно будет работать, не написав тесты, даже, видимо, ни разу не запустив этот свой код. Откуда такие баги ??
Потом это всё превращается в проект с сотнями ошибок которые даже никто уже не читает.

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

Популярность на каком-то этапе это ещё не есть успех. Успех приходит потом, о чём и говорится в статье.
Абсолютно согласен.
Сам знаю кучу дырявых проектов с костылями, но они зарабатывают так, что позавидует любой красиво и качественно сделанный проект.
Из опыта: есть дырявый проект с костылями, который делался без тестов практик а лишь бы побыстрее. Занял нишу, нашел хороших инвесторов, куча пользователей, сириус бизнес. Только…

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

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

Снежный ком говнокода уже давно неподконтролен. Внутренняя сложность ПО уже давно перешла все рамки любого мозга. А без тестов никто не решается это рефакторить.

Движения наверху. Никто не может Это сдвинуть хоть куда-то. Никто не может это исправить. (Уже никто и не берётся). Тех кто начинал уже давно поменяли инвесторы на более опытных. Но всё равно инвесторы недовольны.

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

Конечно, кто-то может назвать это успехом… но Боб прав. Если вам важна скорость выхода на рынок, то надо обрезать функционал первой версии до минимума, но никогда, никогда, никогда не трогайте практики!
я не против хорошего кода, сам сталкивался с очень плохой архитектурой и не понятными подходами. переписывал. переписывал несколько месяцев пока предыдущая версия работала, одновременно внося «костыли» в предыдущую.
А без тестов никто не решается это рефакторить.

Что мешает сначала написать тест для куска кода, а потом провести его рефакторинг?
Код не изолированный, не приспособлен для тестов, в частности захардкоженные зависимости, которые ни замокать, ни застабить, по крайней мере малой кровью. Получается замкнутый круг — чтобы нормально покрыть тестами нужно отрефакторить, а чтобы нормально отрефакторить нужно покрыть тестами. Это не говоря о таких «мелочах» как код, который вообще непонятно что делает.
Угу. Хорошая книжка. Можно сказать настольная моя. Но особенно радует, что многие приемы в ней описанные сейчас IDE реализуют автоматически, что позволяет разрывать круг сравнительно малыми усилиями без тестов. Пару кликов и выделена функция или метод с большой вероятностью безопасности этого выделения (в IDE тоже могут быть баги, но как-то маловерроятнее по-моему чем ручками выделяя ошибиться, особнно в динамических слабыотипизированных языках, где пропуск или опечатка в переменной даже нотайса может не выдать)
Не знаю как там думает БОБ. Но, если что-то пошло расти, то наверняка будет вторая версия, которая ессно будет написано по всем методикам.

Я к тому, что иногда сам не знаешь, что писать во время развития. А покрывать тестами нету времени. Если пошло, то надо просто в какой-то момент нанять команду и переписать и дальше поддерживать эту культуру.
Погоня за кратковременным почти всегда приводит к полной жопе. Да-да-да, вторую версию мы выпустим по всем правилам. А если после первой версии пришёл успех, то почти всегда случается так, что, мол, блин, надо срочно клепать вторую. И ни о каких переписях речь не встаёт. Говнокод размножается лавинообразно. И четвёртую версию выпустить будет уже не суждено никогда.
Клепать вторую не проблема. Проблема в том, что менеджеры заставляют её клепать на основе первой.
Уважаемые минусующие ботаны всезнайки и великие программисты или просто тем кому не повезло и нарвался на говнокод в своей жизни (я искренне соболезную без приколов, я сам был в такой ситуации), я наверное не так хорошо расписал мысль. Вот её смысл в развернутом виде.

Когда структура БД уже укрепилась и явно намек на рост (например 200% в месяц). Ничего не стоит нанять к одному разработчику первопроходцу целый отдел.

На начальный этап — БД оставляем ту же.

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

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

Самое главное такая схема не нарушает принцип, кто первый встал — того и тапки.

Я к тому, что пока те кто пишут тесты дотащатся до первой версии, путем постоянного мегарефакторинга без костылей, ты уже займешь 70% рынка. На второй фазе переписывания ты уже будешь иметь возможности все переписать с командой раз в 5 превышающий текущую когда конкуренты будут до сих пор находиться в в фазе написание первого прототипа с командой первой очереди.
Когда выходит первая версия, и появляются первые пользователи, как думаете, первая прибыль сможет перекрыть первый поток фичреквестов и багрепортов, чтобы ещё остались деньги на команду «второй очереди»? А если учесть, что к моменту первого релиза все первопроходцы выжаты до суха, так как вложились на 100% в расчёте на будущий рай?

Нет. Тогда откуда деньги на команду «второй очереди»?
Обычно считают, что TDD замедляет те, кто делает это неэффективно:
— пишет юнит тесты на тривиальные функции
— перегибает: например, тест, который проверяет, что функция A вызывает функции B, C, D, а C вызывает E, когда особой необходимости именно в такой реализации и разбивки на функции нет.
— не пытается сделать тест инвариантым к изменениям
— сначала пишет код (конечно же тестирует вручную), а потом вспоминает про тест.

А не видят, где TDD больше всего экономит те, кто никогда не разрабатывал с autotest :) TDD больше всего экономит не там, в будущем, а прямо сейчас, во время программирования, когда не надо после каждого сейва нажимать Alt-tab и вручную тестировать изменения, а достаточно скосить глаза на соседнее окно, где только что пробежали новые тесты.
>>пишет юнит тесты на тривиальные функции

Сходу определить, тривиальна ли функция(для кого тривиальна, кстати?) и не стала ли они нетривиальной после твоих правок/дополнений — весьма нетривиальная задача. ))
Тоже к пункту с тривиальными функциями отношусь скептически. Если функция тривиальная, то и тест для нее тривиальный и много времени его разработка не займет, достаточно одного тривиального, для нормальных условий.

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

Представьте, вы написали сайт, которым начали пользоваться люди. Они начали давать фидбек, а вы начали его учитывать. В какойто момент вам стало ясно, что этот прототип, созданный изначально вообще как proof of concept, так далеко не уйдет. Вам нужно переписывать код заново. А как это выглядит для менеджмента? У вас есть удачно стартанувший проект, набирающий обороты, инвесторы уже начинают требовать какие-то фичи в какие-то сроки, и тут разработчики говорят, что им нужен месяц (например), чтобы переписать движок заново и восстановить (!) функционал к текущему виду, чтобы какие-то фичи продолжать добавлять (несмотря на то, что они их добавляли вот уже сколько времени без проблем). Какая к чертям вторая версия??? пиши-код.рф!
Бывает обиднее: если будете делать правильно и потратите много денег/времени — взлетит. А если только попробуете — одни расходы.
Сомневаюсь что можно определить за пару месяцев взлетит ли стартап. И за пол года не определить. Часто и за год. Да еще и критерий взлета у каждого будет разный. И динамика разная. И окружающая обстановка разная. Да все разное. А за год можно такого в коде наколбасить что и сам не разберешь.
Никто не знает, взлетит проект или нет, надо просто безупречно делать свою работу.
Через 5 лет программист, который всегда делал код правильно, будет делать его идеально за пару месяцев, и иметь высокую ценность в лице любого работодателя.

Привычка правильного кода — это долгосрочные инвестиции.

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

В целом, выглядит как дяденька пиарит TDD как всегда единственный правильный (ничего не имею против самого подхода и всеми руками за) подход. Чтобы его же книжки покупали, а на семинары ходили :)
Дядя действительно очень крут. Но я согласен насчёт пиара. Действительно, нужно включать свою голову и смотреть на свою ситуацию, а не слепо следовать всему, что скажет Дядя Боб или Рой Ошероув. Абсолютных истин в программировании катастрофически мало (если они вообще есть в программировании).
Ну вот насчёт TDD лично мне кажется, что многие «включившие голову», TDD даже не пробовали на «одноразовых» проектах больших чем сотня строк.
Я включаю голову и использую TDD в крупных проектах. А насчёт многих не знаю)
Здесь есть вот какая штука. Какие основные выгоды дает TDD? Хороший дизайн кода, документация и, самое важное на мой взгляд, регрессию, возможность рефакторить код или исправлять ошибки и сразу видеть результат.
Так вот на маленьких проектах, где весь проект «умещается» в голове, вы понимаете, где могут аукнуться изменения, их легко и быстро протестировать пусть даже руками. И писать новый маленький код можно сразу хорошо. Достаточно хорошо. И TDD тут действительно может быть ни к чему.
А вот когда проект уже «не помещается» в голове, когда уже не удержать в голове всех связей, когда уже может быть не так просто сделать хороший дизайн, тогда вот эта ценность TDD и проявляется в полной мере.
Не переоценивайте себя… Что вы будете делать с тестами (которых нет), если проект перестал таки умещаться в вашей голове?
Они начинают писаться. Просто фанатично следовать всему и вся тоже не есть хорошо. И кстати такое же мнение я слышал у Кента Бека (пионера, казалось бы!).
А я бы поспорил. Ошибки бухгалтера вылезают раз в квартал или раз в год. И могу ой как больно бить. Но это ничего, на сути бизнеса (коим является продукт, или сервис) они не сказываются. А вот ошибки программистов тоже вылезают раз в квартал (условно, с релизом). Только есть еще одна штука — код. Который становится хуже и хуже, и в конце концов вы просто утонете в багофиксе. Пользователи начнут уходить, доходы начнут падать. Как ни крути, а продукт, или сервис, это основа вашего бизнеса.
А сравнение в статье вот к чему: чем это программист отличается от других работников, например, бухгалтера, что другие работники работают профессионально и следуют практикам профессии, а программист при этом может делать тяп-ляп? Этим вопросом дядя Боб и задается, и призывает нас всех быть профессионалами.
«Ошибки бухгалтера вылезают раз в квартал или раз в год. И могу ой как больно бить. Но это ничего, на сути бизнеса (коим является продукт, или сервис) они не сказываются. А вот ошибки программистов тоже вылезают раз в квартал (условно, с релизом).»

И во многих стартапах вы бывали? Абсолютно противоречит тому что я видел.

Типичный стартап в рашке — показать инвестору сильную команду и, условно, примечательную идею, получить первый транш (сид не рассматриваем ибо слишком мал), слить все на маркетинг (как раз момент истины, в который всем безразличен код). Если поперло — рефакторить и развивать. Не поперло — закрываем и начинаем новый. Это то что я видел лично, не понимаю причем тут практики. В таких условиях от программистов зависит очень немногое, единственное что от них требуется — не затягивать релиз. Мелкие ошибки, вроде неработающей формы отправки отзыва — вообще ни на что не влияют. Влияет лишь первоначальная идея, позиционирование и маркетинг.

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

Дядя Боб призывает быть «профессионалами» только потому что ему, видимо, это выгодно. Не стоит в этом пытаться рассматривать слова истины. Серебрянных пуль не существует, так ведь?
Полагаю, дядя Боб живёт не за счёт семинаров. На семинарах много не заработаешь. Вообще-то он зарабатывает на жизнь программированием. Так что не надо.
Семинарами можно заработать гораздо больше, чем программированием, если ты такой известный человек как дядя Боб.
Как научить и заставить человека писать тесты, если он не хочет этого делать? Речь не обо мне. Я считаю, что тесты нужны. Пускай хоть и не на 100% покрытие кода(и 100% покрытие всех брачней). Но они нужны. По крайней мере к идеалу стоит стремиться.

Но вот сидят два девелопера — я, сениор, и Вася, тоже сениор.

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

Вот как перетянуть такого человека на темную(а может светлую) сторону силы, если у человека есть уже сложившиеся взгляды на написание софта и он не приемлет чужое мнение на написание софта кроме своего?
>>Вот как перетянуть такого человека на темную
Да впринципе очень просто: дать Уасилыю, небольшой проект, который постепенно усложнять и усложнять, завинчивать все больше архитектуру и «винтики», и когда Уасилый взвоет волком от того что он все время что-то ломает когда добавляет, и вместо того чтобы попить чайку и пойти спать, сидит 2 дня за багами, тогда надо ему подсунуть книгу по TDD/XP и Уасилый будет бесконечно рад :D Кстати сеньонр не знающий TDD/BDD это не сеньор :D
А еще лучше, перед тем как подсунуть книжку, сесть и показать. Взять конкретную ошибку, написать тест, исправить ошибку, прогнать тест. А потом уже подсунуть книжку.
Собственно меня так и научили. Сидел лид и все показывал. Правда книжки я уже сам читал, подсовывать ничего не надо было :).
Когда узнаете рецепт как заставить писать тесты поделитеть пожалуйста. Я себя никак не могу заставить)
Себя легко заставить: для начала каждый раз когда будете искать и исправлять ошибку в уже имеющемся коде, напишите простой unit-test, который её демонстрирует. Самомотивация простая: вам всё равно придётся тестировать (руками или автоматически) и всё равно придётся тестировать ещё раз после того, как исправите (опять же руками или автоматически). А скорее всего, если ошибка сложнее опечатки, придётся тестировать не один раз, а несколько. Таким образом, один раз написать тест скорее всего дешевле, чем из раза в раз тестировать руками.

Так можно научиться писать unit-test'ы и приобрести полезную привичу, а дальше TDD, BDD и прочая…
Повесить хук на прекоммит, чтобы коммит роняющий тесты не проходил :) Писать он их может и не будет, но хоть ваши ломать перестанет.
Но у обоих одинаковые права, он просто отменит двух фазовый былд и будет дальше коммитить, плюя на поломанные тесты.

Лично был в такой лодке, своего Васю реченьками так и не прельстил. Решил кардинально, найдя работу в адекватном коллективе.
мы работали с гитом и все коммиты в главную ветку выполнялись через pull request. Pull request обязан был закрыть кто-то другой, не сам автор кода…
Код без тестов попросту не принимался.
2 диаметрально противоположных мнения по данному вопросу:

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

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

А разве я не об этом написал? Некоторые сразу делают качественно (TDD — это признак качественной работы). Другие же стремятся сделать чем быстрее и дешевле, не взирая на качество.

Кто прав а кто нет — вопрос не однозначный. Строго говоря, не всем людям нужно качество. Кто-то любит дорогую и качественную обувь, которую комфортно носить (за $300-500), а кто-то дороже $20-50 ничего в жизни не обувал. И что лучше: делать качественную обувь или ширпотреб?
Вроде правильно, но TDD всё же замедляет, а значит и удорожает разработку первой версии. Вроде логично выпустить публичный «спагетти» прототип, который будет потом переписан с нуля с использованием лучших практик. Но, зачастую, начинают сыпаться баг-репорты и фичереквесты, которые менеджеры считают более приоритетными, чем переписывание (и даже то, что прототип сделан на другом языке, не на планируемом к релизу их не смущает :( ). Может имеет смысл писать пускай без тестов, но не спагетти, имея в виду последующее покрытие кода тестами в режиме «нужно править баг — пишем тест его ловящий», «нужна новая фича — пишем тест на нее и закрепляем тестами зависящее от нее поведение»? Реалистично или все равно всё выльется в костыли, которые чтобы покрыть тестами нужно переписывать снуля?
TDD тормозит только если ваша кодовая база пару тысяч строк, т.е крайне небольшой проект. Там можно и без тестов обойтись, в крайнем случае, потом тестов накидать. Если у вас большой проект (over 30k строк), то TDD не тормозит, выбросьте этот миф из головы.
Совсем другое дело, что люди не понимают как применять TDD на больших проектах. А всё потому, что кроме TDD надо разбираться как минимум в Agile Modeling. Без Agile Modeling, TDD может привести к тяжёлым дефектам, начиная с середины проекта.
У меня скорее средние, между 2к и 30к — 10-15к. Меньше 2к TDD сильно тормозит без ощутимой пользы. Ближе к 10к польза чувствуется, но скорее на перспективу. Agile Modeling — даже не встречал такого термина в книгах по которым TDD изучал. Agile — встречал, но не интересовался глубоко.
TDD для большого проекта тормозит еще больше. Тысячи написанных тестов нужно поддерживать. Сталкивались ли вы с такой ситуацией: система уже работает как надо, а вы тратите еще 1 день на то чтобы поднять тесты?
А как вы решаете, что система работает как надо? В TDD тесты идут вперед. Если они не работают, значит система работает не как надо. Или что-то не учли в формулировке «как надо», принимая решения не зафиксированные тестами до написания кода.
В TDD тесты идут вперед

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

Значит беда в некачественных интеграционных тестах.
Я говорю о юнит тестах
Для юнит-тестов не надо ничего сетапить. Как только речь заходит о сетапах — это уже не юнит-тест.
А по мне так ровно наоборот — чем меньше сетапов, тем ближе тесты к приемочным.
Для юнит-тестов не надо ничего сетапить. Как только речь заходит о сетапах — это уже не юнит-тест.
Юнит-тест — это не функция, покрытая атрибутом [Test] или [TestMethod] (в .NET).
Юнит-тест — это тест, обладающий рядом характеристик:
1. Повторяемость
2. Независимость
3. Полнота
4. Поддерживаемость
5. Быстрота
6. Читаемость

Как только появляется полносью не замокнутое внешнее окружение, то тест — уже не юнит-тест.

Кстати, сейчас прочитал ваш комментарий ещё раз. Хотелось бы уточнить, что вы имели ввиду под «актуализировать мокнутое окружение тестируемого класса»?
Как то противоречят друг другу высказывания:
Для юнит-тестов не надо ничего сетапить. Как только речь заходит о сетапах — это уже не юнит-тест.

и
Как только появляется полносью не замокнутое внешнее окружение, то тест — уже не юнит-тест.

Т.е. вы используете моки без их настройки (сетапов)
Для меня сложный сетап — это интеграционный сетап. А для моков я не встречал сложного сетапа (ну, это просто лично мой опыт).

Сложный сетап — это когда я прошу прицепить к серверу реально работающее устройство, чтобы тесты интеграционные проходили. Для такого сетапа мне официальный запрос в организации писать надо :)
Как это не надо? простейшая функция типа sum(a, и) и нужно сетапить a и b. Несвязанных архитектур практически не бывает. У функций (включая методы, включая конструкторы) бывают параметры, а параметры желательно инициализировать перед тестом.

Это не я имел в виду, но раз почти согласился, то поясню: был класс, от объекта которого зависело 100500 функций.методов (принимали как параметры) и в тестах вместо объектов этого класса мы подставляли моки. Класс немного изменили (публичное свойство заменили на геттер) и приходится исправлять все 100500 тестов.
Когда вы поменяли публичное свойство на геттер, пришлось править только тесты или ещё 100500 мест и в коде тоже?
И в коде, и в тестах. Причем в тестах может правок требоваться больше, иной раз в разы. Тесты хорошо решают задачу получения уверенности в рефакторинге, но для изменения интерфейсов они скорее преграда, чем помощь.
Так насколько я помню, одно из предназначений TDD и есть зафиксировать контракты, чтобы если что — сразу было видно где что надо менять.
EngineerSpock имеет в виду внешнее окружение — например, другие сервисы, БД, железки и проч. Для «юнит-теста» же достаточно самой программы, теста, и чем его можно запустить. Все.
под сетапами я имею в виду конфигураю мокнутых объектов, например библиотеки moq. Или у вас получается тесты писать без моков?
Хм, странно. Нет, я пишу тесты, используя моки (но не везде!). Ну, вот, например, мой последний проект: старт приложения проходит n-е количество этапов. Эти этапы зависят от библиотек моих коллег, которые общаются с устройствами. Для того, чтобы протестировать всю логику запуска приложения мне пришлось сконфигурировать моки как надо, но после того как я их сконфигурил — я их больше не трогаю.

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

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

Простите, но вы говорите глупость. В продукте, где я сейчас работаю, C# кода что-то около 400к строк. 1600+ тестов. Покрытие 75%. Две трети ночных билдов — зеленые. Когда они красные, то либо по делу падает пара-тройка тестов (и мы сразу чиним), либо от глюков на билд-площадке (тут уж ничего не омжем поделать).

Штука в том, что просто не надо запускать тесты, а сразу все вычинивать. Это такая же часть вашей программ, как и «обычный» код. В нем нет никакой разницы. Слмалось — почини. Сразу. В этом помогают в том числе gated check-in.
А чем, с точки зрения TDD, проект в пару тысяч строк отличается от проекта в десятки тысяч строк? Пользу от TDD можно получить уже на проекте с одним классом и одним публичным методом :)
Такой режим совершенно точно хорош для legacy кода. А вот насчет «писать сразу хорошо, но без тестов» сказать не могу.
Существует компромиссный вариант: писать тесты выборочно, только для самых критичных кусков кода, где наиболее вероятны трудновыявляемые баги. TDD очень полезная штука, но не надо впадать в крайности – фанатичное использование TDD сильно замедлит разработку.
Всё же основной задачей TDD считаю не выявление обычных багов, а контроль регрессий и стимулирование слабосвязанной архитектуры.
UFO just landed and posted this here
Почему все считают TDD тяжёлой практикой? Это обычное написание кода. Просто более надёжного. Больше писать? Ну, да, писать больше, но разве кого-то пугает количество писанины при наличии таких инструментов, которыми мы обладаем? (например, VS+R#) А раз количество писанины это больше не проблема, то проблема в качестве. А чтобы достичь хорошего уровня качества мы применяем TDD.
Можете подсказать инструмент, чтобы заметно меньше нужно было писать при использовании PhpUnit?
Прошу прощения, я говорил о высокоуровневых Java или .NET. Про остальное — врать не буду, не в курсе.
Уровни сравнимые. Есть подозрение, врать не буду, что для Java или C# (lkz .NET можно писать и на PHP), как для статически типизируемых языков, инструменты более развиты. То есть объёмы кода сравнимые или даже больше, но кнопок нажимать приходится меньше благодаря кодогенерации. Или вы что-то другое имели в виду?
UFO just landed and posted this here
Что значит «всё менять»?

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

Есть случаи, когда доменная область является нестабильной, как в банковской сфере, где может быть 1001 «особый клиент» не удовлетворяющий общей бизнес-логике домена. Но это особый случай. Как с этим бороться у меня опыта нет.
Я вообще вот что скажу. TDD, ИМХО, это не формализованный механизим разработки ПО от А до Я. Это свод рекомендаций, принципов и практик, которые могут быть иногда нарушены, если того требует ситуация. Если есть кусок, тесты под который поддерживать сложнее и дороже, чем просто тупо протыкать кнопки в рантайме, то зачем такие тесты?
UFO just landed and posted this here
Я считаю TDD тяжелой практикой (хотя сейчас на нашем основном проекте, мой код покрыт тестами на 40-70%), потому что за последние пять лет, практиковал TDD в нескольких компаниях, с совершенно разным подходом к разработке и количеством разработчиков на проекте от одного меня, и до семи (где я был ведущим или обычным разработчиком). И сейчас дома поднимаю небольшо й проект… в котором тесты появятся не раньше чем через 1-2 месяца (при той скорости разработки, которую я сейчас стараюсь поддерживать). Причин этому несколько:
1. Тесты отнимают время: Так за все эти пять лет никто не заметил, что тесты ускоряют написание кода. По сути плевать как будет писаться код — сначала код, потом тыкаем проверяем, а потом правим баги, либо вначале пишем тесты, а потом уже пишем код и правим баги. Тут такая ситуация, что если кусок кода не рабочий, и проще его проверить визуально при помощи echo\println или пройтись при помощи дебагера по нему (или что там у вас в языке) — то любой разработчик будет делать именно так. Причем тут не важно есть ли кусок кода на этот ест или его нет. Тест уже отработает потом. Причем то, что он пройдет вот не гарантирует стопроцентно, что код рабочий (привет продакшн в роли тестовой площадки, шесть утра и пять коктелей пина колады, которые помогли мне примерно за четыре часа отыскать косяк на код, который был покрыт тестами более чем на 9000%)

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

3. Есть такие сиутация где тесты ничего не решаеют. Об этом я писал в соседнем топике.

4. Тесты — это скучно, особенно при рефакторинге. Я не знаю людей которые бы сказали наоборот, что-то вроде «я люблю писать тесты потому что это круто! это весело и делает меня умнее». Нет, самый лучший тест — это самый тупой код, который может быть, который проверяет, а правильно ли работает твой самый замороченный код. Есть такие люди которые пишут тесты «с изюминкой». Говно это а не тесты, на большую часть из них придется еще одни тесты писать потому как тесты не работают.

Остальные причины, по крайней мере для меня, такие как: опыт написания тестов (не все умеют писать тесты) — менее важные, поэтому я их даже не стал расписывать.

Теперь почему я сейчас пишу проект без тестов (почти, есть некоторые тесты на куски кода, которые я просто не знал как написать и поэтому писал вместе с тестами. Покрытие менее 10%). Хотя они опять же появятся там, но чуть позже. Все очень просто — мне важна скорость. Мне нужно к концу месяца выдать готовый продукт, который примерно работает. Учитывая что сейчас у меня 5-й прототип, в котором опять было переписано примерно 70% кода — в этом есть смысл. Старый код, который не работает начинает работать потому как он у меня всегда на виду и я его уже правил несколько раз и багов в нем не осталось. А если и остались, то может быть через пару недель, когда я опять все перепишу и добавлю пару новых фишек — они вылезут и я их поправлю.

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

Прочел вашу статью и сразу вспомнилась эта цитата с башорга. Если не брать в расчет её окончания, то идея-то тут озвучена правильная. Пока ты будешь делать «как надо», другие напишут говнокод, обскачут тебя, а потом еще и три раза все отрефакторить успеют.

Вася и Петя одновременно начали писать один и тот же продукт.
Вася был «ориентирован на результат» и начал сразу писать говнокод не продумав толком архитектуру.
А Петя месяц разрабатывал архитектуру, месяц делал удобный интуитивный интерфейс, которому позавидывал бы Джони Айв, потом месяц писал тесты, потом два месяца писал сам код и получил идеальное стабильное приложение.
Но Вася выпустил уже через месяц первую версию программы, пусть и не идеальную, пусть с багами, но рабочую, и начал её продавать. Ещё через месяц выпустил вторую версию исправляющие баги первой и добавляющие новые баги. Ещё через месяц на доходы от продаж нанял двух толковых программеров, которые за два месяца перелопатили весь код, согласно пожеланиям пользователей допилили интерфейс и выпустили третью версию программы.
Итого, через пять месяцев у Васи было два работника, куча клиентов и сносно работающее приложение отвечающее желаниям клиентов.
У Пети было вылизанное никому не известное приложение, минус на банковском счёте и ни одного клиента.
В завершение этого выдуманного примера можно сказать, что через полгода Вася купил все наработки Пети, Петю взял в штат тестировщиком, а сам по пьяни разбился на своём новеньком Туареге
А причём здесь TDD и статья? Месяц разрабатывал архитектуру — никакого отношения к тому, что сказано в статье.
Вероятно это придуманная история, не имеющая никакого отношения к реальности. Какой смысл из выдумок делать какие-либо выводы?
А на баш это притащили с Хабра. И коммент этот человек написал ради фана, как пример выдуманной и притащенной за уши истории.
А я воспринимаю стартап, как возможность начать проект с чистого листа. Учитывая все прошлые ошибки, сделать код максимально хорошим. Думаю, что многие программисты мечтают о таком, но вынуждены поддерживать старый код.
Психологический посыл входа в ловушку понятен: не ошибается тот, кто ничего не делает. Т.е. надо выбрать такой угол вхождения в стартап — очень отличающийся от типового решения — при котором всё будет по-новому и неожиданному. Ведь проектировщик зачастую устаёт от отсутствия когнитивного сопротивления в процессе проектирования по шаблону, т.е. когда ситуация предельно ясна и прикладывать мозги особо не к чему, хочется почувствовать процесс проектирования хотя бы так: сделав маленькую революцию — ведь хочется делать работу, чувствуя себя умным, даже если работа — рутина на 99%. Но, вот с этого и начинаются проблемы. Ошибка такого посыла: в умозаключении вида «если ты не ошибаешься, то ты ничего не сделал; поэтому надо создать такую ситуацию, которая бы обеспечивала появление ошибки в проекте».
«Хуже того, я не писал терпеливо всю программу, проверяя, нет ли ошибок, я извергал безнадежно кривой код и постепенно приводил его в норму. Отладка, учили меня, — это последний заход, когда вылавливаешь опечатки и упущения. Я же работал так, что программирование походило на бесконечную отладку. Я долго из-за этого переживал — как из-за того, что карандаш держу не так, как учили в начальной школе. Посмотри я на других творцов, — на художников, архитекторов, — я бы понял, что у моих методов есть имя: эскизы. Насколько я понимаю, в колледже программированию меня учили совершенно неправильно. Программу создаешь в процессе написания, как делают художники, архитекторы и писатели.
Осознание этого факта реально влияет на разработку ПО. Язык программирования прежде всего должен быть гибким. Язык программирования — чтобы думать о программах, а не формулировать программы, которые уже обдуманы. Карандаш, а не ручка. Статический контроль типов — неплохая штука, если б программировали и впрямь так, как учат в колледже. Но ни один известный мне хакер так не работает. Нам требуется язык, что позволит карябать, сажать кляксы и стирать, а не вроде как сидишь с чашкой типов данных и вежливо беседуешь со строгой престарелой тетушкой-компилятором.»

Пол Грэм. «Хакеры и художники».
Не верю! Не было раньше TDD и других модных слов, а программы писали не хуже, а даже лучше. Я не спорю о ценности тестов, но скажу прямо, код прочитанный и перечитанный и сданный под личную подпись и ответственность исполнителя, будет идеальный! То же самое и с бухгалтером: проверял, не проверял, подписал. Если ошибся — вали.

А то какая-то ерунда получается, навалял говнокод, говнопротестировал — и свободен?
1) И трава раньше была зеленее, когда TDD не было.
2) прочтя ваш коммент, подумал что вы большую часть жизни в СССР прожили. Глянул в профиль — почти угадал — Беларусь.
Не будет он идеальным. Все мы люди, ве мы ошибаемся, глаз замыливается, что-то пускаем на авось (особенно регрессии) и т. п. По сути «зеленая полоса» в плане ответственности это подпись не под кодом, а под ТЗ — «всё требования реализованы, код прилагается». Тесты — способ формализации ТЗ (не важно, раз в 10 лет оно меняется или каждый день). Возникнет баг — легко можно проверить, была ли предусмотрена бажная ситуация в ТЗ (тесты написаны с ошибкой или не всё покрывают), или ТЗ было слишком общим, оставляющим разработчику широкое поле для допущений типа функция умножения в калькуляторе не должна возвратность значения большие по значению или точности чем стандартный int для данной платформы.
Сказан один бред. Товарищ это написавший просто возомнил, что сраное TDD можно сравнивать с бухгалтерией, в то время как это выдумки зеленных человечков.
Так и есть… Когда пойдут клиенты писать вторую версию будет просто некогда. Поэтому писать надо стараться сразу так, чтобы то, что ты писал было полезно в будущем. Хотя бы в части… Тесты нужны для развития системы, которая находится в продакшне. Ничто другое не способствует быстрому совершенствованию продукта. Автоматизация — это наше всё…
Комментарий относительно топика, но не конкртено. Я разработчик с ростущей командой под Android. Пытаюсь разобраться какие лучшие практики могут быть приняты, но как по мне, «просто» покрыть тестами android app где основной input есть ничто иное как UI, довольно сложно и не сравнимо с тем же back-end, где input параметры и есть точный набор функций которые эти параметры съедает. Кто что посоветует? Может кто-то уже работает и применяет практики для Android?
Спасибо.
я вот только не понимаю одной установки, почему, «как только попрёт рыба клиент, сразу посыпятся баги»?
вы перед запуском хоть раз сами запустили? или «о блин, мы запилили первую версию, скорее в продашкн, клиенты протестят»
А так и будет. Кол-во всплывших багов напрямую зависит от кол-ва активных пользователей. прогрммист может 1000 раз запустить свой проект и перепроверить каждую запятую и ничего не найти. А прибежит пользователь и в 5 минут уронит приложение в таком месте о котором программист даже и подумать не мог. Случается из-за того что девелопер знает что у него «под капотом» и уделяет максимальное внимание самым слабым на его взгляд местам кода. Часто и густо вижу такое в проде, идеально отлаженный с точки зрения бизнес логики код, лагает, например в UI, на аутентификации или работе с пулом подключения к базе.
Использует ли он двойную бухгалтерию?

Допускаю, что в российских реалиях это корректно, но уверен, что Дядюшка Боб имел в виду двойную запись, а не двойную бухгалтерию :)
Sign up to leave a comment.

Articles