Насколько большим должен быть мой проект, чтобы я смог его протестировать? [закрыто]

86

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

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

Ламин Саннех
источник
26
Большое неверное предположение, которое вы делаете, состоит в том, что проект предназначен только для вас и что пока только . Что если вы оставите это на несколько месяцев, сделаете что-то еще, а затем вернетесь к этому? Будете ли вы иметь такую ​​же уверенность в том, чтобы быть «приличным программистом» (что не имеет никакого отношения к тому, стоит ли тестировать)? Что, если кто-то еще возьмет на себя ваш проект ...? Великий блоггер (к сожалению, уже не активный) писал, что вы всегда должны «заботиться о читателе кода, а не о писателе кода».
Амос М. Карпентер
6
Как насчет этого (предназначено для C # .NET): int x = 3 * (1/3); какое значение хранится в x после завершения операции? Я хочу сказать, что даже однострочный код может потребовать тестирования, потому что это может привести к ошибке, либо потому, что вы не знаете, либо потому, что знаете, но сделали неправильный код.
NoChance
2
@aaamos, я думаю, ты упустил мою мысль. Тот факт, что мне задают только этот вопрос, показывает, что я тоже рассматриваю возможность обслуживания программы для чтения кода.
Ламин Саннех
13
Проделав это в обоих направлениях, я могу сказать вам, что гораздо проще писать тесты по мере продвижения вперед (т. Е. Пока проект мал), чем вернуться назад и написать модульные тесты позже, когда вы почувствуете, что проект встретил какую-то произвольность ». мы должны написать тесты сейчас "условие.
Wonko the Sane
1
Вы задаете не тот вопрос. Неважно, насколько велик проект. Вопрос в том, насколько тебя волнует, если это правильно? Если правильность важна, то модульные тесты являются эффективным способом улучшить правильность.
Марк Э. Хаазе

Ответы:

206

Ваш проект уже достаточно большой.

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

    class Simple {
        boolean reallySimple() {
            return true; // how do we make sure it doesn't change to false?
        }
    }


    class SimpleTest {
        void assertReallySimple() {
            // ensure reallySimple return value isn't changed unexpectedly
            UnitTestFramework.assertTrue(new Simple().reallySimple());
        }
    }
комар
источник
24
Конечно, вы должны начать раньше, с функциональной точки 0 класса / 0 ... если вы следуете TDD :)
Kaz Dragon
115
+1. Если ваша программа достаточно велика, чтобы иметь ошибки, она достаточно велика, чтобы проводить модульные тесты.
Джейсон Орендорфф
9
@JasonOrendorff: я делаю это на постере и размещаю в своем офисе. Brilliant.
Джастин ᚅᚔᚈᚄᚒᚔ
Кроме того, он допускает «безопасный» рефакторинг.
Тимо
7
Хотя я не обязательно не согласен с мнением, но если ваш код действительно такой простой, вы, вероятно, можете обойтись без простых утверждений вместо полномасштабных модульных тестов.
Чуу
109

Я никогда не увлекался идеей «Вы должны все протестировать», хотя, конечно, есть люди, которые имеют (см . Ответ Гнат !).

Насколько мне известно, основными преимуществами модульного тестирования являются:

  1. Помогая гарантировать, что изменения не сломают вещи.
  2. Помогает вам разрабатывать разумные интерфейсы для ваших классов (поскольку это заставляет вас быть клиентом для вашего собственного кода).
  3. Помогите документ, как ваш код будет использоваться.

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

Номер 1 обычно достаточен для написания тестов. По моему опыту,> 95% кода рано или поздно модифицируется.

vaughandroid
источник
8
Согласитесь с этим - работая в одном магазине разработчиков, вы должны соблюдать баланс между качеством программного обеспечения и тестированием всего (что может занять много времени). Не забывайте, что каждый раз, когда вы вносите изменения, вам может понадобиться изменить свои юнит-тесты, чтобы они подходили
Мэтт Вилко,
1
Вы не должны проверять все, но вы должны проверять любое поведение, которое подвергается воздействию внешнего мира. Безусловно, расходы на техническое обслуживание и / или расходы на обслуживание очень высоки, и, как сказал Кент Бек в каком-то SO-ответе (я думаю, что SO), достаточно тестировать, чтобы убедиться, что ваш код правильный.
Уэйн Вернер
10
Я бы добавил, что если вы выполняете только минимальное автоматизированное тестирование, юнит-тесты - не тот уровень, на который вы нацелены Вместо этого отправляйтесь на высокоуровневые интеграционные / дымовые тесты, которые проталкивают несколько наборов данных через ваше приложение до конца, ничего не дразня. Вы хотите, чтобы эти тесты использовали как можно большую часть вашей кодовой базы и охватывали все обычные сценарии использования и пути выполнения. 75% -ный шанс узнать, что ваши изменения что-то сломали где-то в приложении, более выгоден, чем 5% -ный шанс узнать, что вы нарушили SomeClass.OneOfTheHandfulOfTestedFunctions ().
Дэн Нили,
3
Я думаю, вы пропустили одно: «Убедитесь, что код работает так, как и должно!»
BlueRaja - Дэнни Пфлугхофт
3
@ BlueRaja-DannyPflughoeft: На самом деле было бы точнее сказать: «Убедитесь, что код проходит написанные вами модульные тесты!»
vaughandroid
34

