exam15 4 - stankin/design-part-1 GitHub Wiki

Выполнил: Талько Стас

Проверил:


Технологии модульного тестирования (Unit Tests). Возможности и ограничения на применимость.

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

Для всех популярных языков программирования созданы фрейморки, которые позволяют упростить тестирование. Например, для Java есть JUnit и Mockito, а для JavaScript: MOCHA, JEST, JASMINE и т.д. Разработчик может сам выбрать любой удобный инструмент тестирования, подходящий для используемого языка, если работает над проектом один, либо обязательно должен знать тот, что используется в команде. Как правило, все эти фреймворки достаточно похожи и суть сводится к тому, что программист пишет исходные тестовые данные, которые затем обрабатываются с помощью тестируемых метода или функции, а потом результат сравнивается с тем, что программист указал как ожидаемый результат. Если они не совпадают, то тест будет провален, а значит в программе есть ошибка (при условии, что тест написан правильно).

Преимущества

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

Недостатки (ограничения)

  • Сложный код

Тестирование программного обеспечения — комбинаторная задача. Например, каждое возможное значение булевской переменной потребует двух тестов: один на вариант TRUE, другой — на вариант FALSE. В результате на каждую строку исходного кода потребуется 3−5 строк тестового кода. Алгоритмы вроде Marching cubes или красно-чёрного дерева имеют разветвлённое дерево решений, и чтобы проверить все варианты, нужны огромные наборы тестов. Как и любая технология тестирования, модульное тестирование не позволяет отловить все ошибки программы. В самом деле, это следует из практической невозможности трассировки всех возможных путей выполнения программы, за исключением простейших случаев.

  • Результат известен лишь приблизительно

Например, в математическом моделировании. Бизнес-приложения зачастую работают с конечными и счётными множествами, научные — с континуальными.[1] Поэтому сложно подобрать тесты для каждой из ветвей программы, сложно сказать, верен ли результат, выдерживается ли точность, и т. д. А во многих случаях качество моделирования определяется «на глаз», и последний результат записывается как «опорный». Если найдено расхождение, новый результат проверяют вручную и выясняют, какой качественнее: старый или новый.

  • Код, взаимодействующий с системой

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

  • Ошибки интеграции и производительности

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

  • При общей низкой культуре программирования

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

  • Проблемы с объектами-заглушками

За исключением простейших случаев, тестируемый объект должен взаимодействовать с другими объектами. Этих «товарищей по взаимодействию» — объекты-заглушки — делают предельно простыми: либо крайне упрощёнными (память вместо базы данных), либо рассчитанными на конкретный тест и механически повторяющими сессию обмена. Проблемы могут возникать при смене протокола обмена, в таком случае объекты-заглушки должны отвечать новым требованиям протокола.

Литература

https://logrocon.ru/news/unit_testing

https://ru.wikipedia.org/wiki/Модульное_тестирование

http://java-online.ru/junit-mockito.xhtml

https://blog.logrocket.com/a-quick-and-complete-guide-to-mocha-testing-d0e0ea09f09d/