Модульное тестирование

Модульное тестирование

При подходе “черного ящика” тестировщики не проводят модульное тестирование. Их главная цель – проверить приложение на соответствие требованиям, не вдаваясь в детали реализации.

Но, будучи любопытным или нестандартно мыслящим человеком, задумывались ли вы когда-нибудь о том, как разработчики тестируют свой код? Какой метод они используют для тестирования, прежде чем передать его QA? Как важно тестирование для разработчиков в agile-процессе?

Ответ на все это – unit-тестирование. Я хочу рассказать вам о важности unit (модульного) тестирования, чтобы команды разработчиков и тестировщиков могли работать более слаженно для разработки, тестирования и релиза качественного приложения.

Кто знает, возможно, в будущем некоторые из вас даже перейдут на тестирование “белого ящика” и будут самостоятельно использовать эти методы проверки и улучшения кода!

Друзья, подпишитесь на наш телеграм канал QaRocks. Там много туториалов, задач по автоматизации и книг по QA.

Содержание:

Что такое unit-тестирование?

Unit-тестирование – это не новая концепция. Обычно разработчики и иногда тестировщики, использующие подход “белого ящика”, пишут модульные тесты для улучшения качества кода путем проверки каждой единицы кода, используемой для реализации функциональных требований (также известная как разработка на основе тестов (TDD) или test-first разработка).

Большинство из нас знают классическое определение: “Unit-тестирование – это метод проверки самого маленького тестируемого фрагмента кода на соответствие его цели”. Если цель или требование не выполняются, значит, unit-тестирование провалено.

Простыми словами, это означает – написание части кода (модульного теста) для проверки кода (модуля), написанного для реализации требований.

Unit-тестирование в SDLC

Модульное тестирование в SDLC

Для unit-тестирования разработчики используют ручные или автоматизированные тесты, чтобы убедиться, что каждый блок ПО соответствует требованиям заказчика. Таким блоком может быть отдельная функция, объект, метод, процедура или модуль в тестируемом приложении.

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

Важность написания unit-тестов

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

Оно является неотъемлемой частью agile-процесса разработки ПО. При ночной сборке должен запускаться набор модульных тестов и генерироваться отчет. Если какой-либо из unit-тестов не прошел, то команда QA не должна принимать эту сборку для проверки.

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

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

Если вы хотите изучить unit-тестирование в деталях – посмотрите обзор книги «Принципы юнит-тестирования»

Методы unit-тестирования

Оно может быть выполнено двумя способами:

  1. Ручное тестирование
  2. Автоматизированное тестирование

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

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

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

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

Техники unit-тестирования

1. Тестирование “белого ящика”:

При тестировании “белого ящика” тестировщик знаком с внутренней структурой ПО, включая код, и может проверить его на соответствие требованиям проекта. Тестирование “белого ящика” также известно как “прозрачное тестирование”.

Тестирование белого ящика.

2. Тестирование “черного ящика”:

При тестировании “черного ящика” тестировщик не знает ни внутренней структуры, ни имеет доступа к коду ПО.

Тестирование черного ящика.

3. Тестирование “серого ящика”:

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

Отладка осуществляется путем фактического ввода данных с frontend для получения точных данных с backend. Таким образом, “серый ящик” считается комбинацией методов тестирования “черного” и “белого” ящиков.

Тестирование серого ящика.

Тестирование “серого ящика” охватывает следующие виды тестирования:

  • Тестирование по матрице требований.
  • Регрессионное тестирование.

