Через мою карьеру в программном обеспечении я столкнулся с широким диапазоном отношений и мнений к тестированию. Два крайности, являющиеся тем, что «тесты не стоит писать, потому что что-то слишком сложно», или что «каждый кусок проверки кода должен сопровождаться тестами». Из этих двух контрастных мнений последних, хотя и не всегда в такой крайней форме, гораздо более распространены. Здесь я буду спорить три случая, почему нам не всегда нужно тестировать код: очевидная корректность изолированных кусочки кода может иметь; Тестовые тесты в избыточном состоянии могут испытать при рефакторинге; и часто неизменность к важному бизнесу кода. Вместо этого я считаю, что мы должны быть тщательно рассмотрены, где необходимо по-настоящему обязанности, прежде чем реализовать.
Очевидное
Если вы когда-либо занимали учебник, просмотрели курс или прочитали книгу по тестированию подразделения, вы, вероятно, видели пример, который тестирует кусок кода по строкам следующего:
func Sum(x int, y int) int { return x + y; }
Без сомнения, вы тогда будете иметь то, как именно вы пройдете тест, который проверяет различные входы, чтобы убедиться, что Сумма
Функция производит правильные результаты для каждого возможного случая, о которых вы можете подумать.
Однако все эти учебники не могут рассмотреть, требуется ли функция теста в первую очередь. Посмотрите на приведенный выше пример, вы думаете, что есть возможность, что она не делает то, что он претендует? Может ли он быть выраженным более простым способом? Трудно ли обернуть голову? Ответ на все три из этих вопросов (надеюсь) нет. Это иллюстрирует, как код может быть интуитивно правильным с первого взгляда без необходимости обширного доказательства или тестирования. Сэр Тони Хоар, чрезвычайно влиятельный компьютерный ученый, неизменно сказал следующее:
«Существует два способа построения программного обеспечения: один состоит в том, чтобы сделать его так просто, что, очевидно, нет ошибок, а другой — это усложнить, что нет очевидных ошибок».
Этот кусок риторики идеально подходит с вопросами, которые мы просили от Сумма
пример. На практике мы можем видеть, что тесты действительно нужны, когда что-то «настолько сложно, что нет очевидных ошибок». Эти тесты затем докажут значение, показывая, что эти неочевидные ошибки не существуют. Таким образом, для простого, «очевидно» правильный код, есть ли какие-либо необходимые тесты? Вместо того, прежде чем добавлять тесты, вы должны задать вопрос: «Является ли этот код, очевидно, правильно, или я могу изменить его, чтобы сделать это, очевидно, правильно?». Если ответ на этот вопрос — да, то нет необходимости проверять, что очевидно.
В сочетании
При принятии решения о том, какой уровень тестов для записи для системы (Unit/Service/ui/Integration/Cont-Tion-end или различные другие имена), «Тестирование пирамиды» Сразу же пружины. Если вы не видели идею раньше, она предполагает, что мы делаем большинство наших тестирующих на индивидуальном уровне «единицы», этот уровень единицы приводит к тестам, быстро работает и может быстро, дешево и эффективно обеспечить высокий уровень Кодовое покрытие. Затем мы должны обеспечить более высокий уровень тестов в гораздо режерам, полагаясь на них, чтобы эффективно доказать, что все проводно и правильно обменивается, а не для проверки отдельных ветвей в логике.
Эта система проста и изначально имеет полное смысл. Это также обычно принимаемая практика. Тем не менее, он не признает, что устранение кода или способность рефакторина может быть основным соображением в каких тестах писать и как их писать. Любая система, проходящая постоянную работу, увидит единицы или изолированные кусочки кода, исчезают, исчезают и принимают совершенно разные формы со временем. Это естественный прогресс и эволюция рабочего, живого программного обеспечения. Чтобы подчеркнуть эту точку зрения, я спрашиваю «Вы когда-либо поощрили раздел кодовой базы, чтобы найти, что существующие модульные тесты сделаны совершенно неактуальными или избыточными?». Если это так, это показывает, что начальные тесты были чрезмерно связаны с макетом и структурой кода. Помните, что тесты — это просто больше кода, который согласуется с первоначальным кодом, который вы только что написали (или если вы выполняете TDD, они просто больше кода, которые согласуются с кодом, который вы собираетесь написать).
В областях кода, которые быстро и постоянно меняются в структуре, тесты на более высоком уровне обеспечивают больший уровень ремонтопригодности и устойчивости, поскольку работа более высокого уровня системы, как правило, более стабильны. Эти тесты значительно меньше могут быть сделаны полностью избыточными.
Это, однако, представляет интересную загадку: как мы узнаем, когда код, вероятно, изменится в структуре или подходе в будущем? Если бы мы могли выявить эти районы заранее, то наша недостенажена может просто означать, что мы пишем их в лучшей форме в первый раз. К сожалению, однако, мы остались боевыми в темноте: попытки организационного кода являются «лучшим подходом усилия», учитывая текущее состояние знаний.
Однако мы делаем повышенное понимание системы, тем больше она существует, или чем дольше мы работаем над этим. Это позволяет проинформированным решения о том, что тестирование полностью уместно. Молодые системы или системы с высокой степенью неопределенности пользуются наибольшим количеством из высокоуровневого стиля «черного ящика», поскольку они наиболее вероятно подвергаются структурным изменениям со временем. Эти тесты намного реже могут рисковать избыточничеством. Соотложительно более старые, более стабильные или более понятные системы пособивают больше от гибкости и эффективного покрытия, которое может обеспечить тестирование единиц.
В целом, возраст, стабильность и неопределенность системы необходимо поддерживать, какие тесты мы пишем: тестирование Pyramid предоставляет упрощенное представление мира, но полезный инструмент для рассмотрения. Тем не менее, нам нужно дополнить это с помощью нашего понимания кода и его эволюции со временем, спрашивая, как долго эти тесты будут иметь отношение к? Или «они могут быть неактуальными в течение х месяцев/лет?».
Неподвижный
На многих крупномасштабных программных проектах я работал, присутствует довольно интересная ирония: самые важные, важные для бизнес-критических частей кода часто являются наиболее недостаточно протестированными. Их выходы отсутствуют четкое определение и, казалось бы, любые небольшие изменения могут писать катастрофу. Тем не менее, они остаются таким образом.
Несколько лет назад я работал на проекте NHS. Это было, чтобы значительно упрощать, невероятно сложную и фундаментальную систему, ответственную за ассоциирующие цены с больничными процедурами и генерированием отчетов на основе этих цен. Система отчета была хорошо проверена, с тысячами тестов, тщательно проверяющих каждый возможный выпуск для массивного разнообразия входов. Несмотря на все это, ядро проекта, ценовая система, была почти полностью отсутствует в тестах. Только было действительно проверено как побочный эффект в тестировании отчетов. Кодекс был невероятно трудно работать и не поддался тестированию, и поэтому никогда не было. В то время я не понял, как можно оставить таким образом, когда это была такая фундаментальная часть системы.
Я позже понял, что обоснование невероятно просто. Оригинальный код был написан как доказательство концепции. Работал, и в результате стал производственный код. Никто не хотел внести какие-либо изменения в страх причинения неизвестной регрессии, который может быть невероятно сложным и дорогостоящим для отслеживания и исправления. Точно так же процесс назначения цены был фиксированной логикой: он не изменился со временем, никаких новых требований не изменился, как оно сработало, и никто не должен был знать, как он работал внутри, — только что это сделал. Стоимость не имея никаких тестов, даже для такого важного куска кода, было масштабно перевешено риском в изменении кода, чтобы сделать его тестируемыми и усилиями в тестировании.
Я выступаю, не тестируя решающие бизнес-системы здесь? Нет — совсем нет! Однако важно признать, что мы не живем в идеальном мире. Системы отсутствующие тесты для важных частей существуют Везде и гораздо более распространены, чем я хотел бы признать. Однако это не катастрофа, которую мне подумала, что это было. Если кусок кода сложен, но он работает и никогда не меняется, то это имеет значение, если оно плохо тестируется? Добавление тестов при внесении изменений, однако, все равно будет осторожно — но мы все равно можем задать вопрос: «Преосуществует ли преимущество тестирования этого кода, перевешивает сложность добавления тестов?». Это опасный вопрос, чтобы спросить, и ответ почти исключительно «да — добавить тесты». Но просто, может быть, иногда, это достойная вещь, чтобы рассмотреть.
Заключить
Подход к созданию хорошо разработанных тестовых люков, обеспечивающих постоянное значение на протяжении всего жизненного цикла проекта, является сложной задачей. Сторонники «тестирования пирамиды» поддержан вопросом. Хотя намерение это хорошо, оно не входит в нерешительность в практичности постоянно меняющегося мира разработки программного обеспечения: эволюция кода со временем может легко представлять тесты избыточных или ненужных, а иногда эти тесты могут даже быть барьером для рефакторинга Отказ «Очевидная« чистый код природы »может обладать, также снижает необходимость теста в качестве доказательства правильного поведения. Аналогичным образом, следует учитывать простые анализу затрат-выгод, когда его известно, что известно, что он является правильным и неизменен, или меняется очень нечасто. Не все тесты стоит написать. Не все должно быть проверено, и это нормально.
Оригинал: «https://dev.to/dglsparsons/on-testing-1jae»