Все просто: вам не нужно юнит-тестирование, если вы откажетесь от программы после ее запуска один раз.

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

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

Килиан Фот
источник
22
Программисты, как известно, плохо оценивают свои навыки предсказания будущего
superM
3
@superM Я согласен с тобой. Программа «Беги один раз и выбрасывай», которую я уже написал во время своей короткой карьеры, осталась, проводилась каждые несколько дней и становилась критической для бизнеса. Я называю это временным постоянным эффектом .... вздох
Джалайн
@Jalayn Разве это не просто ответ, что нужно вернуться и добавить модульные тесты, как только это произойдет?
Корнел Массон
@CornelMasson Вы абсолютно правы, ожидайте, что часто бывает сложно убедить менеджеров, что «это еще не закончено», потому что тесты отсутствуют :-)
Jalayn
@Jalayn: слишком верно!
Кизил Массон
22

Некоторое время назад я нашел хороший пост: почему юнит-тестирование ускоряет разработку . Это может помочь вам ответить на вопрос.

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

У меня есть вера".

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

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

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

Майкл Фезерс представил в одной из своих книг два способа работы с изменениями в коде:

  • редактировать и молиться,
  • накрыть и изменить.

Неважно, насколько велика база кода.

Марчин Санецки
источник
18

Согласно Кенту Беку в ответе на вопрос о переполнении стека Насколько глубоки ваши юнит-тесты? , вы должны проверить код, который вы склонны ошибаться.

Если я обычно не совершаю какую-то ошибку (например, устанавливаю неправильные переменные в конструкторе), я не проверяю это.

Mansuro
источник
4
Хороший вопрос, и это означает, что вопрос ОП неправильный; тестировать не имеет ничего общего с размером проекта. 5-строчная кодовая база может нуждаться в тестах, а 1-строчный метод в большой кодовой базе может не понадобиться (хотя другие вещи в этой кодовой базе делают).
Натан Лонг
Это может работать для крошечных проектов, над которыми вы работаете в одиночку, но для проекта, который делается либо для работы (где вы не контролируете, кто будет работать над ним в будущем), либо для всего, что может быть с открытым исходным кодом, вам нужно чтобы проверить все. И вам нужно начать немедленно, потому что позже будет «слишком сложно засыпать весь код, который уже написан»
xaxxon
@xaxxon: Кент на самом деле говорит об этом в том же ответе, на который ссылается Мансуро, говоря: «Когда я пишу код для команды, я изменяю свою стратегию, чтобы тщательно тестировать код, который мы, как правило, ошибаемся».
henko
Нет, это все еще невероятно близоруко. Вы не можете знать, кто будет работать над кодом в будущем. Это тип мышления, который поражает начинающих разработчиков.
xaxxon
5

Проведены юнит-тесты для экономии времени и улучшения:

  • отслеживание ошибок
  • рефакторинг и / или переписывание кода
  • интеграционное тестирование
  • регрессионное тестирование и др.

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

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

superM
источник
Вообще хороший ответ, так что +1. Тем не менее, я думаю, что ваш последний пункт не учитывает тот факт, что вам все еще нужно / нужно вручную тестировать свои модульные тесты!
vaughandroid
@Baqueta, возможно, я не звучал ясно, но я не имел в виду, что юнит-тесты полностью заменяют ручное тестирование
superM
4

На вопрос «Должен ли я выполнить это модульное тестирование» обычно можно ответить, ответив на следующий вопрос: «Важно ли, чтобы эта функция работала правильно, и важно ли для меня знать, когда она перестанет работать?»

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

Брайан Оукли
источник
4

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

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

Если стоимость написания модульного теста составляет 2 минуты, а стоимость выполнения модульного теста - практически 0, а стоимость ручного тестирования кода - 1 минута, то вы безубыточны, даже если вы дважды выполнили тест.


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

