Comments 115
Существуют вариации переработки таких систем в тестопригодные?
1. Пропустить пользователя с валидным билетом.
2. Показать предупреждение, если билет поддельный (не найден код в базе данных).
3. Показать предупреждение, если билет уже использован (например, дал другу, он распечатал такой же куар-код).
Проблема в чем: в ручную тестировать относительно легко: распечатать несколько куар-кодов и подностиь к камере, проверяя каждый из трех сценариев.
Но автоматически это сделать сложно.
Решение:
1. Изоляция компонента, который сканирует куар-код и подстановка тестового двойника.
2. Моканье (mock) метода SDK, который возвращает считанный код.
Автоматический тест для каждого из трех сценариев будет подставлять заранее известный код, как будто бы он пришел с реальной камеры, и сравнивать на него реакцию на визуальном интерфейсе с ожидаемой.
В целом этот большие сложные системы, в которых:
а) сложный граф зависимостей её частей, вследствие чего практически невозможно инициализировать конкретную часть без инициализации всей системы
б) различные виды IO не вынесены в изолированный слой. Сюда же работа с текущими датами/временами и случайными числами
в) активная работа в коде с глобальными состояниями, включая глобальные переменные, и, как их разновидность, статические переменные классов, в том числе в синглтонах
г) неактуальная или вообще отсутствующая документация по архитектуре, конфигурированию и развёртыванию системы, в лучшем случае тестовые окружения периодически синхронизируются с продакшеном с "вырезанием" потенциально чувствительных или просто объёмных данных, притом, как говорится, на глазок, без чёткого понимания может ли, например, система в принципе работать, если, скажем, в базе данных ни одного пользователя нет.
д) много захардкоженных значений типа имен и портов внешних сервисов
Способов переработки много, в целом они заключаются в уменьшении связанности отдельных частей системы друг с другом и средой исполнения без изменения функциональности, то есть один из видов рефакторинга. Основная проблема (если вопрос с руководством о повышении тестопригодности уже решён) — обычно нетестопригодные системы почему-то тестами не покрыты или покрыты очень слабо, а значит приводя систему в тестопригодное состояние мы вносим изменения корректность которых автоматически проверить не можем, только путём полного ручного регрессивного тестирования, что обычно очень дорого. Хорошо если рефакторинг ограничивается автоматизированными средствами рефакторинга, например из инструментов IDE, но часто нет.
В проблеме сразу и отгадка: не покрыты, потому что нетестопригодны. :)
Из нашего опыта для нетестопригодных систем:
1. Расставляем функции по приоритету в соответствии с ценностью для клиента/пользователя.
2. Пишем высокоуровневые (UI или API) тесты.
Тем самым снижаем вероятность внесения случайных регрессий.
Хоть какие-то тесты лучше полного отсутствия.
В проблеме сразу и отгадка: не покрыты, потому что нетестопригодны. :)
Надо было кавычки поставить вокруг "почему-то" :)
- На практике лучше себя показывает анализ флоу разработки. Какие файлы чаще меняются, в каких больше ошибок выявляется на всех стадиях и т. п. — те и покрываются тестами в первую очередь.
2. Пишем высокоуровневые (UI или API) тесты.
там может быть намного сложнее с наблюдаемостью…
А еще можете привести примеры нетестопригодных систем?
Тестопригодность это же не бинарное свойство. Совершенно непригодных для тестирования систем вряд ли много. Но вот плохо приспособленных — полно. В компании где я работаю сейчас, например, частая проблема в слишком сильной связности компонентов. В результате для тестирования такого компонента приходится либо описывать простыню моков втрое длиннее чем собственно сам тестируемый класс, либо уходить на более высокий уровень функционального/интеграционного или даже системного тестирования, что на порядок дольше даже для сопоставимого количества тестов. А количество не сопоставимо из-за комбинаторного взрыва.
P.S. Я не уверен насколько мой комментарий понятен, поэтому не стесняйтесь спросить если что.
Например, идеальная тестопригодность у функции:
def sum(a, b):
return a + b
Потому что совершенно не нужно прикладывать никаких усилий, чтобы ее протестировать. :)
Очень сложно внедрить автоматические тесты, если программист не обучен методам тестопригодного проектирования или если менеджмент не поддерживает культуру надежного программирования в организации.С точки зрения кого нужно их внедрять? Вы здесь в какой роли, консультант, рядовой программист, менеджер смежного подразделения?
То что тесты нужны, мне например очевидно, статью с интересом прочитал, всё доходчиво, всё по делу. Условный Василий, мой коллега за соседним столом, тоже статью прочитает, если я ему скину ссылку, но сделает для себя прямо противоположные выводы, он-то пишет быстро и четко, рефакторинг не практикует, тесты/отладка вручную 1 раз при написании, затем код лежит и не меняется практически, зачем тратить в 2-3 раза больше времени, у него свой путь. Нет, через год-два-пять, по мере разрастания проекта или работы с горами чужого легаси он конечно поймет, что тесты нужны, рефакторинг важен, и т.п. Но он поймет это сам, отбив себе всё самолюбие собственноручно расставленными в прошлом граблями. Наверное только так, через боль и унижения, это всё усваивается, а не по указке сверху.
Когда я будучи стажером-третьекурсником работал в одной компании, мне дали рутинную задачу на тестирование, которая вручную заняла бы неделю. Я не пожалел двух вечеров, написал скрипт, который все то же самое сделал за один день.
В одной организации, которую я консультировал, таким драйвером изменений выступил собственник и СЕО, который потерял на разработке ненадежного ПО 70000 (семьдесят тысяч) долларов своих личных средств.
Мне такие «Василии» знакомы. Для таких Василиев шанс для изменения, увы, только один — это глубокий кризис. Такие кризисы рано или поздно переживают все программисты: это и бессонные ночи на работе, и увольнения, и штрафы, и судебные иски. Те моменты, когда человек уверенно говорит: «Никогда в жизни больше я не буду писать без автоматических тестов!»
Мы с единомышленниками видим такую стратегию изменения культуры программирования:
1. Сформировать новый источник этических профессиональных норм. Иными словами, сформулировать, что хорошо, что плохо. «Тесты, рефакторинг — хорошо», «Редактировать исходники прям на сервере — плохо».
2. Подготовить материалы (статьи, курсы, видео) в поддержку п. 1. Чтобы нельзя было сказать, что мы голословны и кидаемся громкими лозунгами.
3. Пропаганда этой новой культуры надежного программирования.
Программист «Василий» должен сам добровольно выбрать, на какой он стороне: с тестами, рефакторингами и счастьем? Или без тестов, с авралами и без работы? :)
«если срочных задач нет» — 99% срочных задач можно было бы избежать, если бы заранее было сделано надежно: проработаны требования, архитектура, сделан код ревью, написаны тесты. ;)
Ох, я как раз в процессе донесения мысли до разработчиков и менеджеров что отсутствие тестов — это технический долг и незаконченная задача, а не место куда можно слить свободное время когда оно есть (а его естественно нет). Я такой здесь не один, и дело движется впрочем, так что все не так уж и плохо.
Не согласен. По пунктам:
- профессионал не должен доказывать ничего руководству или заказчику на этапе сдачи работы, если это не предусмотрено законом, договором или заданием. Есть конкретные претензии? Назовите, обсудим это невыполненные требования или новые. Нет? Оплатите. Писать тесты в оплачиваемое время без ведома заказчика и руководства — в лучшем случае неэтично.
- это возможно и без автоматических тестов, ручным тестированием по тем же кейсам как минимум. Даже юнит тесты можно вручную делать, особенно если язык интерпретируемый или имеет "псевдоинтерпретатор" в наборе инструментов.
Вот тут-то и самое интересное! Профессионал прислал работу, сказал: «Я все сделал», руководитель полез перепроверить, а там на 2 из 10 юз-кейсов приложение просто крешится. Говорить «я все сделал», когда на самом деле «я что-то там написал, но не проверял» — это непрофессионально и ненадежно.
«это возможно и без автоматических тестов, ручным тестированием»
Повторюсь, 500 тест-кейсов для мобильного приложения «Онлайн-кинотеатр» тестировщик проверяет за 40 рабочих часов для одной версии iOS, а поддерживаем мы их три. Автоматический тест смог бы проверить правильность за несколько часов.
И как вы себе представляете тестировать, например, копилятор языка в ручную без автоматических тестов?
Ну, то есть всё же не невозможно, а вполне конкретных и реальных 40 часов занимает. Если релизы раз в месяц, то одного тестировщика хватит с запасом. Можно обсуждать что выгоднее в тех или иных аспектах. Покрыть такое приложение автотестами на всех уровнях скорее всего займёт довольно много времени минимум трёх человек: разработчика, тестировщика и девопса. При том необходимость в тестировщике не исчезнет вообще после покрытия. И время всех троих надо будет тратить и на поддержку, и на развитие. Может оказаться выгодно, может нет.
Ну я тестировал, написанный мной транслятор языка вручную. Это с одной стороны. С другой, писать тесты или нет, насколько полно их и писать и т. п. — это вопрос экономической целесообразности обычно. При этом нельзя забывать, что тесты — это не гарантия отсутствия ошибок, это лишь повышение вероятности обнаружения некоторых ошибок автоматически.
Ваши действия? :)
А если серьёзно, то абстрактные ситуации обсуждать можно бесконечно, нужно считать конкретные, пускай и на основе оценок, типа тестировщик стоит столько-то, разработчик столько-то, такую-то часть своего времени он будет тратить на тесты, что освободит столько-то времени тестировщика и т. п.
На мой взгляд тесты — вообще не дело заказчика. По крайней мере юниты. Юнит тесты — это часть процесса разработки. Их не нужно даже пытаться продавать. Поэтому и к этике не имеет никакого отношения. Есть требования, есть сроки, как конкретно разработчик делает свою работу клиента не должно волновать, его должен волновать результат. А результат при разработке с тестами обычно лучше чем без них.
Отвратительная статья. "Вы все дураки и не лечитесь, только я знаю, что вам надо". И автор думает, что с таким настроем ему удастся кого-то убедить в необходимости автоматизированного тестирования? (а оно таки зачастую очень нужно, но такие вот, с позволения сказать, "евангелисты" только отбивают людям охоту его внедрять… Нужен ведь не такой "энтузазист", а специалист, который поможет внедрить малой кровью)
«Нужен ведь не такой „энтузазист“, а специалист, который поможет внедрить малой кровью»
Перед тем как внедрять, нужно понять, почему это не было внедрено уже. Ведь в интернете есть кучу книг, статей и фреймворков — любой человек может скачать и внедрить. Но этого не происходит.
Врач, перед тем как лечить, проводит диагностику пациента, чтобы знать как и отчего лечить.
Если вы внимательно прочитаете эту отвратительную статью, то там для некоторых проблем даже наметки решения есть.
К сожалению, объем статьи не позволяет сразу и решение расписать. Это темы для будущих статей.
Если у вас уже есть решения — прошу, напишите!
У меня нет никакого универсального решения. И вообще на моей совести только один эпизод "внедрения" тестирования не для себя, много лет назад, когда я, увидев, как коллега мучается с выводом и реализацией правильной формулы в проге (расчёт каких-то отрезков при клике мышью или типа того), сказал: "да ты сдохнешь так её делать, напиши юнит-тест".
Насчёт "намётков решения" из статьи — они, как вы понимаете, хорошо расписаны во многих других источниках :-). Но я писал не об этом, а о чисто психологическом моменте. Если с таким подходом продавить (а речь идёт именно о продавливании) автоматизированное тестирование — то получите вольный или невольный саботаж. При любой проблеме все будут радоваться, что вы сели в лужу — кроме, может быть, немногих чистых душой :-)
Такие виды тестирования не автоматизируются. Максимум, А/Б тестирование со снятием целевых метрик типа конверсии.
Ну а так, да, например, Скайп меняет дизайн ежемесячно — я уже не то, что офигеваю, я просто не понимаю, куда нужно нажать, чтобы просто початиться с человеком. :)
- Нужно сделать Minimum Viable Product за заниженные в 2-3 раза сроки. Ну, вроде пока ничего страшного — жертвуются автоматическое тестирование и расширяемая архитектура, пишется миниальное решение и тестируется вручную, благо скудный набор фич позволяет. «А потом если что переделаем»
- Возникает набор дополнительных, «необходимых вчера» фич. Приоритет отдается им, проектирование архитектуры и тесты уходят на второй план.
- Проект потихоньку растет, из-за плохой архитектуры проект обрастает костылями и становится
малонепригодным для тестирования, усложняется поддержка, рефакторинг напрашивается, но менеджмент по очевидным причинам не одобряет огромные трудозатраты на него. - Проект развивается очень медленно, превознемогая регрессии и руководствуясь девизом «работает — не трогай».
Что необходимо чтобы так не происходило? Да черт его знает
Достаточно поменять у некоторых и большинство подтянется. Да, может остаться пара упертых программистов, но такие либо уйдут под давлением, либо их переведут туда где это все не так важно. Для этого конечно нужна поддержка от тимлидов и/или менеджеров, зависит от организации процессов и иерархии. Если же проблема изначально в менеджерах — тут тоже можно бороться, но успех к сожалению не гарантирован. Но вообще — автоматизация тестов не должна подниматься как вопрос делаем/не делаем. Это часть процесса, нигде же уже менеджеры не требуют писать не меньше скольки то строк кода в день, команда сама решает как ей удобно писать и как лучше добиться результата. Вот и тут то же самое — автотесты это дело самой команды их вообще незачем обсуждать с менеджерами.
С какой стати? Дело менеджера — насколько продукт соответствует желаниям заказчика с одной стороны, и насколько много можно продать клиенту того что может сделать команда с другой. Процесс разработки включающий или не включающий тесты его никак и никогда не касается. Если менеджер считает что касается — значит он не компетентен. Это конечно мое мнение и мы можем аргументированно о нем поспорить, но на данный момент я не вижу ни одной причины менеджеру лезть в репозиторий, хоть центральный, хоть локальный.
Насколько я знаю кодирование занимает меньше половины времени разработчика. Увеличение этой части даже на 30% заметного влияния не окажет. А думать над архитектурой тестов много не нужно и чем больше опыта в их написании тем меньше времени на обдумывание требуется.
Это да, но вот здесь я и говорил что с опытом необходимое время снижается очень значительно. При этом разработчик, который умеет писать более тестируемые программы (тестопригодные? как-то криво звучит на русском все равно) выигрывает в стоимости поддержки даже когда тестов нет. Просто потому что чем проще продукт тестировать, тем проще находить и устранять недочеты, хоть руками, хоть автоматически.
Разработчики озвучивают оценки сроков, их зарплата известна, если конкретно эти люди работают больше месяца в компании, то менеджеру должны быть также известны риски и он должен уметь оценить как нужно поставить дедлайн команде чтобы риски минимизировать. Это, опять же, никак не относится к способам разработки. Команда либо способна реализовать в приемлимые сроки, либо нет. Если сроки менеджера устроили, то какое ему дело пишет команда автотесты или танцует с бубнами и призывает духов. А с вашим подходом можно дойти до того чтобы со стороны менеджера регламентировать количество классов и методов в них. Ну а что, больше методов — больше кода написано, а занчит больше времени потрачено. И рефакторингом менеджер должен управлять. А еще имена переменных можно ограничить тремя буквами. А то тратят разработчики время клиента на написание длинных переменных, как так то?
Естественно что это преувеличение, но принцип тот же — менеджер лезет во внутреннюю кухню команды и пытается что-то регулировать.
Менеджер — не технический специалист. Его задача — управление людьми, управление рисками и общение с заказчиком. В вашей версии области ответственности менеджера шде проходит граница после которой разработчики могут сами решать как им писать код? Это касается только тестов? Почему? Почему не имен переменных или строк кода в день? Распространенная практика в свое время между прочим была.
На мой взгляд процесс должен выглядеть так: команда технических специалистов получает задачу, оценивает ее, после обсуждения требований, получения уточнений и так далее, в общем после обычного процесса постановки задачи, команда выдает свою оценку необходимого времени и, возможно, каких ресурсов ей не хватает. Ну например нужны еще разработчики, дизайн, что-то еще. И вот эта оценка — то с чем работает менеджер. Входят в нее тесты или нет — не его дело, так же как не его дело сколько строк кода будет написано для решения этой задачи. Если оценка не устраивает менеджера или клиента, то дальше начинаются переговоры. Но они идут не о том, какую часть процессса разработки нужно выпилить, а чем можно пожертвовать из задачи, или насколько качественно она должна быть сделана. Вот тут команда может решить что тесты не нужны, например потому что это разовый таск или потому что фича нужна для галочки в документах или ТЗ (частая ситуация при работе с правительственными структурами). Но это все равно не область компетенции менеджера, это решение команды делать так или иначе.
Уточнение — естественно менеджер часть команды с точки зрения клиента. Но он не часть команды разработчиков, он не пишет и не проверяет код, от него требуется совершенно другая квалификация. Я бы даже сказал что совмещение позиции разработчика и менеджера только усложнит процесс, это будет недостатком а не преимуществом. Но тут я могу только рассуждать, вживую я таких людей не видел.
Менеджер — не технический специалист
Почему? Менеджер — это очень размытое понятие. В том числе может быть техническим специалистом типа Королёва и Глушко
Да, само понятие достаточно размытое, но я имею ввиду именно человека, который общается с клиентом, оценивает риски и управляет людьми. Он может одновременно быть еще и на должности технического специалиста, как я ответил чуть ниже, но это все-таки очень разные должности и я сомневаюсь что людей способных на высоком уровне такие должности совмещать много.
Технический бэкграунд в ИТ — это замечательно, но я говорил немного о другом. Я говорю о том, какую работу этот человек выполняет, какие у него обязанности, какая область ответственности. Проблема не в накоплении знаний из двух областей, проблема в выполнении всей необходимой работы на двух весьма разных должностях. На мой взгляд это реально только для либо очень талантливых людей, либо для весьма небольших проектов. Но я, конечно, могу ошибаться.
Вы так и не ответили почему решение о написании тестов входит в компетенцию менеджера, а количество строк кода в день или длинна переменных — нет.
Я не знаю про классического тимлида, в моем опыте было всегда так: есть главный технический специалист команды, где-то его назвают тимлидом, где-то архитектором, он отвечает за выбранные технологии и архитектуру в целом, но он не ставит задачи и не получает требования от клиента напрямую. Его задача — оценить различные технические способы решения.
И есть тот, кого я все эти комментарии называю менеджером. Это человек, который принимает решения в целом: эту фичу мы делаем, эту — нет. Он общается с клиентом чтобы узнать что ему нужно и с командой чтобы получить оценку сроков и рисков. Это — не технический специалист.
Основная суть разделения — тимлид решает как делать, а менеджер — что.
Да, эти позиции, наверняка, могут совмещаться в одном человеке. Я правда такого не видел и вообще сомневаюсь что в относительно большом проекте одного человека хватит на обе должности, возможно где-то в стартапах или просто небольших проектах разве что. Но это все равно две разных позиции с совершенно разными требованиями к скилам челвоека. В первом случае это должен быть хороший архитектор разбирающийся во всех затрагиваемых областях проекта. Пусть не детально, но разбирающийся. Во втором — это управленец и переговорщик. Ему не нужно разбираться в технических деталях, ему нужно уметь управлять людьми, оценивать риски, уметь добиваться от клиента нормально сформулированных требований и уметь продать клиенту фичи которые ему может предложить команда.
Юнит, интеграционные, системные тесты — в компетенции первого, да и то с юнитами можно и поспорить, это в первую очередь компетенция каждого отдельного разработчика. Приемочные тесты, если они есть — могут быть в компетенции второго. Имеется ввиду именно решение о написании этих тестов, не собственно написание конечно.
Я чаще встречал разделение руководства командой на два человека: ПМ и тимлид. ПМ занимается контактами с внешним миром по административным и финансовым вопросам, тимлид в эти контакты вовлекается в роли технического консультанта и сборщика технических требований, вплоть до «спасибо, а теперь иди, мы бюджет обсудим», но он осуществляет декомпозицию проекта на задачи и подзадачи, назначение конкретных исполнителей, первичный контроль за ними, установлением проектных/командных стандартов и т. п… ПМ же обычно мониторит общий прогресс исполнения, и напрямую в команду не лезет, вопросы типа «вот по этой задаче эстимейты превышены, что случилось?» он задаёт тимлиду прежде всего.
В целом получается что управление проектом распределяется между двумя менеджерами, один из которых полностью берёт на себя техническое руководство и, обычно, сам решает некоторые технические задачи, часто архитектурного плана.
Именно такого ПМ я и называл в своих комментариях менеджером. Проясните свою позици пожалуйста, вы считаете что именно ПМ должен принимать решение о написании юнит тестов?
Для рендера и UI могут подойти тесты, которые сравнивают результаты рендеринга (скриншоты) с эталонными с какой-то долей погрешности. Например, если кадр совпадает на 99% с эталонным, то все ок, если 95% — то все плохо.
Кроме этого на рендеринг наверняка performance тесты есть.
А вообще хороший подход — проанализировать какие ошибки вписываются на вашу игру, посмотреть из-за чего они происходят, попытаться обобщить и придумать тест, который покрывал бы такой класс ошибок.
Здесь большое поле для творчества.
Поэтому по моему опыту в играх очень хреново приживается кондовое ООП — любые сложные иерархии, реализующие изоляцию компонентов друг от друга в какой-то момент делают модификацию кода игры под новые требования невозможной, и приходится переписывать всю архитектуру, либо пробрасывать нужные данные через изолированные слои костылями.
Плюс, в играх мало объектов со сложной собственной логикой, и много сложной логики, требующей доступа к нескольким объектам разных типов, которую трудно поместить в один из них, и приходится выносить в некий третий объект. По моему опыту, большая часть багов в играх того типа, когда все функции по отдельности работают вроде бы правильно, а вот когда их случайно вызывают в непредвиденной последовательности — всё идёт в ад.
Честно говоря сложно представить чтобы невозможно было разбить. Методов то в этом классе хотя бы много? Если да, то методы группируются каким-либо образом и выделяются в отдельные классы. Можно например нарисовать граф связности методов и постараться выделить кластеры сильной связности. Если не ложится на человеческую логику — постараться где-то связность поменять чтобы начало ложиться. Если у вас есть опенсурсный пример кстати было бы очень интересно глянуть, я думаю здесь найдется больше одного человека которые могли бы подсказать варианты.
Общие идеи кода описаны тут: github.com/MaxSavenkov/drdestructo2/blob/master/docs/ReadMe_Source.txt, но в целом идея была в том, чтобы разбить код на Компоненты, которые почти ничего не делают, а только пассивно содержат данные, и Процессоры, которые обрабатывают Компоненты каждого типа в один проход (например, всю физику, потом всю графику, потом весь звук). А весь код, которые требует взаимодействия _между_ разными компонентами (в т.ч. копирование данных из компонента в компонент, т.к. они дублируют данные — иначе бы Процессорам пришлось принимать на вход более чем один тип компонентов), находится в GameStateLevel :)
GameStateLevel::ControlsToPhysics
GameStateLevel::PhysicsToGraphics
GameStateLevel::FireWeapon
GameStateLevel::ProcessSingleCollision
GameStateLevel::Update
Там очень много условий и ветвлений — навряд ли такое качественно тестируется вручную. Кроме этого: «It grown organically, so be prepared.» — будет расти, будет меняться, будут появляться регрессии. ;) Ну и в третьих, если эти алгоритмы рефакторить, то лучше это делать на тестах.
Ну а так вообще конечно нужен отзыв эксперта в написании игр. Как такой код отрефакторить к какой-то стандартной игровой архитектуре.
Я не эксперт в С++, последний раз на них писал лет 5-6 назад, так что прошу принимать мое мнение с изрядной долей скептицизма, я могу пропустить какие-то нюансы.
А так, сходу мне кажется что никаких проблем не составит вынести в отдельный класс методы вроде
GameStateLevel::ExitGame
GameStateLevel::PauseGame
метод
GameStateLevel::Update
просто просится в кандидаты на разбиение на более мелкие и тоже в отдельный класс (скорее всего не в одиночестве конечно). Легко должно быть вынести что-то вроде
GameStateLevel::TutorialTimerUpdate
GameStateLevel::LevelTimerUpdate
GameStateLevel::ReapplyKeyboardSettings
и так далее. Практически все условные ветвления в этом методе на мой взгляд можно вынести в отдельные методы, а может даже и в отдельный класс частично. Например работсу с таймерами
Высокоуровневое етстировать, как уже написали через интеграционные или системные тесты (что по моему мнению практически одно и то же, просто на разных уровнях). А юниты как и везде — любое высокоуровневое состоит из небольших, относительно, частей.
Игровая механика так точно должна биться на отдельные небольшие методы каждый из которых можно тестировать юнит тестами.
С рендером сложнее, но там обычно, насколько я знаю, могу ошибаться, есть движок в котором много математики внутри. Если движок ваш, то вся математика великолепно тестируется кусками, сложность только в нахождении данных тестирование на которых даст осмысленный результат, не всегда очевидно правильный ли вывод в отдельном конкретном куске математического алгоритма. Если движок сторонний, то остается только интеграционное тестирование, тестировать внутренности того что не в вашей ответственности конечно можно, но не очень осмысленно обычно.
Ну а UI это проблема, да. В общем случае тестирование UI практически не автоматизируется. Какие-то куски можно, где-то можно в полуавтоматическом режиме, например записав сценарии и прокручивая их перед глазами, а что-то — только руками.
Отсутствие автоматического тестирования свидетельство, что программистам ведущим по крайней мере НЕ ИНТЕРЕСНО ПРОГРАММИРОВАНИЕ. Они привыкли делать свою работу определенным образом. Книги и статьи о программировании перестали читать много лет назад. И они ни чего не хочет менять, они искренне уверены, что тесты просто пустая трата времени. Продумывайте интерфейс, не совершайте ошибок и все будет ок.
Нормальному программисту как минимум должно быть интересно, что за тесты такие и действительно ли они помогают. А начальник программистов просто ОБЯЗАН изучать практики помогающие улучшить работу своих подчиненных и соответственно внедрять их.
Рядовые же программисты просто серая масса которой однозначно пофигу все. Пока деньги платят.
Нужно выстраивать систему мотивации, финансовой, карьерной, чтобы люди внедряли тесты. Например, не повышать до middle software engineer, пока программист не докажет на практике, что внедряет автоматические тесты.
Когда он докажет то доказывать придется работодателю, что он достоин этого работника.
Если сотрудник приносит больше ценности компании, то и получать он будет пропорционально.
Я вот тесты рассматриваю прежде всего как документацию, на соответствие которой систему можно автоматически проверить. Но объективно число выявленных на этапах прогона тестов ошибок минимально (красные тесты при TDD и ко — не ошибки по факту). Главное, что они мне дают — повышают субъективную уверенность, что всё работает как я ожидаю, прежде всего что мой новый код не сломал старую логику. Но у многих коллег эта уверенность есть и без тестов. При этом им вполне нравится программировать.
2) Я люблю писать тесты. Но есть ситуации когда я то же не пишу тесты потому что понимаю что овчинка не стоит выделки.Понимаю на основании опыта написания тестов.
И наоборот есть ситуации когда ОТЛАДКА через тесты экономит время.
Ну а когда с помощью теста кусочек кода отлажен, я просто пишу асерт начинаю отлаживать следующий кусочек кода в другом тесте.
Таким образом я экономлю время а тесты остаются как полезный артефакт от разработки.
1) Разработчики изначально учились что замедляет процесс.
2) Разработчики пробовали писать тесты на то что не стоит тестировать. Простой код, или GUI (овчинка выделки не стоит).
3) Результат может появится когда кому ни будь приведется переписать функционал А это далеко не 2 месяца.
У меня тесты 5- 6 летней давности работают себе без проблем а стоит полезть в этот код, что то ломается ( не было бы тестов и не узнал бы что внес ошибку) и ее словили бы в продакшене возможно с воем и с претензиями денежными.
Как вариант предложить эксперимент
Сделать серьезные изменения в сложном коде коде
1) который был покрыт тестами.
2) который не был.
Делать должен тот кто этот код не писал.(или писал очень давно).
Вероятность внести ошибку во втором случае заставит разбираться как все работает досконально ( или положиться на авось).
В первом же случае проще разобраться в том что написано и есть ГАРАНТИЯ что я ни чего не сломал.
Я на вашей стороне, но на всякий случай добавлю: гарантия не 100% и важно чтобы разработчик это понимал. Не понимание этого нюанса в перспективе может привести к серъезным ошибкам и разочарованию в тестах.
все возможные сценарии
Исчерпывающее тестирование невозможно кроме тривиальных случаев.
Например для начала писать тесты только для того, что легко тестировать.
Есть ли какие-то области кода, которые приност наибольшее количество багов или типы багов, которые чаще возникают? Тогда их можно покрыть небольшим количеством тестов. Пусть это будут интеграционные тесты, но если их запускать все время, они найдут ошибки такого типа раньше.
а польза от них минимальна
Что значит «минимальная польза»? Т. е. они не обнаруживают никаких ошибок или регрессий?
Как-то оценивалось функциональное покрытие тестов?
Требование было 100% построчного покрытия для нового кода.
Если да, то тесты внедрены некорректно. Корректное внедрение повышает эффективность обнаружения ошибок.
Корректно или нет, не мне судить, но именно эффективность тестов была низкой и поэтому эксперимент с ними закрыли.
Подробнее я рассказываю в этом видео: youtu.be/t376yJuLncE
Она может быть есть если ты работаешь один, а вот по мере увеличения количества работающих увеличиваются шансы что тебя кто ни будь «сломает».
Не говоря уш о том, что если придется дорабатывать свой же функционал пару лет спустя тесты помогут.
И главное тесты это инструмент и пользоваться им должен уметь каждый программист.
Как каждый столяр должен пользоваться лобзиком, топором, бензопилой и прочим. Каждому инструменту свое место.
Уверенность в правильности кода без проверки — прямой путь к ошибкам в этом самом коде. Причем это в различной степени характерно далеко не только для программистов, а вообще для всех людей. Мне нравится пример про электриков: погибают в основном два типа рабочих — те кто еще ничего не знает и зачем-то полез и те кто уже много лет работают и считают что они такие крутые что могут и так. Вот тут то же самое — офигенно опытный программист с кучей лет за плечами в предметной области легко наделает кучу багов просто потому что считает что уж он-то таких ошибок никогда не совершит.
Это не значит что проверять нужно обязательно авто тестами конечно, можно и руками или в полуавтоматическом режиме каком. Просто юнит тесты обычно самый простой и быстрый способ если учитывать поддержку написанного кода в будущем.
Ну и я не видел, вживую, а не в интернете, опытного программиста, который бы попробовал писать тесты, разобрался как что и зачем и решил что они в принципе не нужны. В конкретном случае — да, постоянно. Вообще — ни разу не встречал.
В вашем случае для меня очевидно непонимание инструмента. Не конкретно вами, а теми кто так говорит (что не исключает возможности того что вы в их числе). Аджайл, не аджайл, бардак не бардак но для каждого метода разработчик его написавший в момент когда он его написал должен весьма четко представлять собственно цель его создания и границы его применимости хотя бы. А значит тесты уже можно и нужно использовать.
С другой стороны независимо от процесса разработки у написанном коде скорее всего будут условные ветвления, какая-то модификация данных и другие не всегда очевидные вещи. И если разработчик горячится и говорит что да он, да никогда, да в таком простом месте ошибку совершить, то для меня как тестировщика это сигнал к тому чтобы тщательнее изучить результат деятельности такого разработчика. Ни разу это правило меня не подводило.
Я даже больше про всякий аджайл и бардак скажу — там именно из-за количества и скорости изменений без автоматизации никуда. Это, естественно, не панацея и применимость все равно ограничена, да и руками все еще проверить возможно, но ускорение которое можно получить убрав рутинные проверки стоит того практически в 100% случаев по моему опыту. Да и затраты на тесты с опытом уменьшаются очень сильно.
Ну и последнее: регулярно вижу на митингах по оценке тасков пойдущих в спринт как разработчики говорят что-то вроде: "Здесь на 2-12-бесконечность часов больше нужно, потому что нужно модифицировать кусок который делал человек который уже уволился, как он это сделал никто не знает, тестов чтобы хотя бы примерно убедится что ничего лишнего не поменялось нет. А значит придется тратить время на изучение не только куска который нужно поменять, но и массы других вещей." В результате разработчик недоволен потому что копается в ужасном по его мнению легаси, менеджер недоволен потому что нормальных точных сроков на такой таск никто не даст, клиент не доволен потому что типовой таск, который уже выполнялся в другой части системы за Х часов здесь требует Х + У часов которые нужно оплачивать, да еще и без гарантий что разработчики уложатся.
Можно, конечно, даже до написания метода тесты написать. Но не всегда это просто с одной стороны, с другой, если по опыту знаешь, что после демо требования изменятся с вероятностью 90% и половину тестов выкинуть надо будет, то желания писать их как жест доброй воли, пропадает. Особенно на фиксед прайс.
Я вот тесты рассматриваю прежде всего как документацию, на соответствие которой систему можно автоматически проверить. Но объективно число выявленных на этапах прогона тестов ошибок минимально (красные тесты при TDD и ко — не ошибки по факту).
Что значит не ошибки — а что?
Видимо несоответствие документации и реальной работы продукта. Впрочем если такое несоответствие трактуется не в пользу тестов, то тесты были написаны неудачно, либо не хватает опыта, либо требования поменялись в процессе. Во втором случае впрочем стоило бы сначала тесты и поправить.
Это не значит, что все красные тесты не ошибки. Есть красные тесты которые ошибки.
Но вообще имеет смысл мерять количество багов, которые ушло в прод. Если тесты пропускают в прод не меньше ошибок чем люди тестеры и люди тестеры меньше стоят, то люди выигрывают.
Единственное, тут вопрос в качестве тестов и в легкости их разработки — это может серьезно повлиять на результат.
Сопротивления автоматизации тестирования