Эффективное покрытие модульных испытаний (и что на самом деле должно быть проверено?) - PullRequest
5 голосов
/ 13 апреля 2011

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

(Я не уверен, имеет ли это значение, но я использую C # с .NET Framework 4.0 и использую встроенную среду тестирования Microsoft)

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

Второй пример. У меня есть блок кода, который выполняет несколько вызовов приватных методов класса и, наконец, вызывает веб-сервис, чтобы отправить электронное письмо пользователю. Я понимаю, что мне нужно внедрить фиктивный веб-сервис для службы электронной почты, чтобы я не тестировал несколько классов, но как мне проверить, что все эти частные методы и этот вызов по электронной почте выполнены?

Третий пример похож на последний. Моя классовая структура выглядит примерно так:

Контроллер --- зависит от ---> IWidget (некоторый бизнес-объект) && IDataProvider DataProvider (реализует IDataProvider) --- зависит от ---> WebService WebService --- напрямую звонит ---> База данных

Сейчас у меня есть модульные тесты для контроллера (внедрение фиктивных виджетов и провайдеров данных). Так что все хорошо. У меня также есть модульные тесты для Widget без проблем.

Проблема заключается в DataProvider и WebService. WebService в данном конкретном случае ничего не делает, но проходит через запросы поставщика данных и возвращает данные (из-за ограничений физической архитектуры).

У меня проблемы с модульным тестированием DataProvider, потому что я не знаю, как сделать инъекцию поддельного веб-сервиса. Я также не уверен, стоит ли проводить модульное тестирование DataProvider, потому что мне пришлось бы кодировать множество макетированных наборов данных только для проверки значений. Точно так же я не уверен, как выполнить модульное тестирование веб-службы, потому что в этом случае основная функция WebService зависит от базы данных. Еще раз, стоит ли это тестировать? Что, если WebService сделал больше, кроме того, что он просто служил проходом, но все еще зависел от базы данных?

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

Ответы [ 2 ]

3 голосов
/ 13 апреля 2011

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

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

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

У меня есть блок кода, который делает несколько вызовов классачастные методы и, наконец, вызывает веб-сервис, чтобы отключить электронную почту для пользователя.Я понимаю, что мне нужно внедрить фиктивный веб-сервис для службы электронной почты, чтобы я не тестировал несколько классов, но как мне проверить, что все эти частные методы и этот вызов по электронной почте выполнены?

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

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

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

2 голосов
/ 13 апреля 2011

Ad First)
Вы можете утверждать, что на самом деле вы не предоставляете никакой функциональности, если вы только делаете операторы настройки.Но если у вас есть начальник, который занимается вопросами покрытия кода, не тестирование такого метода принесет вам неприятности.И да, вы должны утверждать только одну вещь, но IMHO утверждение для каждого свойства устанавливается корректно методом, тогда оно считается только как одно утверждение - независимо от того, сколько операторов assert содержится в вашем тестовом методе.Иногда я даже извлекаю все утверждения в приватный метод, чтобы проиллюстрировать это

Ad Second) Если вам нужно протестировать приватные методы, это означает, что вам, вероятно, будет лучше извлечьте.

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

Обновлено:
Упс ... перепутано с нумерацией.Исправлено сейчас

...