Тестирование умных оболочек для сторонних библиотек - PullRequest
6 голосов
/ 08 мая 2011

Предположим, вам необходимо использовать излишне сложную, трудную для насмешки (возможно, у нее есть конкретные классы без виртуального интерфейса) и ненадежную стороннюю библиотеку, которая интегрируется с некоторым внешним ресурсом, таким как сокет или база данных.Вы решаете создать интерфейсы / классы «оболочки», чтобы значительно упростить использование этой библиотеки и позволить разработчикам, использующим оболочку, продолжать писать тестируемый код.Интерфейс обертки не похож на оригинальный интерфейс.

У меня есть несколько вопросов о том, как протестировать эту обертку.

  1. Если обертка будет проверена без внешнего ресурсаразработка слоя метода для метода над плохой библиотекой, которая может быть подделана?

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

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

Ответы [ 3 ]

9 голосов
/ 08 мая 2011

TDD не говорит, что все должно быть проверено модулем.TDD говорит, что вы должны сначала написать тест, но это не обязательно должен быть модульный тест.

  1. Начните с интеграционного теста - он проверит вашу логику в зависимости от оболочки, которая будет взаимодействовать с реальным компонентом,Здесь нет издевательств.Это интеграционный тест, потому что он тестирует несколько уровней вашего приложения, а реальный компонент все еще использует сокеты или доступ к базе данных.
  2. Интеграционный тест не пройден, потому что у вас нет логики
  3. Напишите модульный тест с поддельной оболочкой для проверки логики
  4. Модульный тест не пройден, потому что вы неt Ваша логика
  5. Напишите логику для выполнения модульного теста (4.)
  6. Повторите 3.-5.чтобы получить всю логику, необходимую для выполнения интеграционного теста (1.)
  7. Повторить весь процесс со следующим интеграционным тестом

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

Я рекомендую прочитать Growing Object-OrientedПрограммное обеспечение под руководством тестов Стива Фримена и Ната Прайса.

6 голосов
/ 08 мая 2011

Я думаю, что этот вопрос вращается вокруг этого утверждения:

Интерфейс оболочки не похож на оригинальный интерфейс

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

Лучший способ сделать это - извлечь интерфейс 1: 1 из исходного API. Однако это не тот интерфейс, который вы предоставляете остальной части приложения. Интерфейс, который вы предоставляете остальной части приложения, может быть Facade поверх извлеченного интерфейса. В некотором смысле вы могли бы сказать, что извлеченный интерфейс - это деталь реализации антикоррупционного уровня, а не то, что доступно остальной части приложения.

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

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

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

2 голосов
/ 08 мая 2011

Объявление 1) Нет, это короткий ответ.Обертка не должна делать ничего, кроме обертки.Поэтому интеграционное тестирование - единственное, что имеет смысл.

Объявление 2) Да, это так.

Объявление 3) вы останавливаетесь, когда целевой объект делает только одно, и позволяете внешним объектам - инъекционным и насмешливым - делать все остальное (SRP)

...