Мы несколько раз пытались внедрить автоматизированное тестирование для разработчиков в моей компании. Наша команда QA использует Selenium для автоматизации тестов пользовательского интерфейса, но я всегда хотел представить юнит-тесты и интеграционные тесты. В прошлом, каждый раз, когда мы пытались это сделать, все были взволнованы в течение первого или двух месяцев. Затем, через несколько месяцев, люди просто перестают это делать.
Несколько замечаний и вопросов:
Автоматическое тестирование действительно работает? Большинство моих коллег, которые раньше работали в других компаниях, пытались и не смогли реализовать стратегию автоматизированного тестирования. Я до сих пор не видел реальной компании по разработке программного обеспечения, которая на самом деле использует ее, а не просто говорит об этом. Поэтому многие разработчики видят в автоматизированном тестировании нечто отличное в теории, но не работающее в реальности. Наша бизнес-команда хотела бы, чтобы разработчики делали это даже за 30% дополнительного времени (по крайней мере, так говорят). Но разработчики скептики.
Никто действительно не знает, как правильно проводить автоматизированное тестирование. Да, мы все читали примеры модульного тестирования в Интернете, но их использование для большого проекта - это совсем другое. Основным виновником является насмешка над базой данных или что-то еще, что не является тривиальным. Вы тратите больше времени на насмешки, чем на написание реальных тестов. Затем, когда для написания тестов требуется больше времени, чем для кода, вы отказываетесь.
Есть ли хорошие примеры модульных тестов / тестов системной интеграции, используемых в сложных ориентированных на данные веб-приложениях? Какие-нибудь проекты с открытым исходным кодом? Наше приложение ориентировано на данные, но также имеет много логики предметной области. В какой-то момент я попробовал подход с хранилищем и нашел его довольно хорошим для модульного тестирования, но он пришел ценой возможности легко оптимизировать доступ к данным и добавил еще один уровень сложности.
У нас большой проект, реализованный 20 опытными разработчиками. Казалось бы, это идеальная среда для внедрения модульного тестирования / интеграционного тестирования.
Почему это не работает для нас? Как вы заставили это работать в вашей компании?
Ответы:
Самая сложная часть модульного тестирования - это научить писать тесты сначала / рано. Большинство разработчиков привыкли просто погружаться в код. Это также замедляет процесс разработки на раннем этапе, так как вы пытаетесь выяснить, как написать тест для кода. Однако, по мере того, как вы становитесь лучше в тестировании, это ускоряется. И из-за написания тестов начальное качество кода начинается с более высокого уровня.
Когда вы начинаете, попробуйте просто написать тесты. Не стоит так сильно беспокоиться о насмешках / заглушках. Сделайте тесты простыми. Тесты являются кодом и могут / должны быть реорганизованы. Хотя в этом отношении, если что-то трудно проверить, это может быть и дизайн. TDD действительно использует большинство шаблонов проектирования (по моему опыту, в частности, шаблон Factory).
Убедитесь, что тесты получают уровень видимости. Интегрируйте их в процесс выпуска, во время проверки кода спросите о них. Любые найденные ошибки должны пройти проверку. Эти вещи - то, где TDD сияет.
Вот несколько ресурсов, которые я нашел полезными:
http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
http://www.agitar.com/downloads/TheWayOfTestivus.pdf
Редактировать:
При написании тестов нужно помнить одну вещь. Вы не пытаетесь указать что-либо о реализации кода, только поведение. Когда вы пишете код, вы все время его тестируете. Попытка выполнить его с помощью отладочных операторов и так далее. Написание тестов формализует это и обеспечивает запись тестов, которые у вас есть. Таким образом, вы сможете уверенно проверять свою функциональность, не пропуская случайно тестовый пример, который вы запомнили в середине процесса разработки.
источник
Во многом я согласен с вашей командой.
Большинство модульных тестов сомнительны по стоимости. Поскольку подавляющее большинство тестов кажутся слишком простыми.
Писать хороший тестируемый код гораздо сложнее, чем просто рабочий код. Существует большой процент сообщества разработчиков, которые верят в то, чтобы заставить его работать, в отличие от качества кода / дизайна. И еще больший процент, кто даже не знает, что такое качественный код.
Написание кода модульного теста может занять гораздо больше времени, чем сам код.
Выяснение того, как адекватно протестировать более сложный код (т. Е. Материал, который вы действительно заинтересованы в тщательном тестировании), выходит за рамки возможностей многих разработчиков.
Ведение юнит-тестов занимает слишком много времени. Небольшие изменения могут иметь большой волновой эффект. Основная цель автоматизированных модульных тестов - выяснить, не нарушают ли изменения код. Тем не менее, 99% времени заканчиваются взломом тестов, а не кода.
Со всеми вышеперечисленными проблемами все еще нет лучшего способа внести изменения в код и иметь некоторую степень уверенности в том, что что-то не случилось неожиданно, чем автоматизировать ваши тесты.
Некоторые из вышеперечисленных могут быть в некоторой степени смягчены, если не брать учебник юнит-тестирования.
Многие типы конструкций / приложений лучше тестируются путем автоматизации тестов на уровне модулей / пакетов. По моему опыту, большинство ошибок кодирования происходит не потому, что код в классе был закодирован неправильно, а потому, что кодер не понимал, как их класс должен работать с другими классами. Я видел много удачи в этом типе тестирования. Но опять же, эти тесты сложнее написать, чем модульные (на уровне класса) тесты.
Это действительно сводится к тому, верят ли разработчики в процесс или нет. Если они это сделают, то они напишут хорошие модульные тесты, рано найдут ошибки и будут сторонниками. Если они этого не сделают, то их модульные тесты будут в целом бесполезны и не найдут никаких ошибок, а их теория о том, что модульные тесты бесполезны, будет доказана (по их мнению).
Суть в том, что я никогда не видел, чтобы полностью автоматизированный метод модульного тестирования работал более двух месяцев, но идея автоматизированных модульных тестов все еще сохраняется, хотя мы избирательны в том, что действительно нуждается в тестировании. Такой подход, как правило, имеет гораздо меньше критиков и является более приемлемым для всех разработчиков, чем для немногих.
источник
Frobinate()
(вместо десятков более мелких методов, вызываемых под ним) после проверки системы другими средствами для обслуживания. как тест дыма, что ни одно из изменений более низкого уровня ничего не сломало. Как правило, в этих тестах использовались те же данные, которые составляли часть фунта в пользовательских тестах клавиатуры, чтобы клиент мог видеть, что система делает то, что хочет. Впоследствии инструменты покрытия кода могут идентифицировать, где крайние случаи еще не покрываются.И есть твоя проблема.
Каждый делает хорошие замечания о том, как интегрировать модульное тестирование в вашу среду. Как заставить людей сделать это достаточно, чтобы они увидели практическую ценность и она «прилипла». Но если это супер больно делать и / или не дает никакой пользы, оно не прилипнет.
Уничтожение базы данных должно быть очень простым. Вместо того, чтобы ваш интерфейс обращался к какой-либо базе данных БД, чтобы предоставить ее результаты, вы помещаете простой жестко закодированный объект. Если вы не можете этого сделать, то у вашего дизайна / архитектуры есть проблемы. Ваш код предполагает, что он собирается в базу данных, или у вас нет абстракции интерфейса для его изменения.
Это не просто проблема тестирования / качества. Как только вы захотите сменить поставщика БД, или перейти в облако, или поддержать несвязанные мобильные приложения, ваш дизайн просто провалится. Если вы не можете поддержать простейшие случаи гибкости, вы, безусловно, не сможете поддержать более сложные вещи, которые неизбежно потребуются вашему бизнесу.
источник
Вы должны начать с чего-то небольшого, простого в автоматизации и высокой стоимости. Опустите сладкие, низко висящие фрукты, и вы сможете продать процесс. Покажите, как это спасло кого-то поздним вечером или звонком на выходные. Тогда вы можете расширяться оттуда.
Чтобы хорошо выполнять автоматизированное тестирование, вам нужен кто-то, кто является ресурсом и евангелистом, и кто примет участие в управлении высшего уровня.
Относитесь к разработке автоматизированных тестов, как к любому другому гибкому проекту. Производить завершенные тесты на регулярной основе.
Добавление из комментария: Это больше проблема управления. Считается ли код «выполненным» до его документирования? Прежде чем это проверено? Прежде чем он включает и проходит модульные тесты?
Как вы к этому подходите, зависит от вашей роли. Вы сверстник? Если это так, покажите другим, как он облегчает повторное использование и поддержку вашего кода. Вы ведущий? Выберите своего программиста, у которого больше всего проблем с кодом, и помогите им добавить тесты, чтобы избежать этих проблем. Ты начальник? Установите в качестве стандарта, что «код не будет выполнен, пока не пройдут и не пройдут модульные тесты.
источник
Следуйте этим основным правилам. тесты:
должен бегать регулярно! Вы можете запускать тесты при каждой сборке, до / после каждой регистрации или просто каждое утро. Автоматически сработавший является более предпочтительным, чем сработавший вручную. Потому что теоретически вы можете поручить всем членам команды обеспечить выполнение тестов, но если это не автоматизировано, это, вероятно, происходит не достаточно часто! И если вы не запускаете свои тесты достаточно часто, они оба обнаруживают ошибки слишком поздно, поощряя множество неудачных тестов, что приводит к пункту 2:
Вы все еще добьетесь успеха только в том случае, если те тесты, которые сейчас выполняются регулярно, не будут мешать вам . Под которыми мы подразумеваем тесты:
а. не должно слишком долго бегать (субъективно) за ценность, которую они предоставляют! Сделайте свои тесты быстрыми. Не позволяйте людям проверять тесты, которые будут пустой тратой вашего времени, чтобы позволить им работать!
б. не должно быть ненадежным. Избегайте многопоточных тестов, если это вообще возможно. Применяйте инженерные методы к своим тестам так же, как к другому коду: особенно - проверяйте код ваших тестов!
с. не должно быть труднее исправить и поддерживать, чем реальный протестированный код. Ваша скорость кодирования действительно будет плохой, если небольшое изменение в вашей кодовой базе потребует от вас исправления 10 различных тестов.
И, наконец, правило № 3. Тесты должны не только не давать отрицательное значение, как в правиле 2, они должны давать положительное значение. Тесты ...
Один из популярных способов нарушить правило № 3 - это проверить не то, что нужно . Иногда это происходит потому, что тест слишком большой или слишком несфокусированный. Но обычно это происходит не из-за того, что клиент будет заботиться о чем-либо, а из-за несущественных деталей реализации. (Но иногда тестирование деталей реализации также делает эффективный тест - IMO просто требует практики, чтобы решить, какой.)
Вывод: эти основные правила указывают на общее направление дисциплины устойчивого тестирования, которой вы отчаянно жаждете. При тестировании спросите себя, является ли этот тест действительно устойчивым и ремонтопригодным. Помните:
Тестирование на самом деле сложно. Вы должны ожидать, что тесты вашей команды будут в основном плохими, когда вы начнете писать тесты . Не расстраивайтесь. Есть ли выбрасывать старые тесты, когда вы заметите , что они сосут и являются неустойчивыми.
источник
Да, это так - если все сделано правильно. Дело в том, что тестировщики должны настраивать и расширять свои автоматизированные сценарии после того, как инженеры внедрили новые функции.
Получить консультанта (тот, кто знает, как это делается правильно). Или потратьте больше времени. Альтернатива состоит в том, чтобы иметь большую команду по тестированию, которая выполняет такое же тестирование вручную (что подвержено ошибкам).
Я бы не назвал их «опытными разработчиками», если они откажутся проводить юнит-тесты. Есть много замечательных статей о положительных преимуществах тестирования (как модульного, так и интеграционного тестирования), и в конце все сводится к тому, сколько ошибок стоит ваша компания . Например, я работаю в компании, где качество имеет значение, поэтому модульные и интеграционные тесты неизбежны. Вы можете легко найти множество статей, в которых говорится, что только модульные тесты уменьшают количество ошибок на 30%! (На самом деле, он находится в диапазоне 20-90%, в среднем 30%, но это все еще много.)
Чтобы заставить его работать в вашей компании, либо нанять консультанта, либо поручить это задание старшему инженеру (это займет у него некоторое время). А затем заставьте всех придерживаться правил.
источник
По многим причинам внедрение автоматизированного тестирования может не сработать. Я думаю, что это сводится к тому, что программисты, как правило, не меняют свои привычки кодирования и не способны полностью охватить модульное тестирование.
Многие люди, которые хотят начать с автоматизированного тестирования, пытаются представить их для существующей базы кода. Они попытаются написать интеграционные тесты, которые одновременно тестируют множество функциональных возможностей существующего приложения. Такие интеграционные тесты, как известно, слишком сложны и слишком дороги в обслуживании. Совет: ввести автоматизированные тесты для новой кодовой базы.
Модульные тесты - это хорошие тесты для автоматизации. Все вышеперечисленное (интеграционные тесты, тесты компонентов, системные тесты) также может быть протестировано автоматически, но соотношение затрат и выгод быстро снижается при одновременном тестировании большего количества функциональных возможностей. Этот негативный эффект усиливается, если вы строите такие тесты на плохо протестированном модуле функционале. Совет: вводите автоматизированные тесты на уровне модульных тестов и создавайте автоматизированные интеграционные тесты на прочной основе модульных тестов .
От вышеприведенных пунктов большая часть успеха автоматизированного тестирования зависит от того, насколько эффективны юнит-тесты. У вас есть эффективные юнит-тесты, если вы чувствуете себя продуктивно с юнит-тестами. Когда люди начинают с модульного тестирования, они склонны преобразовывать свой существующий код и привычки кодирования в модульные тесты. По иронии судьбы это самый сложный способ научиться юнит-тестированию. Также модульное тестирование требует, чтобы вы изменили способ кодирования (например, применяя принципы SOLID ). Большинство программистов вскоре прекращают написание модульных тестов, потому что они думают, что кривая обучения слишком крута, и считают неудобным заключать модульные тесты в не так проверяемый код. Совет: Изучите модульное тестирование с нуля с новым кодом и учтите тот факт, что вам нужно изменить свои привычки кодирования.
Есть много других факторов, но я обнаружил, что большинству программистов сложно изменить свой код. Код, написанный без теста, выглядит иначе. Если вы не можете втиснуть свой код в тестируемый дизайн, вы, скорее всего, не сможете написать эффективные модульные тесты. Это разрушает почву для эффективного автоматизированного тестирования.
Я испытал это сам, и теперь я счастлив работать в компании, которая успешно внедрила автоматизированные тесты. Я мог бы написать намного больше о других факторах, но я думаю, что привычки кодирования и модульного тестирования являются наиболее важными. К счастью, есть другие, которые имеют больше опыта, чем я, и наполняют книги своим ноу-хау. Одна из этих книг - разработка приложений Brownfield в .NET, которую я действительно могу порекомендовать, поскольку вы используете стек технологий Microsoft.
источник
Introduce automated tests on the unit test level and build automated integration tests on a solid foundation of unit tests.
+1Одна вещь, которую я не заметил четко в ответах выше, это то, что модульное тестирование - это, по сути, общественный товар и частная цена. Я написал пост в блоге об этом здесь .
То, что сводится к тому, что набор тестов приносит пользу команде или отдельному разработчику, написание теста в большинстве случаев обходится тем, кто его проводит.
Короче говоря, если написание теста каким-то образом не выполняется - и ответы выше перечисляют несколько различных способов сделать это - у отдельного разработчика нет причин делать это.
В одной компании, в которой я работал, написание модульных тестов было обязательной частью предоставления возможности. Новый код не принимался, если только модульное тестирование не было частью фиксации или новой функции - были краткие обзоры кода для каждой «задачи», которую давал разработчик. Возможно, стоит внедрить аналогичную политику на вашем рабочем месте.
источник
Интересно, что бизнес более про-тестирующий, чем разработчики! Для меня это звучит так, как будто вашей главной задачей будет преодоление сопротивления разработчиков к изменениям; они должны пересмотреть свое понимание своей работы, чтобы включить модульное тестирование.
Ничто не может помочь вам больше, чем первые успехи модульного тестирования, которые помогут вашим разработчикам преодолеть сопротивление написанию этих тестов. Если вы заставляете их делать что-то новое, убедитесь, что вы сначала настаиваете на чем-то с почти гарантированным вознаграждением.
@SkipHuffman коснулся этого, но я скажу это прямо. Некоторые вещи гораздо больше подходят для автоматического тестирования, чем другие. Для первого прохода я бы НЕ проверял базу данных или пользовательский интерфейс. Ввод из базы данных может быть чрезвычайно сложным для настройки и удаления. Выходные тесты пользовательского интерфейса, как правило, быстро ломаются из-за изменений, которые совершенно не имеют отношения к вашим тестам.
То, что я бы назвал «промежуточным ПО», идеально подходит для модульного тестирования. Код с четко определенными условиями ввода и вывода. Если вы следуете принципу СУХОЙ (не повторяйте себя), вы напишете несколько небольших классов или функций для решения повторяющихся проблем, уникальных для вашего приложения.
Модульное тестирование является отличным инструментом для ограничения риска изменения существующих внутренних компонентов. Напишите модульные тесты, прежде чем менять внутренний компонент, который работал долгое время. Эти тесты доказывают, что работающая в данный момент функциональность сохраняется. Когда вы внесли изменения и все модульные тесты прошли, вы знаете, что ничего не сломали «вниз по течению». Если вы обнаружили проблему ниже по потоку, добавьте для нее модульный тест!
Рон Хейфитц сказал бы: «Разрешать конфликты в ценностях, которые придерживаются люди, или уменьшать разрыв между ценностями, за которые люди выступают, и реальностью, с которой они сталкиваются. Адаптивная работа требует изменения ценностей, убеждений или поведения». После того, как вы преодолеете сопротивление человека изменениям, вы можете перейти к более сложным областям тестирования по мере необходимости.
источник
Одна вещь об автоматизированном тестировании состоит в том, что он требует написания кода для тестирования. Само по себе это не плохо (на самом деле это хорошо, потому что это мешает многим практикам, которых, как правило, следует избегать), но если вы пытаетесь применить модульное тестирование к существующему коду, скорее всего, это не так. был написан в тестируемом виде.
Такие вещи, как синглтоны, статические методы, реестры, локаторы сервисов и т. Д., Вводят зависимости, которые очень трудно смоделировать. Нарушения закона Деметры означают, что слишком много частей вашей кодовой базы слишком много знают о том, как функционируют другие части вашей кодовой базы, создавая дополнительные скрытые зависимости, которые может быть трудно сломать. Все это затрудняет изоляцию модуля от остальной части кода, и если вы не можете тестировать свои модули изолированно, то модульные тесты теряют большую часть своей ценности. Если тест не пройден, это из-за ошибки в тестируемом модуле, или из-за ошибки в одной из его зависимостей, или, возможно, это из-за того, что данные, которые извлекаются через зависимый источник данных, не соответствуют ожиданиям автора теста ? Если вы можете'
Большинство кодовых баз, которые я видел, которые не были созданы с учетом модульного тестирования, по своей сути непроверяемы, так как кодеры, как правило, сосредотачиваются на том, чтобы заставить код работать так, как они ожидают, вместо того, чтобы выполнять работу, необходимую для сохранения свободной связи и явных зависимостей , Код, который был написан с учетом модульного тестирования, имеет тенденцию выглядеть совсем иначе.
Многие люди применяют наивный подход к модульному тестированию, когда начинают его впервые, они думают, что могут просто написать множество тестов для существующей кодовой базы, и все будет хорошо, но это никогда не сработает, потому что вышеупомянутые проблемы. Они начинают обнаруживать, что им нужно чрезмерное количество настроек в модульных тестах, чтобы заставить их работать вообще, и результаты часто сомнительны, потому что отсутствие изоляции в коде означает, что вы не можете отследить, что вызвало сбой теста. Они также имеют тенденцию начинать писать «умные» тесты, которые демонстрируют какой-то очень абстрактный аспект того, как должна работать система. Это может привести к сбою, потому что «умный» модульный тест сам по себе является потенциальным источником ошибок. Тест не прошел из-за ошибки в тестируемом модуле, или из-за ошибки в тесте? Тест должен быть настолько мучительным и простым, что, очевидно, нет возможности скрыть в нем ошибку. На самом деле, лучшие тесты редко бывают длиннее двух строк: первая строка инструктирует тестируемое устройство что-то делать, вторая утверждает, что то, что он сделал, было тем, что ожидалось.
Если ваша команда серьезно относится к внедрению модульного тестирования, было бы неразумно начинать с существующего проекта. Существующие проекты вашей команды, вероятно, невозможно протестировать без серьезного рефакторинга. Вам лучше использовать новый проект в качестве основы для изучения модульного тестирования, поскольку у вас есть чистый лист для работы. Вы можете спроектировать новую кодовую базу для поддержки внедрения зависимостей над синглетами, реестрами и другими такими скрытыми зависимостями, вы можете написать ее так, чтобы она зависела от интерфейсов, а не от реализаций и так далее. Вы также можете (и должны) писать тесты рядом с тестируемым кодом, поскольку последующее написание тестов приводит к модульным тестам, которые проверяют, что тестируемый модуль выполняет то, что, как вы думаете, он должен делать, а не тесты, которые он выполняет. что спецификации говорят, что это должно сделать.
Как только вы приобретете некоторую уверенность в модульном тестировании, ваша команда, вероятно, начнет осознавать недостатки в существующем коде, которые будут препятствием для модульных тестов. Это когда вы можете начать работу по рефакторингу существующего кода, чтобы сделать его более тестируемым. Не будьте амбициозными и не пытайтесь делать это все сразу, или пытайтесь заменить систему, которая работает на совершенно новую, просто начните с поиска битов кодовой базы, которые можно легко протестировать (те, которые не имеют любые зависимости или где зависимости очевидны) и написать тесты для них. Я знаю, что сказал, что написание теста вместе с кодом предпочтительнее, чем написание тестов после, но даже тест, написанный позже, все еще имеет значение в качестве отправной точки. Напишите тесты так, как будто вы ничего не знаете о том, как работает класс, кроме того, что в его спецификациях сказано, что он должен делать. Когда вы запускаете тесты и получаете ошибки, то либо спецификации, либо реализация ошибочны. Дважды проверьте оба, чтобы определить, что не так, и обновите либо тест, либо код соответственно.
После того, как вы сняли низко висящие фрукты, начинается ваша настоящая работа. Вы должны начать находить скрытые зависимости в вашей кодовой базе и исправлять их, по одной за раз. Не становитесь слишком амбициозными на этом этапе, просто придерживайтесь одного модуля за раз или даже только одной проблемы в одном модуле, пока препятствия для тестирования не будут устранены, и вы не сможете перейти к следующему этапу.
TL: DR: Большинство людей думают, что тестирование легко, и вы можете легко переоборудовать тесты в существующий код. Оба эти предположения неверны. Если вы приступаете к проекту, чтобы провести модульное тестирование в своих проектах с учетом обоих этих фактов, у вас больше шансов на успех.
источник
Если нет, то инициативы по автоматическому тестированию, скорее всего, не будут выполнены Автоматизированное тестирование - это навык, как и многие другие навыки программирования, и если у вас нет никого с опытом в этом деле, нелегко определить, является ли автоматизированный тест хорошим автоматическим тестом с реальной ценностью или плохим, который будет случайно проваливаются / требуют частых обновлений / фактически не выполняют никакого интересного кода.
Если никто не слушает, это не имеет значения, если они говорят, что тест не годится. (Обратите внимание, что власть лидера не должна быть формализована. Наличие команды, которая заботится, тоже хорошо.)
Разработчики ленивы. Вам нужно сделать вещи, которые вы хотите, чтобы их было легко выполнить, и вещи, которые вы не хотите, чтобы они делали, было более трудным для выполнения. Вы должны убедиться, что библиотеки тестирования позволяют легко выполнять задачи, связанные с установкой и разбором теста, особенно настройки, связанные с окружающей средой, такие как тестовые базы данных или тому подобное. (В некоторых из этих комментариев обсуждается макетирование базы данных, но его следует использовать с осторожностью. Реальную базу данных легко раскрутить, и она позволяет тестировать взаимодействие компонентов и жизненные циклы процессов, зачастую более важные и более эффективные, чем модульное тестирование. индивидуальный доступ к данным.)
Вы также должны убедиться, что у ваших IDE есть хороший способ запустить набор тестов. Вам следует часто запускать тестовый набор, чтобы люди замечали, когда он терпел неудачу, а не позволяли ему оставаться в нищете. Разработчики также хорошо реагируют на отзывы, например, автоматизированная система интеграции, которая отменяет свои изменения, если они не прошли тест. Или, что еще лучше, положительные отзывы: автоматизированная система интеграции, которая улавливает ошибки и избавляет вас от поломок.
источник
Во-первых, если ваши разработчики не видят ценность ваших тестов, то, возможно, это потому, что ваши тесты не являются ценными, а не потому, что ваши разработчики не видят их ценность или ценность тестов в целом. Среди его евангелистов существует тенденция полагать, что разработка, управляемая тестами, не может провалиться, ее могут просто провалить ленивые, ленивые разработчики. Я думаю, что это неправильно и контрпродуктивно.
Когда я познакомился с разработкой, управляемой тестами, это означало, по сути, написание теста для проверки того, что метод, который никогда не потерпит неудачу, никогда не потерпит неудачу. Поначалу это приятно, потому что вы получаете прекрасный зеленый чек и чувство выполненного долга. Позже, после того, как вы реорганизовали код, у вас появятся десятки ярых красных X-ов, ни один из которых не говорит ничего, кроме того, что код изменился, что тесты больше не действительны и что вы потратили много времени на их написание.
Вы хотите избежать этого.
С тех пор я использовал другой подход к тестам. Вместо пары реализации интерфейса у меня есть интерфейс, реализация, тестовая тройка . Интерфейс определяет поведение, реализация выполняет поведение, тест проверяет поведение.
Я полагаю, это кажется очевидным, но для меня это различие между кодом, который вы должны доказать, работает, как указано, и кодом, который вы можете тестировать столько, сколько вы считаете нужным. Код, который вы должны доказать, - это интерфейс, который вы предлагаете извне; остальное ваша забота одна.
В этом случае я хотел бы спросить разработчиков, видят ли они естественное разделение в коде, где такой тест был бы уместен. Есть ли интерфейс, который реализует команда A и использует команда B? В этом случае в интересах группы B обеспечить, чтобы интерфейс вел себя так, как он ожидал. Попросите команду B написать тест для нее, затем скажите команде A, чтобы убедиться, что их реализация соответствует тесту; или, если нет, и намеренно не обсуждает неожиданные изменения с другой командой, чтобы они могли подготовиться к ней.
Я думаю, что это иллюстрирует ценность теста. Это не самоцель, несмотря на прекрасные зеленые чеки. Он существует для того, чтобы сделать явное обещание, данное одним разработчиком другому, и обеспечить, чтобы обещание было выполнено для удовлетворения обоих.
источник
Добавление большого количества модульных тестов в большой существующий проект - тяжелая работа. Если вы уже нашли хороший фреймворк, который работает для вас, то вы должны были решить самую сложную проблему.
Я предлагаю попытаться добавить тесты по мере добавления функций / исправления ошибок. Исправление ошибок является самым простым. Написать тест, который не удается из-за вашей ошибки, а затем исправить ошибку. В то же время вы, вероятно, обнаружите, что пишете несколько простых тестов, которые действительно проходят. Конечно, вы действительно хотите использовать небольшой и легко проверяемый фрагмент кода для этого.
Когда люди начнут привыкать к написанию тестов для более простых вещей, надо надеяться, что они пишут свой код, чтобы сделать его более тестируемым.
Я также рекомендовал бы вам измерить охват кода ваших тестов (я использовал cobertura для Java в прошлом). Вы захотите, чтобы какой-нибудь сервер непрерывной интеграции выполнял тесты и регулярно генерировал метрики (каждый день, каждую регистрацию). Если ваши коллеги-разработчики заинтересованы, то они захотят увидеть увеличение покрытия с течением времени, и они могут увидеть зияющие дыры в некоторых из ваших
источник
Я думаю, что вам, возможно, придется играть в длинную игру. Одна вещь, которую вы можете сделать, чтобы получить какое-то признание, - это попытаться провести исчерпывающий модульный тест следующей написанной вами функции, а затем отслеживать количество ошибок с течением времени. Надеемся, что вы обнаружите, что основные ошибки будут обнаружены на ранней стадии (особенно если вы объедините это с тест-ориентированным дизайном), и число регрессий должно быть очень низким. По прошествии некоторого времени, скажем, 1 года, сравните статистику с не скомпонованными объектами с аналогичной сложностью. Если вы можете показать, что число новых ошибок и регрессий заметно ниже, вы предоставили финансовое обоснование, и команде разработчиков будет сложнее игнорировать.
У меня была ситуация, когда я мог использовать TDD и модульное тестирование для основной функции. После окончания этапа разработки не было зарегистрировано ни одной ошибки за 5 лет. Когда было запрошено новое - и рискованное - улучшение, я смог его реализовать и уловить все регрессии в модульных тестах.
источник
Я твердо убежден, что ценность юнит-тестов в значительной степени недооценена многими командами из-за нескольких факторов, многие из которых уже отмечены в ответах.
Зачастую разработчики вынуждены «добиваться успеха», поэтому доказательство того, что блок кода работает, является достаточным доказательством для клиента. Это почти всегда относится к консалтинговой компании и человеческому контролю качества: если клиент не требует модульного тестирования и готовит демо-версию в достаточной степени, то клиент полностью потерпел неудачу, так как собирается подписать утверждение для кода, который может скрывать ошибки.
Часто разработчики разочарованы. Быть программистом - тяжелая работа: завершение задачи и переход к следующему - это удовлетворение, поэтому каждый хочет поторопиться и закончить. Пока их не сбил автобус с серьезной ошибкой, которая возникает спустя месяцы после первоначального контроля качества. В этом сценарии автоматизированное и непрерывное обеспечение качества - это проблема руководства, а не разработчиков (им все равно будут платить за свою работу, возможно, сверхурочно).
Но есть исключение
Я твердо верю, что принятие модели автоматического теста является функцией "человечности" проводимых тестов. Если вы тестируете веб-модуль с внешним интерфейсом, вы, несмотря на такие инструменты, как Selenium, с большей вероятностью сможете заполнить форму самостоятельно, увидеть результат и поверить в детерминизм. Вы забудете перезапускать тесты позже, или вам просто будет лень повторять старые тесты, и именно поэтому ошибки иногда обнаруживаются позже. Чтобы использовать это, сильная модульность кода и строгие правила «модификации старого кода» оказались приемлемыми в банковской среде (по моему личному опыту работы).
Вместо этого, если разработчик отвечает за разработку высокоавтоматизированного модуля с большими объемами данных, он с большей вероятностью напишет подробные модульные тесты и отправит их на тестовые пакеты. Это связано с тем, что заполнение большой полезной нагрузки XML данными, преобразованными из внешнего источника данных (поддельные или нет), не является делом человека. Некоторые разработчики тестов в конечном итоге создадут крошечный и забавный интерфейс для этого конкретного вида тестов. Когда я работал над магистерской диссертацией, я работал на шине протоколирования, которая обрабатывала более 6000 сообщений системного журнала в секунду, и мне приходилось измерять потерю пакетов и их повреждение: естественно, я написал модульные и стресс-тесты почти для всех компонентов, особенно парсера системного журнала.
Чтобы сделать разработчиков более склонными к юнит-тестированию
Я считаю, что они должны быть вынуждены. Если вы умный клиент, вам потребуется, чтобы ваши консультанты выполняли полный набор тестов при каждом контроле качества. Если вы хороший руководитель группы, вы можете подумать о том, чтобы поручить умному разработчику следующую задачу: создать платформу для внутреннего тестирования. Это не имеет ничего общего с антипаттером платформы внутренних эффектов, но вместо этого это набор вспомогательных классов, макетов баз данных, конфигураций, парсеров, конвертеров, швейцарских армейских ножей, которые помогут разработчикам быстро создавать тесты.
Текущие платформы тестирования, такие как NUnit, являются универсальными и позволяют проверять общие утверждения. Правильное использование внедрения зависимостей и конкретных проектов помогает разработчикам писать меньше кода для тестов и быть счастливее. У меня еще не было возможности экспериментировать с полным проектом, я не могу предоставить реальную обратную связь.
источник
Автоматизированное тестирование похоже на разработку программного обеспечения. К сожалению, люди, которых вы нанимаете для тестирования, изначально предназначены для написания тестовых примеров, планов, стратегий, отслеживания процесса проверки, ручного тестирования и регистрации ошибок.
Как только они получают обязанности по автоматическому тестированию, это включает в себя некоторое количество разработки программного обеспечения. Суть в том, что автоматическое тестирование, независимо от того, какие инструменты вы используете (и ради всего святого, не спорьте об этом), требует ежедневного обслуживания и обновления. Как разработчики меняют код,
non-functional
тесты отдельно и не ожидайте, что они будут выполняться ежедневно, требуется время, чтобы сохранить эти обновления, и это хорошо. Но не сдавайтесь, убедитесь, что они поддерживаются.Вы терпите неудачу по этим причинам
if
иwhile
петлей. Потому что, откровенно говоря, ни один курс не учит автоматическому тестированию, а только ручной тест.Это из моего опыта работы в компаниях, которые очень серьезно относятся к автоматизированному тестированию и понимают, что dev важен как инженер автоматизированного тестирования. И из моего опыта работы для людей, которые не знают, понимают разницу, независимо от того, сколько вы им объясняете.
источник