Мне платят за работающий код, а не за тесты, поэтому моя философия заключается в том, чтобы тестировать как можно меньше, чтобы достичь заданного уровня уверенности (я подозреваю, что этот уровень уверенности высок по сравнению с отраслевыми стандартами, но это может быть просто высокомерием) . Если я обычно не ошибаюсь (например, устанавливаю неправильные переменные в конструкторе), я не проверяю это. Я склонен разбираться в ошибках тестирования, поэтому я особенно осторожен, когда имею логику со сложными условными выражениями. При кодировании в команде я изменяю свою стратегию, чтобы тщательно протестировать код, который мы все вместе склонны ошибаться.
У разных людей будут разные стратегии тестирования, основанные на этой философии, но это кажется мне разумным, учитывая незрелость понимания того, как тесты могут лучше всего вписаться во внутренний цикл кодирования. Через десять или двадцать лет у нас, вероятно, будет более универсальная теория о том, какие тесты писать, какие не писать и как отличить их. А пока поэкспериментируем.
Напишите модульные тесты для вещей, которые вы ожидаете сломать, и для крайних случаев. После этого следует добавлять тестовые примеры по мере поступления отчетов об ошибках - перед написанием исправления для ошибки. Тогда разработчик может быть уверен, что:
Согласно прилагаемому комментарию - я предполагаю, что такой подход к написанию модульных тестов может вызвать проблемы, если со временем будет обнаружено множество ошибок в данном классе. Вероятно, здесь полезно усмотрение - добавление модульных тестов только для ошибок, которые могут возникнуть повторно или где их повторное появление вызовет серьезные проблемы. Я обнаружил, что в этих сценариях может быть полезна мера интеграционного тестирования в модульных тестах - тестирование кода на более высоких уровнях кода может покрыть пути кода внизу.
источник
Одна из самых непонятых вещей о TDD - это первое слово в ней. Контрольная работа. Вот почему появился BDD. Потому что люди не понимали, что первое D было самым важным, а именно Driven. Мы все склонны немного слишком много думать о тестировании и немного мало о разработке дизайна. И я предполагаю, что это расплывчатый ответ на ваш вопрос, но вам, вероятно, следует подумать о том, как управлять своим кодом, а не о том, что вы на самом деле тестируете; в этом вам может помочь инструмент покрытия. Дизайн - гораздо более серьезная и проблемная проблема.
источник
Тем, кто предлагает тестировать «все»: осознайте, что «полное тестирование» такого метода
int square(int x)
требует около 4 миллиардов тестовых случаев на общих языках и типичных средах.На самом деле, это даже хуже , чем: метод
void setX(int newX)
также обязан не изменять значения любых других членов , кромеx
- вы тестирования , чтоobj.y
,obj.z
и т.д. все остаются неизменными после вызоваobj.setX(42);
?Практично проверять только подмножество «всего». Как только вы примете это, станет более приятным отказаться от тестирования невероятно простого поведения. У каждого программиста есть распределение вероятностей расположения ошибок; разумный подход состоит в том, чтобы сосредоточить свою энергию на тестировании регионов, в которых, по вашему мнению, вероятность ошибки высока.
источник
Классический ответ - «проверьте все, что может сломаться». Я интерпретирую это как означающее, что тестирующие сеттеры и геттеры, которые ничего не делают, кроме set или get, вероятно, слишком много тестирования, не нужно тратить время. Если ваша IDE не напишет их за вас, вы тоже можете это сделать.
Если ваш конструктор, не устанавливающий свойства, может привести к ошибкам позже, тогда проверка того, что они установлены, не будет лишним.
источник
Я пишу тесты, чтобы охватить предположения классов, которые я напишу. Тесты обеспечивают соблюдение требований. По сути, если, например, x никогда не может быть равным 3, я собираюсь убедиться, что существует тест, который удовлетворяет этому требованию.
Неизменно, если я не напишу тест, чтобы охватить какое-либо состояние, оно обнаружится позже во время тестирования «на людях». Я обязательно напишу тогда, но лучше поймаю их пораньше. Я думаю, дело в том, что тестирование утомительно (возможно), но необходимо. Я пишу достаточно тестов, но не более того.
источник
Отчасти проблема с пропуском простых тестов сейчас в будущем, рефакторинг может сделать это простое свойство очень сложным с большим количеством логики. Я думаю, что лучше всего использовать тесты для проверки требований к модулю. Если при прохождении X вы должны вернуть Y, то это то, что вы хотите проверить. Затем, когда вы измените код позже, вы можете убедиться, что X дает вам Y, и вы можете добавить тест для A, который дает вам B, когда это требование будет добавлено позже.
Я обнаружил, что время, которое я трачу на начальную разработку, написание тестов, окупается за счет первого или второго исправления ошибки. Возможность подобрать код, который вы не просматривали в течение 3 месяцев, и быть разумно уверенным, что ваше исправление охватывает все случаи и «вероятно» ничего не сломает, очень ценно. Вы также обнаружите, что модульные тесты помогут отсортировать ошибки далеко за пределами трассировки стека и т. Д. Наблюдение за тем, как отдельные части приложения работают и терпят неудачу, дает глубокое понимание того, почему они работают или терпят неудачу в целом.
источник
В большинстве случаев, я бы сказал, если там есть логика, проверьте ее. Сюда входят конструкторы и свойства, особенно когда в свойстве задано несколько параметров.
Что касается слишком много испытаний, это спорно. Некоторые скажут, что все должно быть проверено на надежность, другие говорят, что для эффективного тестирования нужно проверять только то, что может сломаться (например, логика).
Я бы больше склонялся ко второму лагерю, просто исходя из личного опыта, но если бы кто-то все-таки решил все проверить, я бы не сказал, что это было слишком ... немного излишним, может быть для меня, но не слишком для них.
Итак, нет - я бы сказал, что нет такой вещи, как «слишком много» тестирования в общем смысле, только для отдельных лиц.
источник
Разработка через тестирование означает, что вы прекращаете кодирование, когда все тесты пройдены.
Если у вас нет теста на свойство, зачем вам его реализовывать? Если вы не тестируете / не определяете ожидаемое поведение в случае «незаконного» присвоения, что должно делать свойство?
Поэтому я полностью за тестирование каждого поведения, которое должен демонстрировать класс. В том числе «примитивные» свойства.
Чтобы упростить это тестирование, я создал простой NUnit,
TestFixture
который предоставляет точки расширения для установки / получения значения, принимает списки допустимых и недопустимых значений и имеет один тест, чтобы проверить, правильно ли работает свойство. Тестирование отдельного свойства может выглядеть так:Используя лямбды и атрибуты, это можно было бы даже написать более компактно. Я так понимаю, у MBUnit есть даже некоторая встроенная поддержка для подобных вещей. Дело в том, что приведенный выше код фиксирует назначение свойства.
PS: Вероятно, PropertyTest также должен иметь способ проверки того, что другие свойства объекта не изменились. Хм .. вернемся к чертежной доске.
источник
Я делаю модульный тест, чтобы достичь максимально возможного покрытия. Если я не могу достучаться до какого-то кода, я рефакторирую его до тех пор, пока покрытие не будет максимально полным.
После завершения слепого теста записи я обычно пишу один тестовый пример, воспроизводящий каждую ошибку.
Я привык разделять тестирование кода и интеграционное тестирование. Во время интеграционного тестирования (которое также является модульным тестом, но для групп компонентов, поэтому не совсем то, для чего предназначен модульный тест) я проверю правильность реализации требований.
источник
Таким образом, чем больше я пишу тесты, тем меньше беспокоюсь об уровне детализации тестирования. Оглядываясь назад, мне кажется, что я делаю самое простое из возможных, чтобы достичь своей цели проверки поведения . Это означает, что я создаю уровень уверенности в том, что мой код выполняет то, что я прошу, однако это не считается абсолютной гарантией отсутствия ошибок в моем коде. Я считаю, что правильный баланс - это проверить стандартное поведение и, возможно, один или два крайних случая, а затем перейти к следующей части моего дизайна.
Я согласен с тем, что это не касается всех ошибок, и использую другие традиционные методы тестирования для их выявления.
источник
Как правило, я начинаю с малого, с входов и выходов, которые, как я знаю, должны работать. Затем, по мере исправления ошибок, я добавляю дополнительные тесты, чтобы убедиться, что исправленные мной вещи проверены. Это органично, и мне нравится.
Можете ли вы проверить слишком много? Возможно, но, вероятно, лучше проявить осторожность в целом, хотя это будет зависеть от того, насколько критично ваше приложение.
источник
Я думаю, вы должны протестировать все в своей «основе» бизнес-логики. Getter и Setter тоже, потому что они могут принимать отрицательное или нулевое значение, которое вы, возможно, не захотите принимать. Если у вас есть время (всегда зависит от вашего начальника), хорошо протестировать другую бизнес-логику и весь контроллер, который вызывает этот объект (вы медленно переходите от модульного теста к интеграционному).
источник
Я не тестирую простые методы установки / получения, которые не имеют побочных эффектов. Но я тестирую все остальные общедоступные методы. Я пытаюсь создавать тесты для всех граничных условий в моих алгоритмах и проверять покрытие моих модульных тестов.
Это большая работа, но я думаю, что она того стоит. Я предпочитаю писать код (даже код тестирования), чем выполнять код в отладчике. Я считаю, что цикл код-сборка-развертывание-отладка занимает очень много времени, и чем более исчерпывающими являются модульные тесты, которые я интегрировал в свою сборку, тем меньше времени я трачу на прохождение этого цикла код-сборка-развертывание-отладка.
Вы не сказали, зачем вы тоже пишете архитектуру. Но для Java я использую Maven 2 , JUnit , DbUnit , Cobertura и EasyMock .
источник
Чем больше я читаю об этом, тем больше думаю, что некоторые модульные тесты похожи на некоторые шаблоны: запах недостаточного количества языков.
Когда вам нужно проверить, действительно ли ваш тривиальный получатель возвращает правильное значение, это потому, что вы можете смешивать имя получателя и имя переменной-члена. Введите attr_reader: name для рубина, и этого больше не может быть. Просто невозможно в java.
Если ваш геттер когда-либо станет нетривиальным, вы все равно можете добавить для него тест.
источник
Проверьте исходный код, который вас беспокоит.
Бесполезно тестировать части кода, в которых вы очень уверены, если вы не делаете в них ошибок.
Тестируйте исправления, так что это будет первый и последний раз, когда вы исправляете ошибку.
Тестируйте, чтобы получить уверенность в непонятных частях кода, чтобы создавать знания.
Тестируйте перед тяжелым и средним рефакторингом, чтобы не нарушить существующие функции.
источник
Этот ответ больше предназначен для того, чтобы выяснить, сколько модульных тестов использовать для данного метода, который, как вы знаете, вы хотите выполнить, из-за его критичности / важности. Используя технику Basis Path Testing от McCabe, вы можете сделать следующее, чтобы количественно получить более надежное покрытие кода, чем простое «покрытие операторов» или «покрытие ветвей»:
источник