Таким образом, руководство стремится сделать шаг, чтобы двигаться к выполнению модульного тестирования во всех приложениях, продвигающихся вперед, и, в конечном итоге, войти в полноценный режим TDD/Continuous Integration/Automated build (надеюсь). Однако на данный момент мы просто обеспокоены тем, что все разработчики приложений продвигаются вперед с помощью модульного тестирования. Я бы хотел начать с основ.
Я не буду лгать - я далеко не эксперт ни в коем случае в модульном тестировании, но у меня есть достаточно хорошее понимание, чтобы начать инициативу с основ и позволить нам расти togeather как команда. Мне очень хотелось бы получить комментарии и критические замечания всех ваших экспертов о моем плане нападения на эту вещь. Это команда из 10 разработчиков в небольшом магазине, что дает прекрасную возможность продвигаться вперед с гибкими методологиями разработки и передовыми методами.
Вначале команда состоит из разработчиков в основном среднего уровня с несколькими младшими разработчиками и одним старшим, причем с минимальным уровнем воздействия на единичное тестирование. Обучение будет проходить ежемесячно в течение 30-60 минут каждый раз (возможно, дождаться часа, я думаю, и, возможно, их чаще). Мы продолжим эти встречи, пока не будет смысла останавливать их, чтобы другие могли догнать свою "домашнюю работу" и опыт, но толчок всегда будет включен.
В любом случае - вот мой план уроков, который я придумал. Ну, по крайней мере, первые два. Любые советы ваших экспертов о фактическом содержании или структуре уроков и т.д. Были бы замечательными. Комментарии и критика очень ценятся. Большое спасибо.
Прошу прощения, если это слишком много, чтобы публиковать здесь или читать. Я думаю, что это будет отличная тема для пользователей SO, которые хотят попасть в модульное тестирование в первую очередь. Возможно, вы могли бы просто перейти к разделу "планы уроков" - еще раз спасибо всем.
ЗАМЕТКИ CLIFF. Я понимаю, что этот пост невероятно длинный и уродливый, так что вот записки об утесе. Урок 1 будет "приветствовать мировые модульные тесты". Урок 2 откроет мое решение самое последнее приложение и демонстрируя, как применять каждый пример "привет мир" в реальной жизни... Большое спасибо всем за отзывы, которые вы мне дали до сих пор. Просто хочу подчеркнуть тот факт, что урок 2 будет иметь в нем тестируются реальные единицы производства, так как многие из них предлагают мне это, когда это был мой план с самого начала =)
План занятий по тестированию модулей
Обзор
Почему unit test? Похоже на кучу дополнительной работы - так зачем это делать?
• Станьте хозяином своей собственной судьбы. Большинство наших пользователей не делают настоящих UAT и, к сожалению, как правило, делают свое тестирование один раз в производстве. При модульных тестах мы значительно уменьшаем риск, связанный с этим, особенно когда мы создаем достаточное количество тестовых данных и учитываем как можно больше ресурсов верхнего уровня. Хотя это не "серебряная пуля, которая предотвращает все ошибки", это ваша первая линия обороны - огромная линия фронта, сопоставимая с победой гигантов чемпионата SB.
• Unit-Testing обеспечивает хорошие методы проектирования и архитектуры. Это "насильственный психопат", который поддерживает ваш код и знает, где вы живете, так сказать. Вы просто не можете написать плохой качественный код, который хорошо протестирован с помощью модуля
• Сколько раз вы не перерабатывали вонючий код, потому что вы слишком боялись что-то сломать? Автоматическое тестирование устраняет этот страх, упрощает рефакторинг, в свою очередь делая код более читаемым и более простым в обслуживании.
• Нижняя линия - обслуживание становится намного проще и дешевле. Время, затрачиваемое на проведение блок-тестов, может быть дорогостоящим сейчас, но время, которое он спасает вас по дороге, снова и снова доказывалось гораздо более ценным. Это причина №1 для автоматизации тестирования кода. Это дает нам уверенность в том, что позволяет нам принимать более амбициозные изменения в системах, которые, возможно, в противном случае мы должны были бы снизить требования или, возможно, даже не принять вообще.
Обзор терминологии
• Единичное тестирование - тестирование самого низкого уровня, единицы измерения. НАПРИМЕР. - проверить все возможные пути кода, через которые может проходить одна функция.
• Интеграционное тестирование - тестирование работы ваших подразделений. Например. - запускать задание (или ряд вызовов функций), которое выполняет кучу работы с известными входами, а затем запрашивает базу данных в конце и утверждает, что значения - это то, что вы ожидаете от этих известных входов (вместо того, нарисуйте сетку на веб-странице где-нибудь, например, выполните функциональный тест).
• Подделки - подделка - это тип объекта, целью которого является использование для вашего тестирования. Это позволяет вам слишком легко не тестировать код, который вы не хотите тестировать. Вместо того, чтобы вызывать код, который вам не нужен - как вызов базы данных - вы используете поддельный объект для "подделать этот вызов БД и, возможно, читать данные из файла XML/Excel или насмешливую структуру. o Mock - тип подделки, к которому вы делаете утверждения. o Stub - тип подделки, который вы используете в качестве кода-заполнителя, поэтому вы можете пропустить вызов базы данных, но не делайте утверждений против
Уроки
Урок один - Hello Worlds
• Hello World unit test - Я создам "консольное приложение hello world", которое будет проверено модулем. Создаст это приложение на ходу во время собрания, показывая инструменты в Visual Studio 2008 (тестовый проект, панель инструментов инструментов тестирования и т.д.), Которые мы будем использовать по пути, объясняя, что они делают. Это будет только один единичный тест. (Хорошо, может быть, я не создам его "на лету" =), подумайте об этом больше). Также объяснит класс Assert и его назначение и общий поток единичного теста.
• Hello World, немного сложнее. Теперь наша функция имеет разные пути/логические ветки, через которые может протекать код. У нас будет ~ 3 модульных теста для этой функции. Это будет предварительно написанное решение, которое я делаю перед собранием.
• Hello World, инъекция зависимостей. (Не использовать какие-либо рамки DI). Предварительно написанное решение, которое строится на предыдущем, на этот раз с использованием инъекции зависимостей. Объяснит, что такое DI, и покажите образец того, как он работает.
• Hello World, Mock Objects. Предварительно написанное решение, которое основывается на предыдущем, на этот раз, используя наш недавно добавленный код DI, чтобы ввести в нас классный объект, чтобы показать, как насмехаются работы. Будет использовать NMock2.0, поскольку это единственный, с которым я подвергаюсь воздействию. Очень простой пример, чтобы просто отображать использование макетных объектов. (Возможно, поместите это в отдельный урок?).
• Hello World, (неавтоматизированный) тест интеграции. Создав предыдущее решение, мы создаем интеграционный тест, чтобы показать, как тестировать две функции вместе или весь класс вместе (возможно, поместите это в отдельный урок?)
Урок два - теперь мы знаем основы - как применить это в реальной жизни?
• Общий обзор передового опыта o Правило № 1- Одиночная ответственность. Одиночная ответственность. Одиночная ответственность. Честно говоря, это самое важное, что нужно помнить при написании кода. Класс должен иметь только одну цель; функция должна делать только одно. Ключевым словом здесь является "единичный тест", и SRP будет содержать ваши классы и функции, инкапсулированные в единицы. o Dependency Injection - ваш второй лучший друг. DI позволяет вам "подключать поведение к классам, которые у вас есть, во время выполнения. Среди прочего, это то, как мы используем насмешливые фреймворки, чтобы сделать наши более крупные классы более легко проверяемыми.
o Всегда думайте, как я буду тестировать это, когда вы пишете код. Если кажется, что "слишком сложно проверить, скорее всего, ваш код слишком сложный. Перегруппируйте его до более логических единиц классов/функций - возьмите тот класс, который делает 5 вещей и превратит их в 5 классов, один из которых вызывает другой 4. Теперь ваш код будет намного проще тестировать, а также проще читать и рефакторировать.
o Тестирование, а не реализация. В двух словах это означает, что мы можем в большинстве случаев проверять только публичные функции на наших классах. Мы не заботимся о тестировании частных (реализация), потому что публичные (поведение) - это то, что использует наш кодовый код. Например... Я разработчик программного обеспечения миллионера и отправляюсь в автосалон Aston Martin, чтобы купить себе новый DB9. Продавец говорит мне, что он может делать 0-60 за 3 секунды. Как бы вы это протестировали? Вы бы сняли двигатель и выполнили диагностические тесты и т.д.? Нет... Ты бы взял его на бульвар и сделал 160 миль в час =). Это тестирование поведения и реализации.
• Просмотр приложения с проверкой работоспособности в реальном времени. Здесь мы рассмотрим каждый из приведенных выше примеров "hello world", но реальных версий, используя мой последний проект в качестве примера. Я открою простой unit test, более сложный, который использует DI, и тот, который использует Mocks (вероятно, связан с DI одним). Этот проект довольно мал и прост, так что он действительно идеально подходит. Это также будет включать тестирование DAL и как настроить тестовую базу данных для запуска этих тестов.