Введение в модульное тестирование на C#


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

Что такое модульное тестирование?

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

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

Что такое автоматизированный модульный тест?

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

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

Другие преимущества автоматизированного модульного тестирования

Основным преимуществом модульного тестирования является повышенная уверенность в том, что ваш код ведет себя правильно. Некоторые другие преимущества описаны многими программистами. Ключевое преимущество, которое передают специалисты по тестовой разработке (TDD), также известной как дизайн, основанный на тестировании, заключается в том, что модульные тесты могут улучшить дизайн вашего программного обеспечения. Модульное тестирование требует, чтобы небольшие участки кода проверялись независимо. Как мы увидим далее в учебнике, тесты должны стремиться изолировать тестируемый класс или метод от его зависимостей. Для создания тестируемого кода обычно следует следовать принципам SOLID. Однако вполне возможно провести успешные испытания и при этом иметь некачественный дизайн.

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

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

Ограничения

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

Распространенные заблуждения

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

Написание тестов занимает слишком много времени

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

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

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

Есть также некоторые части вашего кода, которые настолько упрощены, что не требуют тестирования. Например, обычно не стоит тестировать свойства, которые просто предоставляют средства получения и настройки для базовой переменной резервного хранилища. Тесты для этих свойств будут тестами на правильность работы C#; то, что должна тестировать только корпорация Майкрософт, и что вы мало что можете сделать, чтобы исправить, если будет обнаружена проблема.

Выполнение тестов занимает слишком много времени

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

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

Одноразовый код не требует тестирования

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

Модульные тесты портят схему программы

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

Это обоснованная проблема, поскольку частные методы являются деталями реализации, которые не должны быть видны за пределами их содержащих классов. Делая их общедоступными, вы рискуете, что они будут использоваться извне, нарушая правила инкапсуляции и усложняя, если не делая невозможным, рефакторинг класса. Чтобы избежать этой проблемы, мы должны помнить, что мы тестируем поведение кода, а не детали реализации. Такое поведение почти всегда можно косвенно проверить через открытый интерфейс класса.
Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, си шарп, тестирование




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




Урок 11. Задачи продолжения C#
Урок 4. Простая авторизация и регистрация в Laravel
Урок 6. Арифметические операторы C#