Преимущества unit-тестирования

  1. Процесс становится гибким: Чтобы добавить новые функции или возможности в существующее ПО, необходимо внести изменения в старый код. Но внесение изменений в уже протестированный код может быть рискованным и дорогостоящим.
  2. Улучшается качество кода: Качество кода автоматически улучшается, когда проводится модульное тестирование. Ошибки, выявленные в ходе такого тестирования, исправляются до того, как они будут отправлены на этап интеграционного тестирования. Это приводит к надежности проектирования и разработки, поскольку разработчики пишут тест-кейсы, предварительно разобравшись в спецификациях.
  3. Раннее обнаружение ошибок: Выполняя unit-тесты, разработчики обнаруживают ошибки на ранних этапах жизненного цикла разработки ПО и устраняют их. Это касается как недостатков или отсутствующих частей в спецификации, так и ошибок в реализации программиста.
  4. Более легкие изменения и упрощенная интеграция: Проведение unit-тестирования облегчает разработчику реструктуризацию кода, внесение изменений и сопровождение кода. Это также значительно упрощает тестирование кода после интеграции. Исправление проблемы при unit-тестировании может застраховать от ряда других дефектов, возникающих на последующих этапах разработки и тестирования.
  5. Доступность документации: Разработчики, которые изучают функциональность на более поздних этапах, могут обратиться к документации по unit-тестированию и легко найти интерфейс модульного теста – затем быстро и легко исправить работу.
  6. Простой процесс отладки: Это помогает упростить процесс отладки. Если тест не прошел на каком-либо этапе, код необходимо отлаживать, иначе процесс можно продолжать без каких-либо препятствий.
  7. Более низкая стоимость: Когда ошибки обнаруживаются и устраняются во время unit-тестирования, снижается стоимость и время разработки. Без такого тестирования, если те же ошибки будут обнаружены на более позднем этапе после интеграции кода, их будет сложнее отследить и устранить, что приведет к увеличению времени разработки и, следовательно, стоимости.
  8. С помощью unit-тестов можно проверить полноту кода: Это более полезно в agile-процессах. Тестировщики не получают функциональные сборки для тестирования до завершения интеграции. Полноту кода нельзя обосновать, показав, что вы написали и проверили код. Однако выполнение unit-тестов может продемонстрировать завершенность кода.
  9. Экономия времени разработки: Завершение реализации какой-либо функциональности может занять больше времени, но благодаря меньшему количеству ошибок при системном и приемочном тестировании можно сэкономить общее время разработки.
  10. Покрытие кода может быть измерено.

Цикл модульного тестирования

Цикл модульного тестирования.

Что делает хороший unit-тест?

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

Как писать хорошие unit-тесты?

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

Фреймворки для unit-тестирования

Фреймворки для unit-тестирования в основном используются для того, чтобы помочь быстро и легко написать модульные тесты. Большинство языков программирования не поддерживают модульное тестирование встроенным компилятором. Чтобы сделать unit-тестирование еще более увлекательным, можно использовать сторонние инструменты с открытым исходным кодом и платные инструменты.

Список популярных инструментов unit-тестирования для различных языков программирования:

  1. Java framework – JUnit
  2. PHP-фреймворк – PHPUnit
  3. Фреймворки C++ – UnitTest++ и Google C++
  4. Фреймворк .NET – NUnit
  5. Фреймворк Python – pytest

Частые заблуждения о unit-тестировании:

  • Написание кода с применением unit-тестов занимает больше времени, которого у нас и так нет – в действительности, это сэкономит время разработки в долгосрочной перспективе.
  • Unit-тестирование поможет найти все ошибки – не поможет, поскольку цель unit-тестирования заключается не в поиске ошибок, а в разработке надежных программных компонентов, которые будут иметь меньше дефектов на последующих этапах SDLC.
  • 100% покрытие кода означает 100% покрытие тестов – это не гарантирует, что код не содержит ошибок.

Как создавать и выполнять unit-тесты?

Хорошее модульное тестирование может состоять из 3 основных частей.

  1. Написать код unit-теста.
  2. Запустите код модульного тестирования, чтобы проверить, соответствует ли он системным требованиям.
  3. Выполнить программный код, чтобы проверить его на наличие дефектов и убедиться, что код соответствует системным требованиям.

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

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

Лучшие практики

Чтобы создать наиболее качественный код, учитывайте следующие моменты во время тестирования:

  • Код должен быть стабильным: Бывают случаи, когда тест проваливается или в худшем случае вообще не выполняется, если код сломан.
  • Понятным и полезным: Код должен быть простым для понимания. Это облегчает написание кода для разработчика, и даже другие разработчики, которые будут работать над кодом впоследствии, смогут легко его отладить.
  • Должен быть один случай: Тесты, которые определяют несколько тест-кейсов сразными входными даными в одной функции, сложны в работе. Таким образом, написание кода для одного тест-кейса является лучшей практикой, что делает код более простым для понимания и отладки.
  • Автоматизируйте запуск тестов: Разработчики должны позаботиться о том, чтобы тест выполнялся автоматически. Это должно быть в рамках непрерывного процесса доставки или интеграции (CI/CD).

Другие моменты, которые следует иметь в виду:

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

Заключение

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

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

Список best practices модульного тестирования можно почитать в нашей статье “Лучшие практики юнит-тестирования”

Ваши комментарии приветствуются!
Как тестировщик, использующий подход “черного ящика”, каковы ваши наблюдения о unit-тестировании в вашей команде? Есть ли у кого-нибудь идеи для улучшения unit-тестирования?

Перевод статьи “Key to Successful Unit Testing – How Developers Test Their Own Code?”

4 комментария к “Модульное тестирование”

  1. Пингбэк: Что такое тестовый набор

  2. Пингбэк: Большой учебник по тестированию

  3. Пингбэк: Тест-план для мобильных приложений

  4. Пингбэк: Функциональное тестирование

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *