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

Ежедневные утренние обсуждения (aka Daily Standup)


На мой естественный вопрос одному такому CTO — насколько ощутима польза от данного мероприятия, CTO честно ответил — «Я и сам не знаю». Несмотря на некоторые плюсы для команды, часть которой работала удаленно, обсуждения непременно сводились к «Вчера писал код, сегодня пишу код и завтра тоже планирую писать код, а, ну еще правлю такие-то баги». В итоге имеем минус полчаса с каждого члена команды. Некоторым плюсом для удаленщиков является ежедневное общение с командой, для некоторых это важно. На мой взгляд, польза для разработки от подобных ежедневных обсуждений довольно мала, так как основная задача таких всеобщих сборов — донести до всех информацию о текущем состоянии разработки, планы на ближайшее будущее (от недели до месяца), обсудить какие-то вопросы, которые интересуют всех. Очень часто подобные обсуждения скатываются в обсуждения каких-то нишевых вопросов, которые интересны паре человек, а остальные начинают скучать и ожидают, когда же это кончится. Это непременно должно пресекаться и обсуждаться позже, в более узком формате. Текущее состояние разработки и планы весьма важны, но их достаточно обсуждать раз в неделю или даже реже, в зависимости от скорости, с которой работает команда.

Развертывание в Cloud


На текущий момент доступно множество инструментов, которые позволяют описывать инфраструктуру проекта (сервисы, сети, зависимости) в удобной форме, например, Terraform. Вещь эта безусловно полезная, но с некоторого размера проекта, например, когда он становится достаточно сложным. Для большинства стартапов и небольших проектов, это избыточный инструмент, так как инфраструктура меняется крайне редко, а возможность быстро разворачивать еще один Production нужна, грубо говоря, раз в год, многие стартапы могут просто не дожить. Поэтому чем проще описан проект — тем лучше, многим будет достаточно и Docker Compose.

Покрытие кода unit-тестами


Чрезмерное увлечение тестами приводит к тому, что на это расходуются драгоценные ресурсы разработки, значительно увеличивает стоимость рефакторинга (ведь надо переписать все затронутые тесты) и часто создает иллюзию надежности кода и правильности его работы. Я встречал стартап, где после года разработки было написано более 2000 тестов только для backend! Чтобы эффективно двигаться вперед по разработке, тестами нужно покрывать только действительно важные участки кода, где выполняются какие-то вычисления и диагностика вручную ошибок затруднена. Часто для стартапов покрытие тестами можно отложить до момента, когда структура кода станет стабильной, а бизнес-логика станет ясной и вряд ли существенно поменяется. Для frontend unit-тесты зачастую малоэффективны, так как сложных вычислений и алгоритмов обычно там мало, а покрывать базовую функциональность SPA типа нажатий кнопок лучше на этапе BlackBox-тестирования через Selenium или им подобным.

Управление процессом разработки


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

Управление командой


Для Карго-культиста есть один путь и он ему следует. То, что управление командой нужно выстраивать исходя из текущего состояния проекта, его требований, квалификации и ограничений исполнителя, для него ново и он не придает этому значения, так как для него высок риск, что он не справится. Для него непросто признать, что к Senior и Middle разработчикам должно быть разное отношение, что есть разработчики с особенностями в коммуникациях, подходе к делу, ответственности. Для него все фигуры на шахматной доске примерно одинаковы, он и ходы делает примерно одинаковые. Про то, что нужно выявить и использовать самые сильные стороны у каждого разработчика он скорее всего и не слышал. Из-за этого эффективность работы команды значительно снижается, разработчики это прекрасно замечают и это делает их менее удовлетворенными от работы, обычно это характеризуется приличной текучкой. Часто такие CTO любят говорить, что у них все — Fullstack developers, хотя лично я крайне редко встречал одинаково сильных на frontend и backend, слишком много технологий нужно знать на хорошем уровне.