Недавно мне предложили использовать Test Driven Development, и я обнаружил, что это полное откровение. Теперь я твердо убежден, что у меня нет времени не писать юнит-тесты .

По моему опыту, разрабатывая с учетом тестирования, вы получаете более чистые интерфейсы, более сфокусированные классы и модули и, как правило, более твердый , тестируемый код.

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


TL; версия DR :

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

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

Марк Бут
источник
3

Проверьте, как только вы заметите, что произошли регрессии или страх вызвал некоторые изменения и не заметил.

Разожгите этот страх, дайте ему вырасти до адекватного размера: чем раньше вы протестируете, тем лучше.

Обратите внимание: в зависимости от вашей роли в проекте модульные тесты могут быть не единственным видом тестов, который вы хотите написать.

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

Zjr
источник
1
Я понимаю, что вы говорите, но это не модульное тестирование базовой отправной точки для начинающих программистов. А также не могли бы вы подробнее рассказать о том, что вы подразумеваете под «тестированием в целом». Благодарю.
Ламин Саннех
1
Существует как минимум два других типа тестирования - интеграционное тестирование и приемочные тесты. Модульные тесты охватывают определенный юнит (например, эта функция этого класса должна Frab the Fizz). Вы высмеиваете / заглушаете все остальные места, где этот класс взаимодействует, передавая им ложные данные. Когда вы проводите интеграционные тесты, вы объединяете два (или более) класса, чтобы убедиться, что ваши классы идут вместе так, как вы думаете. В конце концов вы создаете достаточно тестов, чтобы провести комплексное тестирование всей системы, иногда называемое «тестами дыма».
Уэйн Вернер
Есть также регрессионное тестирование на суде. Регрессионные тесты, как правило, больше, чем модульные тесты, на их сборку может уйти целый день, что может означать доступ к тестовым данным и специальным тестовым средам. На самом деле модульные тесты - это меньшая, более изящная и более удобная версия (старых) регрессионных тестов.
ZJR
1

Я считаю, что не размер проекта, а тип проекта, который решает, следует ли использовать тестирование или нет.

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

Цитата из «Чистого кода» Роберта Мартина : «Если писать тривиально, тестировать тривиально», поэтому нет повода пропускать тестирование для коротких и тривиальных программ.

Eivind Eidheim Elseth
источник
0

Это действительно не вопрос размера - это то, что вы делаете с ним (и сколько ему лет). Если я буду изучать, как работает технология, и планирую выбросить ее (мы называем это шипом в Scrum), я просто напишу код, не выполняя большого количества тестирования. Если вы планируете развивать его дальше (даже если вы просто дурачитесь), вы должны написать тесты вокруг кода. TDD - это метод проектирования, даже до того, как это будет методика тестирования. Вы хотите иметь четкое представление о том, что вы хотите, чтобы код делал, прежде чем вы будете связаны с деталями выполнения. Я бы тоже НЕрекомендую пытаться писать обширные модульные тесты для большого количества унаследованного кода. Попробуйте определить те части, которые являются сложными (имеют высокую цикломатическую сложность / чувство спагетти к ним) и те части, которые часто выходят из строя (они часто будут одинаковыми). Как и предполагали другие, я бы прочитал книгу Кента Бека о TDD и обязательно прочитал книгу Майкла Фезера. То, что они не покрывают очень много, является политическим аспектом написания модульных тестов вокруг кода. Многие разработчики ненавидят необходимость изменять свой код, чтобы сделать его тестируемым, и многие разработчики вообще не испытывают необходимости тестировать код. Это то, над чем мы должны работать как профессия. Любая другая инженерная дисциплина должна доказать (часто математически), что их работа соответствует спецификации. Мы должны сделать то же самое.

Джон Дал
источник
-1

Связывание проектов в пределах классов или функциональных возможностей, а затем оценка того, подходит ли это для модульного тестирования, может быть неправильным. Есть много преимуществ модульного тестирования приложения, но настоящая красота начинается, когда вам нужно поддерживать приложение или работать в распределенной среде. Так что выбор приходит сюда. Даже небольшое изменение в вашем коде может привести к бедствиям.
Я бы не только предложил «Модульное тестирование», но и рекомендовал бы проверить покрытие вашего кода, убедившись, что максимум вашего кода покрыт модульным тестированием. Порог для покрытия кода должен быть не менее 95%, а цель должна быть около 100% . Вы можете воспользоваться инструментами для отслеживания покрытия кода и создания отчета.
Visual Studio предоставляет данные покрытия -http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
Также вы можете использовать NCover или dotCover.

Niks
источник