company_banner

Как доказать важность тестов каждому участнику проекта

    Представьте, вы за два дня полностью реализовали новую фичу. Код написан, он работает и все классно. Ваш менеджер говорит, что можно сразу в релиз. «А как же тесты?» — воскликнет какой-нибудь дотошный коллега. «А зачем?» — ответите вы в один голос с менеджером. Зачем нам писать тесты? Как объяснять их необходимость другим? Зачем вовлекать тестировщиков, аналитиков и других участников? В этом посте я расскажу, как объяснить пользу тестов любому участнику проекта, а также зачем стоит тесты автоматизировать. И подкрепим все это серьезными исследованиями.



    Нужна ли вам автоматизация? Начнем рассуждение от обратного.

    Почему тесты писать не надо?


    1. Это дорого


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



    2. Это нудно


    Разработка автотестов — это очень нудная работа. Ее можно поручить кому угодно. Я 5 лет учился программировать в универе, и еще два года в аспирантуре. Я хочу проектировать классную архитектуру, применять крутые паттерны и запускать ракеты на Марс. А тесты — это задача не моего уровня.

    3. Это бесполезно


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

    4. Это «не мои проблемы»


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



    Почему весь этот список — неправда?


    Теперь пройдемся по всем пунктам и опровергнем каждый. Заодно приведем еще несколько интересных фактов из исследований известных компаний вроде Microsoft (On the Effectiveness of Unit Test Automation at Microsoft за авторством Laurie Williams, Gunnar Kudrjavets, Nachiappan Nagappan), а также менее известной компании из Южной Америки.

    1. В масштабах проекта это недорого


    Обратимся к «Совершенному коду» Стива Макконнелла. Если оценить, как со временем изменяются трудозатраты, то можно заметить, что постепенно доля тестирования, выполняемого разработчиками, сокращается с 25% до 8-10%. Больше ресурсов начинают красть другие активности.



    Есть другое исследование, где Microsoft изучил примерно 30 внутренних команд разного размера — по 28-35 разработчиков и 14-20 тестировщиков в каждой.



    Это исследование показывает примерно те же цифры. При внедрении практик автоматизированного тестирования время на разработку выросло в среднем на 26%. Но разработка — это не вся проектная активность, есть еще конструирование, интеграция, внедрение и так далее. Поэтому рост на четверть только одного из множества процессов — небольшая потеря для бюджета, особенно в свете падения затрат на ручное тестирование.

    2. Это гораздо веселее, чем проблемы в продакшене


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

    3. Это полезно для всех


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

    4. Это станет вашей проблемой


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

    Тестирование с точки зрения ролей в команде


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

    Клиент


    Что бывает, когда не пишут тесты? Например, ты теряешь спутник, который застрахован на 2,6 млрд рублей.



    28 ноября Роскосмос с помощью ракеты «Союз-2.1б» запустил спутник «Метеор-М» № 2-1. Он не долетел — немного отклонился от курса и упал в океан. Разработчики ПО, которое отвечало за корректировку маршрута, забыли указать актуальные данные. Планировалось, что спутник будет выводиться на орбиту с космодрома «Байконур», а запуск состоялся в нескольких десятках тысяч километров от него —  с космодрома «Восточный». Один маленький тест для проверки входных данных — и 2,6 млрд рублей были бы спасены.

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

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



    Владелец продукта


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

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

    В другом исследовании Microsoft можно подсмотреть еще одну интересную цифру. В рамках команды из 32 разработчиков количество дефектов, которое доходило до пользователя, уменьшилось на 20,9% — после того, как во второй версии продукта команды разработки стали применять автоматизацию тестирования и писать модульные тесты. При этом вторая версия обзавелась дополнительными фичами, выросла по объему кода примерно на 20% и еще на 20% была переписана. Да и сами тестировщики стали замечать, что качество их ПО стало выше — стало интереснее работать.

    В IBM тоже проводили подобные исследования и в итоге выяснили, что стоимость устранения бага, обнаруженного после релиза, выше в 4-5 раз чем при обнаружении во время проектирования или реализации. Автотесты, если их регулярно запускать, помогают вовремя сигнализировать о том, что есть какие-то проблемы. Они помогают резать эти дополнительные косты в бюджете. В итоге стоимость поддержки ПО станет ниже — а качество пользовательского опыта при этом вырастет.

    Тестировщик


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

    Вот отчет по ошибкам в рамках одного внутреннего проекта Microsoft:



    Первая версия — до внедрения автоматического тестирования, вторая — после. Ошибки разделены на четыре категории. Чем выше категория, тем сложнее ошибки. Суммарно во второй версии количество багов уменьшилось на 21%. Количество багов из простых категорий (3 и 4) уменьшилось существенно. Доля более сложных багов осталась такой же либо чуть-чуть подросла из-за того, что общее количество багов снизилось.

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

    Почему до тестировщиков стало доходить меньше багов? Есть известная многим пирамида, которая делит различные виды тестирования по слоям. Эта пирамида говорит о том, что самых примитивных модульных тестов, которые затрагивают исключительно маленькую часть ПО, должно быть в проекте больше всего. А сложных end-to-end или ручных тестов должно быть минимальное количество, но при этом они должны искать самые сложные баги — это так называемые мигающие, плавающие или серые тесты. Если эту пирамиду перевернуть, появляется так называемая воронка тестирования, в которую сыплются всевозможные баги.


    Источник: https://twitter.com/noahsussman

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

    Разработчик


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

    • Понимание требований

    При написании теста разработчик начинает лучше понимать требования, благодаря коммуникации с нетехническими специалистами. Допустим, нужно реализовать какое-то поле ввода. Когда вы пишите тесты к своему коду, то начинаете задавать вопросы: а что если я сюда подставлю пустое значение? А что если я введу 150 символов вместо 10 разрешенных? Уточняя эти моменты, вы делаете более стабильным свой код и избавляете его от самых простых ошибок.

    • Стабильность при рефакторинге

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

    • Формирование документации

    Тесты служат отличной документацией к вашему коду. Гораздо легче понять чужой код, когда есть какой-то потребитель этого кода. И самым первым потребителем как раз выступают тесты. Не заходите в Jira, не изучайте объемные комментарии в Confluence — вы можете просто открыть тестовый класс, набор каких-то тестовых методов к вашему коду, и понять, что этот код делает, просто почитав названия тестовых методов и поняв, какие данные там передаются.

    • Улучшение API

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

    • Уменьшение количества ошибок

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



    Подведем итоги


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

    Конечно, с тестами разработка становится дольше — в среднем на 26%. В зависимости от сложности языка программирования, фичей и опыта программиста, эта доля может уменьшиться до 8% или подскочить до 40-50% времени. Если время выхода на рынок для вас максимально критично — отложите написание тестов, выпустите MVP и возвращайтесь к тестам потом.

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

    Надеюсь, все приведенные аргументы помогут вам объяснить внутри команд, а заодно самому себе, зачем нужны тесты, зачем стоит писать их каждый день и как они делают код лучше.
    Сбербанк 191,44
    Компания
    Поделиться публикацией
    Комментарии 31
    • +2
      Надо понимать, что Unit-тесты — один из способов обеспечить качество. Где-то он хорош, где-то — слишком дорог или неэфективен. Те же Microsoft и Oracle — они же делают всякие SQL Server-ы, компиляторы и рантаймы .NET и Java, там требуется высочайшее качество. Там вообще непонятно как это можно вручную проверять.

      Но это не значит, что юнит-тесты везде отобьются. Большинству средней руки приложений, тесты нафиг не надо. Скажем, какой-нибудь UI на реакте, или там какой-нибудь server-side .NET — который из SQL в JSON перекладывает — это всё зачем тестами покрывать? Вот, скажем, хабрахабр тот же — какой смысл по TDD писать?
      • +1

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


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


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

        • +2
          Не поломаю. У меня есть QA, которые все внимательно проверяют перед релизом. Все равно им проверять всё то, что тесты не ловят: аккуратность верстки, адекватность и понятность UX-а, правописание.

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

          Я вот почему-то уверен, что в коде того же Хабрахабра тесты если и есть, то где-то в самых ключевых местах только. И фичи они на нас через A/B тестирование проверяют. И ничего, норм всё едет.
          • +2
            Если постоянно все по кругу полностью переписывается и живет в романтическом духе стартапа, то вы правы, тесты тут ни к чему. Они только будут тормозить развитие. Автоматизированные тесты нужны тогда, когда вы что-то фиксируете на длительный срок. В этом случае ваш QA скажет вам спасибо, ведь, как написано в статье, самые простые ошибки программист с большой вероятностью устранит сам, и тогда на поиск сложных у QA останется больше времени.
            • 0

              У меня есть отличная картинка для вас.


              Ну и в самой статье отлично написано — настоящий QA не дешевле автотестов, как минимум потому, что люди отвратительно масштабируются. А адекватность верстки и правописание отлично проверяется автоматическими тестами.


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


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

          • +1
            Сложность системы и необходимость его тестирования — понятия, связанные друг с другом лишь опосредованно. Писать тесты нужно тогда, когда вам необходимо явно убедиться, что ваше ПО работает и не деградирует с течением времени. Тут неважно, простой ли это транслятор из SQL в JSON, или компилятор. Важно, долго ли вам это ПО поддерживать. Если это простой MVP, который нужно как можно быстрее довести до пользователя и потом переписать, автоматические тесты могут лишь сделать хуже бизнесу. И от них в этом случае лучше отказаться.
            • 0
              Вот, скажем, хабрахабр тот же — какой смысл по TDD писать?

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

            • +1
              Я один из тех кто не понимает зачем нужны unit-тесты. И я Очень хочу что бы кто-нибудь мне все-таки объяснил зачем с ними возиться, если вы пишите бизнес-приложение (На Java в моем случае). Статья увы не открыла для меня каких-то сакральных мыслей, вопрос остается для меня открытым. Я честно пытался внедрить TDD при работе, и вот что вышло: Разрабатывается сквозная фича, на слой за слоем пишутся тесты, потом как обычно это бывает уже под завершение фичи озаряет гениальная идея, код меняется, соотвественно нужно сразу переписать и кучу написанных тестов, ок. Проходит время, меняется бизнес-требование, что делаем? Правильно, меняем кусок кода и пару десятков тестов. И так по-кругу! Я до сих пор не вижу где тут польза, учитывая что на разработку с таким подходом у меня уходило примерно на 40% больше времени, а выловлено багов было всего пару, которое отловили бы тестеры скорее всего. Считаю необходимыми только приемочные авто тесты, а юнит-тесты писать только на критичный core-функционал, вокруг которого строится приложение, а не на все подряд.
              • +2
                О балансе между разными видами автоматизированных тестов говорит пирамида тестирования. Модульные тесты — самые дешевые в разработке: они быстрее остальных пишутся и отдельный тест дешевле и реже меняется по сравнению с другими видами тестирования. Поэтому количественно их должно быть больше всего в общем ряду.

                Писать модульные тесты (как и любые другие) на все подряд (чтобы code coverage был почти 100%) — неверно. Я бы даже назвал это антипаттерном поведения. Вы правильно указали, что зачастую бывает достаточно закрыть модульными тестами только фундамент приложения, автоматизировать приемочные тесты, а все остальное отдать на откуп ручникам. На мой взгляд, это позволяет соблюдать баланс между качеством тестирования и скоростью реакции на изменчивые требования рынка во многих проектах.
                • 0
                  Обычно если у вас появляется такая проблема, то ваш код не был спроектирован как тестируемый. Можно ли решить эту проблему в рамках вашего проекта — это довольно сложный вопрос. Тот же подход Active Record, на мой взгляд, откровенно плохо покрывается юнит-тестами.
                • –1
                  Если вы до сих пор, извините, «дротите» на тесты, но при этом не разрабатываете продукты по мощности уровня компилятора или управления реактором, вам нечего делать в ИТ — вы просто дилетант, прыгающий с хайпа на хайп и убеждающий (прежде всего себя) в нужности этого хайпа. Взрослейте!

                  А те, кто всё ещё не понял принципа применения тестов, должны наконец уяснить:
                  Есть СТОИМОСТЬ теста, его ВРЕМЯ ЖИЗНИ, его ПРИМЕНИМОСТЬ и наконец, стоимость ошибки. Если ничего из этого не учитывалось, ваши тесты НЕ НУЖНЫ.
                  • 0

                    Обычно так оправдываются когда тестов нет

                    • –1
                      Обычно оправдания ожидает вчерашняя студота, возомнившая себя сеньорами, а у меня своё профессиональное мнение. Хочешь — слушай, не хочешь — продолжай проси*рать время.
                  • 0
                    Написание тестов должно поддерживаться со стороны менеджмента.… Менеджмент должен поддерживать написание тестов и понимать, зачем они вообще появляются в проекте.


                    Менеджмента ИТ или бизнеса?
                    • +1
                      И тем, и другим. Менеджменту бизнеса важен time to market, менеджменту IT — предсказуемость поддержки и сроков. Тесты — один из кирпичиков в фундаменте обеспечения этих потребностей.
                      • 0
                        Один маленький тест для проверки входных данных — и 2,6 млрд рублей были бы спасены.


                        А вы думаете, входные данные живут сами по себе? :) Увы, нет. Они пошли в математику и вызвали цепочку неких управляющих воздействий от программы в целом. Проверить такое — та ещё задача.
                        Вот вам будущая программа одного из устройств. Она на Си и должна работать на микроконтроллере (всего контроллеров 5 и они объединены ДОЗУ), но с обвязкой на Си++ (чтобы можно было отладить на PC — запускается в ОС QNX 6.3). Как бы вы написали бы тесты для такой программы? Я вот даже в принципе этого не представляю.
                        • 0
                          Можно было написать тест, что поставщик данных, который отдает их в блок математики, работает правильно. Одного теста на это достаточно. То, что математика работает верно, проверяется другими тестами.

                          В коде, который вы прислали, нет ничего специфичного. Есть интерфейс классов или функции модулей, на них можно написать модульные тесты. Или написать интеграционные тесты на их взаимодействие. Вопрос, как и какими инструментами писать тесты, выходит за рамки этой статьи.
                          • 0
                            Можно было написать тест, что поставщик данных, который отдает их в блок математики, работает правильно.


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

                            Есть интерфейс классов или функции модулей, на них можно написать модульные тесты. Или написать интеграционные тесты на их взаимодействие.


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

                            Вопрос, как и какими инструментами писать тесты, выходит за рамки этой статьи.


                            Этим грешат все статьи про тесты. Либо в примерах тестируют простую функцию, либо общие слова о полезности тестов. Ни разу я не встретил статьи, где бы тестировалось реальное, относительно крупное приложение на Си/Си++ по полочкам. А вот такая статья очень-очень нужна.
                            • +1
                              В том-то и дело, что нельзя. Диапазон всех этих величин — вся сетка координат. На эти данные программа может реагировать совершенно по-разному.

                              Для борьбы с диапазоном значений существует понятие классов эквивалентности тестов. Для обеспечения полноты покрытия можно использовать pairwise testing. С точки зрения программной реализации также будет полезным property-based testing. Для многих языков, в том числе и для C++, существуют готовые инструменты.

                              Это чисто формальный подход

                              Если тестировать по методу «черного» ящика, то неважно, как устроена внутри программа. Есть набор входных данных, есть набор ожидаемых выходных. Этого достаточно. Можно тестировать и по методу «белого» ящика. Оба подхода не отрицают друга друга, а лишь дополняют.

                              Все эти случаи я даже перечислить не могу

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

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

                              За C++ не ручаюсь, но про то, как мы пишем тесты для iOS-приложения (Objective-C + Swift), расскажем в одной из будущих статей.
                              • 0
                                Для борьбы с диапазоном значений


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

                                Есть набор входных данных, есть набор ожидаемых выходных.


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

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


                                Нет, требования к системе как раз есть — она должна обеспечивать живучесть комплекса. Нет множества тестовых последовательностей (их число как в шахматах число ходов — комбинации что после чего отказало) и неизвестен порядок действий программы (он крайне сильно зависит от входных последовательностей и моментов времени, когда они происходят). Как так вышло? Программа ориентируется на здравый смысл, примерно, как человек. Вот эти «здравые смыслы» в неё и заложены. Вопрос только в том, как проверить, что они во всех ситуациях действительно здравые и не забыли ли мы что-то ещё добавить в здравый смысл, что в 0.01% ситуаций поставит программу на неверную алгоритмику исправления ситуации.
                                • +1
                                  Вы описываете систему как полноценный ИИ. Но по факту ведь это не так. У каждой системы есть критерии приемки (даже у Face ID надежность — 1 к 1 000 000, но Apple считает это допустимым для выпуска продукта на рынок). Их можно автоматизировать. Что-то — через модульные тесты, что-то — через интеграционные и т.д.

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

                                    Для старта ракеты координаты нет нужды проверять — их в программе не хранят и передают извне. Программа формально работает с любыми координатами. Но вот нюансы управляющих воздействий могут получаться разными, в зависимости от координат. И не всегда они верные из-за каких-либо особенностей (просто вообще в принципе не учли какой-либо случай — даже в голову не пришло). Это похоже на решение интегралов в матлабе — в ряде случаев численное интегрирование дает существенно неверное значение из-за особенностей интегрируемой функции. И узнать об этом не так просто — чтобы об этом узнать, нужно как минимум такое искать. А в ПО ракеты просто не подумали о выявленной проблеме. И тест тут не поможет — нельзя тестировать то, что даже в голову не пришло.
                                    • 0
                                      Почему не поможет? Вот есть входные параметры: координаты, соответственно мы должны покрыть две ветки поведения (по координатам байконура стартуем), по любым другим не стартуем.
                                      • 0
                                        Потому что вы о неверном поведении программы с другими координатами узнали уже после того, как ракета ушла не туда. Исключение составляет случай, когда программа делалась так, что она не универсальна — то есть, управление ракетой сводилось не к регулятору, а к тупой последовательности действий (взлёт, 10 км вертикально, 10 км под углом 45 градусов и 1000 км под углом 30 градусов). Но очень сильно вряд ли там сделано именно так. Всё-таки, обычно делают систему управления с обратной связью. А такая система должна работать при любых координатах пусковой.
                                        Впрочем, я вас немного разочарую — мой опыт работы с НПО-разработчиком систем управления для военных ракет показывает, что со специалистами в части ПО там всё очень плохо (как вам контроль правильности массивов данных, сделанный как обычная сумма чисел? Для гарантированной доставки переданных данных их просто повторяют 4 раза и всё. Потом запрашивают устройство. Если устройство эти данные всё-таки не приняло (скажем, оно в неудачный момент перезагружалось), пробовать снова поработать с устройством нам не надо — мы бодро рапортуем об отказе комплекса. В одном приборе сделали прямой код для кодирования отрицательных целых чисел. Нахрена?! Переделывать не будут — сложно пересдать представителю заказчика. Протокол обмена придумал сумасшедший — в него всё добавляется по принципу «ой, а так не работает — нужен ещё и номер подмассива. А у нас свободных полей (страница максимум 64 байта — MIL STD) уже нет… А мы его засунем вот сюда. Если тут такое число, то это такой массив, а если другое, то это будет номер подмассива. Что вы говорите? То число тоже номером может быть? Хм… Ну и пусть будет.»).
                                        • 0
                                          Как осуществляется приемка решения?
                                          Кто и как определяет, что решение удовлетворяет требованиям?
                                          (я сейчас не про автотесты)
                                          • 0
                                            Приёмка какого решения? Программного? Очень просто проходит — в инструкцию по контролю вписывают ту ветку, которая основная рабочая плюс пару-тройку веток имитации отказов. Все, конечно, не вписать (как я уже говорил, отказы могут быть в разном порядке), да и одна ветка проходит эдак часов 10-20 — гироскоп требует такого времени на подготовку. Вот и всё. Если всё прошло успешно, изделие сдано.
                                            • 0
                                              Если набор требований, по которым будет приниматься решение, заранее известен и конечен, то их (требований) автоматизация и будет являться тестами.
                                              Нет, разве?
                                              • 0
                                                Тут следует различать набор по которому принимается решение и набор, покрывающий всё множество входных данных. Поэтому прохождение набора для сдачи сможет не являться полным тестированием программы.
                                                С тестированием плохо, когда требуется отладка реакций на отказы аппаратуры (аппаратура может отказывать множеством способов — от простого обрыва провода и залипания реле, до потери с ней связи). Тут мы тестируем только некоторые базовые вещи.
                                                Вообще, было бы интересно узнать, как тестируют систему управления Space Shuttle…
                                                • 0
                                                  Я могу понять, что требования у разных заинтересованных лиц могут быть разные. У гос комиссии — одни, у руководителей разработчиков — другие (требования). Но зачем отделять требования от тестов, понять не могу. Тесты — это формализованные требования. Есть формализованное требование, к нему может быть автотест.

                                                  Не все требования формализуются, и соответственно тесты к ним неприменимы.

                                                  Отдельная история — стоимость автотестов против ручных. Куча кейсов, когда ручные тесты легко переигрывают автотесты.
                                                  • 0
                                                    Потому что при сдаче тестируете вы не отдельное ПО — вы тестируете сложный аппаратно-программный комплекс в целом. ПО тестировать без аппаратуры можно только эмулируя эту аппаратуру (и сделать привязку к этой модели аппаратуры этого ПО), но аппаратура имеет свои особенности и их эмулировать очень-очень непросто (как эмулировать, например, реальный уход гироскопа или глюки конкретного контроллера или помехи в линии, выбивающие CAN нафиг?). Также есть ручные операции («поверните по шкале поворотного стола на 30 градусов», «закройте луч автоколлиматора пластинкой», «отстыкуйте разъём и убедитесь в пропадании информации» и так далее). Сделать на такое автотесты — это проще сразу найти табуретку, верёвку и мыло. В этой сфере нет абстрактного ПО — есть комплекс со своими особенностями и отказами всего, что только возможно. Принципиально разными отказами.

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

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

                        Самое читаемое