Как не стать/не быть Карго-культистом


  1. Всегда критически подходите к вводу новых сущностей (сервисы, технологии). Если в Вашей команде есть люди, хорошо знающие MySQL, но не работавшие с Postgres, то нет смысла выбирать Postgres, если это не дает Вам значительных преимуществ.
  2. Процесс разработки должен быть адаптирован под команду и бизнес. Если Вася работает по Scrum и покрывает все юнит-тестами, это не значит, что этот подход сработает и у Вас, нужно всегда критически оценивать и сравнивать с другими вариантами (Waterfall). Как правило, то, что работает для маленькой команды, перестает работать для большой и наоборот.
  3. Выявляйте сильные стороны у членов команды и используйте их по максимуму. Это повысит эффективность работы всей команды, а сотрудники будут более счастливы, ведь они приносят больше пользы за меньшие усилия.

Комментарии (96)


  1. Dimtry44
    26.09.2019 16:23
    +1

    Карго-культистом
    Карго-культурист звучит лучше.

    Ну и не забывать главного — вы не гугл.


    1. JordanoBruno Автор
      26.09.2019 16:34

      Культ и культура — две разные вещи, поэтому все же «Карго-культистом».


      1. Dimtry44
        26.09.2019 16:44
        -1

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

        Культист — звучит как будто человек с культей.


        1. mistergrim
          26.09.2019 17:21

          Тут кому что вспоминается
          image


          1. Cerberuser
            27.09.2019 05:04

            Патг'ончики!


          1. franzose
            27.09.2019 08:39

            Это же из Blood? Мы в детстве этих чуваков фантомасами называли :D


  1. Tufed
    26.09.2019 16:26

    Простите, но мне кажется, что статья не полная без объяснения основного термина статьи. Что же такое Карго-культ?
    «Когда вы делаете что-то, не имея иных причин к этому, кроме “в крутой компании делают так ” — вы становитесь адептом культа карго.» т.е. Обычно имеется в виду формальное применение тех или иных методологий без понимания соответствующих процессов.

    Говорят, что использовать термин “карго-культ” начали после этой речи Фейнмана.
    “У тихоокеанских островитян есть религия самолетопоклонников. Во время войны они видели, как приземляются самолеты, полные всяких хороших вещей, и они хотят, чтобы так было и теперь. Поэтому они устроили что-то вроде взлетно-посадочных полос, по сторонам их разложили костры, построили деревянную хижину, в которой сидит человек с деревяшками в форме наушников на голове и бамбуковыми палочками, торчащими как антенны — он диспетчер, — и они ждут, когда прилетят самолеты. Они делают все правильно. По форме все верно. Все выглядит так же, как и раньше, но все это не действует. Самолеты не садятся. Я называю упомянутые науки науками самолетопоклонников, потому что люди, которые ими занимаются, следуют всем внешним правилам и формам научного исследования, но упускают что-то главное, так как самолеты не приземляются.”

    © Р. Фейнман, “Вы конечно шутите, мистер Фейнман”


    1. JordanoBruno Автор
      26.09.2019 16:37

      Спасибо за пояснение, я бы предложил даже про Культ Карго рассказывать в самом начале обучения программированию и другим it-направлениям, может тогда будет меньше его последователей :)


  1. Max2UP
    26.09.2019 17:43

    Ежедневные утренние обсуждения (aka Daily Standup) — вот поэтому они должны быть не больше 15 минут, в командах не больше 6 человек. При этом задачи должны быть распределены так, чтобы на их выполнение было не больше 6 часов = 1 рабочему дню (в идеале). Тогда будет видимость прогресса и проблем. Все попытки длинных обсуждений должны сводится к «мы знаем проблему, мы знаем кто может помочь ее решить — отдельная встреча после standup».


    1. Dolios
      26.09.2019 21:44

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


      1. Ghedeon
        27.09.2019 00:33

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


        1. Cerberuser
          27.09.2019 04:45

          Другой вопрос, зачем вообще разработчику врать...


          1. Max2UP
            27.09.2019 15:50

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


        1. Kanut
          27.09.2019 09:01

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


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


          1. Max2UP
            27.09.2019 15:49

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

            p.s. в современных организациях мало кто пьет кофе вместе, курение так же уже не в почёте и много удаленных сотрудников.


            1. Kanut
              27.09.2019 19:40

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


  1. apapacy
    26.09.2019 17:57

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


    Но вместе с этим по меногим пунктам не поддерживаю.


    Ежедневные утренние обсуждения (aka Daily Standup)

    Да. Если 10 разработчиков работают рядом и задачи имеют часто не пересекающиеся — утренний стендап/митап или как его там это только минус 5 часов суммарно (каждый день) или 107 часов в месяц.


    Развертывание в Cloud
    … Поэтому, чем проще описан проект — тем лучше, многим будет достаточно и Docker Compose.

    cloud и docker-compose это разные вещи. Разворачивать продакшин проекты в облаке это просто удобно и зачастую дешевле чем на выделенном сервере. Но только если не на docker-compose. Применять docker-compose желательно там для чего он был разработан то есть для развертывания окружения разработчика или тестирования.


    Покрытие кода unit-тестами

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


    1. JordanoBruno Автор
      26.09.2019 18:08

      Да. Если 10 разработчиков работают рядом и задачи имеют часто не пересекающиеся


      Мне трудно представить эффективную команду, где 10 разработчиков не пересекаются. Что будет, если кто-то заболеет или уйдет в отпуск?

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


      Как раз это в разы дороже, чем на выделенном сервере, если, конечно, не Hello World разворачивать. То, что удобно — соглашусь.

      Если касается бэкенда покрытие желательно 100% чтобы быть уверенным что следующий коммит не сломал функионал бэкенда.


      Вот сколько я коммерческих проектов не видел, ни в одном не было даже близко 100% покрытия.

      Если Вы разрабатываете компонент то его независимая от общего кода проекта разработка просто немыслима без написания unit-тестов


      В чем немыслимость, компоненты без unit-тестов невозможно создать или сопровождать?


      1. apapacy
        26.09.2019 18:55

        Вот сколько я коммерческих проектов не видел, ни в одном не было даже близко 100% покрытия.

        У меня в этом плане другой опыт.


        В чем немыслимость, компоненты без unit-тестов невозможно создать или сопровождать?

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


        1. JordanoBruno Автор
          26.09.2019 19:01

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


          1. Dolios
            26.09.2019 21:47

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


            1. JordanoBruno Автор
              26.09.2019 21:57

              Что ж за фронтенд такой, где написание теста быстрее, чем поиск и починка багов? Диагностика — один из ключевых элементов разработки, ему здорово помогает логирование и хранение метрик ПО. Если изменения часто ломают другой функционал — это проблема плохой структуры или некорректных изменений и пытаться это лечить тестами — не очень эффективная задача.


              1. Dolios
                26.09.2019 22:32

                Любой большой SPA. На несколько десятков тысяч строк кода.
                Вот пример большого SPA, хоть и весьма специфический: https://www.onshape.com


                1. JordanoBruno Автор
                  26.09.2019 23:27
                  -1

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


                  1. Dolios
                    26.09.2019 23:35

                    А мой опыт мне говорит о том, что вы либо троллите, либо не понимаете, о чем пишите, уж извините.


                    1. JordanoBruno Автор
                      26.09.2019 23:43
                      +1

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


                    1. zorn_v
                      27.09.2019 07:05

                      По вашему 100% покрытие тестами учитывает 100% возможных факапов? (ололо кончилось место на диске)

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

                      Но вы про SPA, да. Но там вообще нереально сделать 100% покрытия

                      PS. Если без тестов вы боитесь изменить строчку кода, потому что хрен знает где может выстрелить — значит с вашим проектом УЖЕ что то не так, и тесты это припарка.


                      1. Dolios
                        27.09.2019 08:04

                        А где я писал то, что вы мне приписываете?


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


                        И как вам поможет грамотное логгирование, если, например, релиз отгружен, развернут на серверах заказчика и тот начал спотыкаться о баги, которые можно было выловить тестами?


                        1. max_mustermann
                          27.09.2019 16:12
                          +2

                          Ну вообще-то именно unit тесты как раз ничего вам не гарантируют. Я кучу раз видел у вот таких вот адептов 100% покрытия все тесты зелёненькие а вот нихрена не работает.

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

                          И как вам поможет грамотное логгирование, если, например, релиз отгружен, развернут на серверах заказчика и тот начал спотыкаться о баги, которые можно было выловить тестами?

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


                          1. Dolios
                            27.09.2019 16:17

                            кучу раз видел у вот таких вот адептов 100% покрытия

                            Вы тоже спорите с воображаемыми людьми у вас в голове? Можно цитату, где я писал, что я адепт 100% покрытия?


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

                            Где я писал, что они называются как-то по-дугому? Цитату, пожалуйста.


                            и если вы не понимаете как они помогают

                            Они не помогают никак предотвратить ситуацию: релиз с багами на проде заказчика. Вот вообще никак. А тесты помогают.


                            1. zorn_v
                              27.09.2019 17:50
                              +1

                              Да, что то я разошелся ) Претензии наверное были больше к автору ветки.

                              Вот сколько я коммерческих проектов не видел, ни в одном не было даже близко 100% покрытия.

                              У меня в этом плане другой опыт.


                              Это же откровенная ложь, либо «опыт» был на «hello world» )


                              1. JordanoBruno Автор
                                27.09.2019 18:03

                                Ну а что, джунам теперь на Хабре не комментировать что-ли? )


                                1. zorn_v
                                  27.09.2019 19:02

                                  -


                                1. apapacy
                                  27.09.2019 19:04

                                  Не думал что еще существуют компании которые не делают прокрытия близкого к 100% по — хочу подчеркнуть — бэкэнду. А то в пылу комментов это уточнение ушло. Разве фриланс. Сделал и забыл.


                                  1. zorn_v
                                    27.09.2019 19:33

                                    > Не думал

                                    Ололо no space on device )
                                    Иногда надо не думать, а размышлять )

                                    Что быстрее?
                                    Написать log.error('KAKAYATO HUINYA na stroke '+_stroka_+' v faile' + _fllename_)
                                    Или написать тест со всеми возможными и невозможными входными данными?

                                    И да, мы в реальном мире живем, а не с розовыми пони и разрабами пишущими тесты от души.


                                    1. Fedcomp
                                      28.09.2019 05:24

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


                                      1. JordanoBruno Автор
                                        28.09.2019 09:22

                                        Сколько бы тестов Вы не написали, в Вашем ПО все равно будут ошибки. Для их поиска и диагностики и нужны логи.


                                        1. Fedcomp
                                          28.09.2019 09:37

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


                                  1. JordanoBruno Автор
                                    27.09.2019 20:12

                                    Такие компании не просто существуют, а их большинство. Мы же в реальном мире живем.


                          1. zorn_v
                            27.09.2019 19:26

                            > На практике автотесты ловят только самые простые баги(

                            Но времени на них надо потратить прилично ) Не, я не против тестов. Если без фанатизма. Легаси какое нибудь покрыть и т.п.


                      1. Dolios
                        27.09.2019 08:14

                        P. S. Если вам наплевать на качество того, над чем вы рабртаете, то все совсем печально. Хреновый вы тогда специалист.


                        Видите, я тоже умею передергивать в вашей манере.


                        1. zorn_v
                          27.09.2019 19:58
                          -1

                          Но ведь тесты не дают «качество» )
                          Помогают держать на уровне (если он был) но не более.


                          1. Fedcomp
                            27.09.2019 20:14
                            +1

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


                            1. JordanoBruno Автор
                              27.09.2019 20:43

                              А тесты кто, ангелы пишут?


                              1. Fedcomp
                                27.09.2019 20:49

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


                                1. JordanoBruno Автор
                                  27.09.2019 20:53
                                  -2

                                  Тест — это тот же самый код, порой он сложнее тестируемого. Вы вообще тестами хоть один проект покрывали, кроме Hello World?


                                  1. Fedcomp
                                    27.09.2019 20:59

                                    вообще тестами хоть один проект покрывали, кроме Hello World?
                                    Я всего лишь писал тонну rspec тестов в разных проектах, юниты, интеграционные, браузерные.
                                    Еще раз, из практики — как я, так и другие программисты с которыми я работал — упрощали тестируемый код чтобы под него было проще писать тесты. Это работает.

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


                                    1. JordanoBruno Автор
                                      27.09.2019 21:01

                                      Ну раз тонну тестов написали, то должны понимать, что от «тяп-ляп» тесты не спасают. На это есть code review и нагоняй от тимлида.


                                      1. Fedcomp
                                        27.09.2019 21:04

                                        то должны понимать, что от «тяп-ляп» тесты не спасают
                                        А я где то говорил что это панацея? я всего лишь говорю что написание юнитов стимулирует и тестируемый код писать чище. Потому что гавнокод сложнее тестировать.


                                        1. JordanoBruno Автор
                                          27.09.2019 21:10

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


                                          1. donRumatta
                                            27.09.2019 21:59

                                            Тестопригодность и хороший код/архитектура понятия параллельные и не обязательно пересекаются. Но если в каком-то проекте пересеклись, то вот оно — счастье(=


                                            1. poxvuibr
                                              27.09.2019 22:14

                                              Тестопригодность и хороший код/архитектура понятия параллельные и не обязательно пересекаются.

                                              Тестопригодность — один из признаков качественного кода


            1. JustDont
              27.09.2019 00:12
              +2

              что изменения ломают какой-то другой функционал

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

              Компонентное построение фронтэнда — оно как бы и нужно в том числе для того, чтоб в явном виде иметь описанные зависимости. Вы меняете контракт компонента? Всё, что использует этот компонент, будет сломано. Если у вас помимо этого ломается что-то еще — увольте своего главного по фронтэнду нафиг.


        1. JustDont
          27.09.2019 00:16
          +1

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

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

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


    1. max_mustermann
      27.09.2019 15:57
      +1

      Если касается бэкенда покрытие желательно 100%

      А пустые геттеры и сеттеры — так вообще обязательно!


  1. SirEdvin
    26.09.2019 17:58

    Чрезмерное увлечение тестами приводит к тому, что на это расходуются драгоценные ресурсы разработки,

    Я так понимаю, что разработчики у вас просто пишут код и сразу заливают на тестовую среду? Ну, или вы предлагаете им тестировать локально руками?


    1. JordanoBruno Автор
      26.09.2019 18:01

      Конечно руками, если не по TDD-разработка.


      1. SirEdvin
        26.09.2019 18:04

        Вы же понимаете, что тестировать руками куда дольше, чем тестировать при помощи написанного теста, при условии:


        1. Что вы умеет писать тесты
        2. Что вы не пишете идеально работающий код с первого раз и локальное тестирование нужно будет как минимум несколько раз прокликивать


        1. JordanoBruno Автор
          26.09.2019 18:12

          Руками тестировать не дольше, более того, в большинстве случаев именно так и просходит разработка кода, если это не TDD. В некоторых случаях тесты могут сильно сократить время тестирования руками, например, когда разрабатывается какой-то алгоритм, преобразование данных, независимая библиотека. Но такого в большинстве коммерческих продуктов — не так много.


          1. FluffyMan
            26.09.2019 20:42
            +1

            Тестировать руками дольше в любом случае. «Запустить билд, который сам прогонит нужные тесты» vs «запустить билд, руками прогнать N тестов». И да, тесты Вы будете писать намного реже, чем их запускать. Точнее не так, писать то будете их часто, но время, затраченное на них, будет меньше времени, затраченного на ручного тестирования.

            Да и тесты это не только про TDD.


          1. DarkFIxED
            26.09.2019 21:15

            Я с трудом могу представить себе ситуацию, когда автотесты менее надежны, чем ручное тестирование.


            1. JordanoBruno Автор
              26.09.2019 21:24

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


              1. DarkFIxED
                26.09.2019 21:30
                +1

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


                1. JordanoBruno Автор
                  26.09.2019 21:46

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


              1. krokodily
                27.09.2019 12:54

                тестами все варианты не покроешь

                В ручную то, конечно, все варианты проверяете. Тесты пишутся для типовых и пограничных вариантов.


          1. Kanut
            26.09.2019 23:00

            Вы когда новую фичу добавляете вы только её тестите или проверяете не сломала ли эта фича что-то другое?
            Или скажем у вас никогда не бывает критических изменений которые хотя бы теоретически могут повлиять на любой кусок программы? И что вы делаете в такой ситуации? Всё ручками тестите?


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


            1. JordanoBruno Автор
              26.09.2019 23:25

              Вы когда новую фичу добавляете вы только её тестите или проверяете не сломала ли эта фича что-то другое?

              Все зависит от важности фичи и возможного его влияния. Для backend-фич, обычно, после тестирования ее разработчиком и того, кто принимает результат, она попадает в staging environment, где тестируется различными методиками на интеграции, включая Black Box. Если все ОК — идет в production.
              Важные фичи тестируются более тщательно, включая написание автотестов, если потребуется.

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

              В большинстве случаев баги будут отловлены через автотесты Black Box или QA. Если баг прошел мимо них, а не должен был — добавляем новые тесты или новые инструкции для QA(aka checklist).

              нет ресурсов ещё и им заниматься

              Как Вы правильно заметили, ресурсов всегда не хватает и правильное их распределение — это искусство управления, то есть вотчина тимлида и выше. Со временем правильно выстроенные процессы позволяют практически гарантированно отловить все критические баги, а не критические — допустимы.


              1. Kanut
                26.09.2019 23:44

                Ну у нас ресурсов не хватает по одной простой причине: легаси кода много и он не особо хорошо покрыт автотестами. И произошло это потому что кто-то "умный" в своё время решил что не "надо покрывать всё автотестами и хватит только критические компоненты покрыть" .


                И мы все этому человеку очень-очень "благодарны". Особенно тестеры и саппорт.


                1. JordanoBruno Автор
                  26.09.2019 23:48

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


                  1. Kanut
                    26.09.2019 23:57

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


                    1. JordanoBruno Автор
                      27.09.2019 00:00
                      +1

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


                      1. Kanut
                        27.09.2019 00:03

                        Я бы не был так категоричен. Думаю убедить его можно было.


                        Да и сейчас его не то чтобы прямо спрашивали хочет он автотесты или нет.


                      1. poxvuibr
                        27.09.2019 13:01

                        Уверен, что клиент бы и первом этапе создания не захотел бы оплачивать 100% покрытие тестами

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


                  1. poxvuibr
                    27.09.2019 13:00

                    Что Вам мешает покрыть тестами этот легаси-код сейчас, если возникла в этом потребность?

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


                1. 0xd34df00d
                  27.09.2019 16:33

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


                  1. Kanut
                    27.09.2019 19:45

                    Если говорить в теории, то да, никогда не знаешь. В нашнм конкретном случае скорость особой роли не играла. У нас "клиент" это наш материнский концерн и их скорее интересует "средняя скорость на отрезке в десять лет", а не "ускорение на старте".


                    1. 0xd34df00d
                      27.09.2019 20:06

                      В таком случае да, никаких вопросов.


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


  1. Alex_ME
    26.09.2019 21:28
    +2

    • Я не сторонник TDD, но юнит тесты очень помогают разработке, позволяя в процессе написания (либо после написания) модуля найти возможные ошибки, которые там просто гарантированно будут (вряд ли вы прям так сходу пишете идеальный код). И с помощью сделать это проще, чем запуская руками, потому что руками вы фактически тестируете какую-то более сложную систему. Помимо этого в процессе написания теста еще раз очень внимательно смотрится код и можно найти еще какие-то проблемы.
    • Тем не менее, помимо юнитов нужны интеграционные тесты, потому что по-кускам может работать, а в целом — нет. Тут, кстати, у меня есть непонимание, что считать юнитом. Вот какой-то юнит. Собрали несколько юнитов в юнит большего размера. И какой это будет тест? На проекте мы вообще отказались от подобного именования
    • Coverage — это инструмент, может, полезный, но надо правильно интерпретировать результаты и он ничего не гарантирует. Приведенный ниже код имеет 100% line и branch coverage, но он неправильный, и тесты неполные. Нет ни проверки возможных ошибок, ни тестов на них.

    Заголовок спойлера
    int sum_values_in_file(const char* file, int* result)
    {
             FILE* f = fopen(file, "r");
             int val;
             *result = 0;
             while (!feof(f)) {
                    fscanf(f, "%d ", &val);
                   *result += val;
            }
            return 0;
    }
    
    /* Test case #
       File: "1 2 3 4 5"
       Expected: return 0, result 15; */


    1. JordanoBruno Автор
      26.09.2019 21:44

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

      Никто ж не говорит, что unit-тесты всегда бесполезны и их нельзя применять. Это как один из инструментов для повышения качества продукта вполне эффективен, в определенных ситуациях и правильно написанные. Еще есть, как Вы правильно заметили, интеграционные тесты, а также Black Box и Input Validation тестирование, перекрестный code review, парное программирование, проверка кода специальными тулзами на ошибки — все это тоже повышает качество продукта. Естественно, за это нужно платить временем разработчиков/тестеров и другими ресурсами, что неизбежно. Для некоторых типов проектов, например, стартапов, это малоприменимо, так как нет столько времени на раскачку, а требования меняются чуть ли не ежедневно, что тянет за собой изменение тестов. Вполне работает для стабильных Enterprise-проектов с размеренными процессами и богатыми на ресурсы.


      1. poxvuibr
        27.09.2019 13:08

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

        Ну да, в основном говорят, что юнит тесты полезны в 90 процентах случаев.


        Это как один из инструментов для повышения качества продукта вполне эффективен, в определенных ситуациях и правильно написанные.

        Примерно в 90 процентах случаев этот инструмент эффективен, да.


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

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


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

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


    1. lxsmkv
      27.09.2019 04:46
      +1

      Лучшее обьяснение разницы между юнит- и интеграционными тестами:

      image

      Граница юнита это его интерфейс. Когда две компоненты взаимодействуют это уже интеграционное тестирование.

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

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

      Да, юнит-тест это атомарный уровень. Часто мы инициализируем кучу компонент для выполнения нашего юнит-теста, потому что зависимости™. И такой тест будет отчасти уже интеграционным тестом. Хотя инициализация зависимостей не является предметом теста, она будет проверяться неявным образом.

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


  1. daiver19
    27.09.2019 05:08

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

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


    1. 0xd34df00d
      27.09.2019 16:35

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

      Следует ли из этого, что юнит-тесты не нужны при достаточно выразительной системе типов?


      1. lxsmkv
        27.09.2019 16:55

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


        1. 0xd34df00d
          27.09.2019 17:09

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

          Это точно можно выразить в типах.


          Делая на эту функцию юнит тест мы с одной стороны проверяем, что функция правильно рассчитывает эту ставку, на примерах

          Какого рода примеры вы рассматриваете? Если это что-то вроде «если x = 4, y = 5, z = 3.5, то f(x, y, z) = 25», то да, тест тут самое оно. Если же вы хотите сформулировать и проверить утверждения вроде «у женатого человека налоговая ставка всегда меньше, чем у неженатого», «если человек ИП, то налоговая ставка не превышает 8%», и так далее, то тесты тут не очень помогут.


          1. lxsmkv
            27.09.2019 21:34

            Если же вы хотите сформулировать и проверить утверждения вроде «у женатого человека налоговая ставка всегда меньше, чем у неженатого», «если человек ИП, то налоговая ставка не превышает 8%», и так далее, то тесты тут не очень помогут.
            Это т.н. бизнес-правила, их тоже можно и нужно проверять автоматически. Тут зависит от реализации, если это все параметры одной функции, то можно тестировать функцию. Если это все разбросано по разным модулям, то тестируем сценарий через связку компонент. В некоторых системах вообще используются middleware с движком для бизнес-правил, в таких системах свои инструменты тестирования (см. Oracle Fusion, Oracle BPM).
            Нужно самому решать на каком уровне тестировать. В конце концов можно сделать сквозной тест. Просто это самый трудозатратный способ. У сквозного теста полный охват, и поэтому он будет чувствителен к изменениям любых нас не интерсующих (в конретной точке проверки) деталей.
            Другое дело, что невозможно с помощью тестов показать полную безошибочность программы. Это следствие теоремы Райса Но это не значит, что тесты нам не помогут.


            1. 0xd34df00d
              27.09.2019 21:41
              +2

              Это т.н. бизнес-правила, их тоже можно и нужно проверять автоматически.

              Вы не сможете их проверить автоматически при помощи тестов, потому что там квантор всеобщности.


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

              Нет, это снова следствие того, что область определения вашей программы бесконечна (или конечна, но имеет такую мощность, что это уже «почти бесконечность»).


              Теорема Райса тут вообще ни при чём. Из теоремы Райса следует, что нет алгоритма, который бы получал на вход текст программы и спеку и решал, соответствует ли программа спеке или нет.


              К счастью, алгоритмически показать соответствие программы некоторой спеке таки возможно (всякие там идрисы-коки этим и занимаются). И они даже не противоречат теореме Райса (тайпчекинг разрешим, а вот type inference — нет).


              1. lxsmkv
                27.09.2019 23:36

                Конечно выборочные проверки, брать всю область определения не целесообразно. Задача тестов давать информацию, если информация не нужна то и тесты не нужны.
                За замечание про интерпретацию теоремы Райса спасибо. Намотал.


                1. 0xd34df00d
                  28.09.2019 18:11

                  Конечно выборочные проверки, брать всю область определения не целесообразно.

                  Ну, это, формальные доказательства же.


                  1. mayorovp
                    30.09.2019 08:33

                    А формально доказать правильность расчёта ставки и не получится. Просто потому что формализовать понятие "правильное рассчитанная ставка" так же сложно как и написать сам расчёт, и в процессе формализации можно без проблем допустить ровно те же самые ошибки, что и в расчёте.


      1. Alex_ME
        27.09.2019 19:31

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


        1. 0xd34df00d
          27.09.2019 20:07

          Но они есть же!


  1. orcy
    27.09.2019 07:20

    Завтрак — это карго-культ. Стоишь у плиты 15 минут только чтобы получить эту стрёмную овсянку, со склизкой текстурой, которая еще говорят не полезна нифига и запиваешь растворимым Nescafe…


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


    1. apapacy
      27.09.2019 19:01

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


      Видео


  1. slonopotamus
    27.09.2019 09:31

    У вас взаимоисключающие параграфы: «Управление процессом разработки» и первый пунктой из «Как не стать/не быть Карго-культистом».


  1. GoshaZ
    28.09.2019 08:14

    Больше похоже на какой-то «Карго-оккульт», если честно.