Когда / как часто я должен проводить тестирование?

StackOverflow https://stackoverflow.com/questions/23031

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

Что ж, если вы хотите следить за ребятами из TDD, прежде чем вы начнете писать код ;)

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

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

Редактировать:

Я подумал, что, вероятно, мне следует подробнее остановиться на этом, это мой основной "рабочий процесс"...

  1. Спланируйте, что я хочу от кода, возможный дизайн объекта, что угодно.
  2. Создаю свой первый класс, добавляю огромный комментарий вверху, описывающий каково мое "видение" этого класса.
  3. Опишите основные сценарии тестирования..Это в основном стать модульных тестов.
  4. Создаю свой первый метод..Также напишу короткий комментарий, объясняющий как это ожидаемый на работу.
  5. Напишите автоматический тест, чтобы увидеть, делает ли он то, что я ожидаю.
  6. Повторите шаги 4-6 для каждого метода (обратите внимание, что автоматические тесты находятся в огромном списке, который выполняется на F5).
  7. Затем я создаю несколько сложных тестов для эмуляции класса в рабочей среде, очевидно, устраняя любые проблемы.
  8. Если после этого обнаружатся какие-либо новые ошибки, я вернусь и запишу новый тест, удостоверюсь, что он завершается неудачей (это также служит доказательством концепции ошибки), затем исправлю его..

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

Другие советы

Прежде чем вы введете код в действие.

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

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

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

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

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

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

Хорошим ключом к запоминанию является

"Тестируйте рано, тестируйте часто и тестируйте снова, когда решите, что закончили".

Когда проводить тестирование?Когда важно, чтобы код работал правильно!

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

В более крупном проекте я пишу тесты перед написанием класса и запускаю тесты после каждого изменения этого класса.

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

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

Наверное, я бы сказал:"Проверяйте почаще".

Я только недавно добавил модульное тестирование в свой обычный рабочий процесс, но я пишу модульные тесты:

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

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

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

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

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

Кроме того, взгляните на такой продукт, как CruiseControl.СЕТЬ для выполнения непрерывных сборок.CC.NET приятно, что он будет запускать ваши модульные тесты с каждой сборкой, немедленно уведомляя вас о любых сбоях.

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

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

Красный:Напишите свой тест так, чтобы он не прошел успешно.Таким образом, вы знаете, что тест утверждает правильную переменную.

Зеленый:Сделайте так, чтобы ваш новый тест прошел как можно проще.Если это означает жесткое кодирование, то все в порядке.Это отлично подходит для тех, кто просто хочет, чтобы что-то заработало прямо сейчас.

Рефакторинг:Теперь, когда ваш тест пройден, вы можете вернуться назад и с уверенностью изменить свой код.Ваше новое изменение нарушило ваш тест?Отлично, ваше изменение имело значение, которого вы не осознавали, теперь ваш тест говорит вам об этом.

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

Здесь много отличных ответов!

Я стараюсь тестировать на самом низком уровне, который имеет смысл:

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

  • Протестируйте каждую функцию.

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

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

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

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

** Я знаю, -1 для бесплатной ссылки на указатель буфера!*

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top