4.5.2. Блочные тесты
Блочное тестирование наиболее понятно для программиста. Фактически это тестирование методов какого-то класса программы в изоляции от остальной программы и является комбинацией методов «белого» и «черного» ящиков.
Однако, далеко не всякий класс легко покрыть блочными тестами. При проектировании тестов необходимо учитывать возможность тестируемости и зависимости класса проектировать и реализовывать явными.
Чтобы гарантировать тестируемость, можно применять методологию TDD, которая предписывает сначала писать тест, а потом код реализации тестируемого метода. Тогда архитектура получается тестируемой. Распутывание зависимостей можно осуществить с помощью Инспектора Зависимостей (Dependency Injection, Microsoft). Тогда каждой зависимости явно сопоставляется интерфейс и явно определяется, как инжектируется зависимость — в конструктор, в свойство или в метод.
Для осуществления блочного тестирования существуют специальные API и фреймворки. Например, NUnit или тестовый фреймфорк из среды Visual Studio. Для возможности тестирования классов в изоляции существуют специальные «Mock» фреймворки. Например «Rhino Mocks». Они позволяют по интерфейсам автоматически создавать заглушки для классов-зависимостей, задавая у них требуемое поведение.
По блочному тестированию написано много статей [15–20]. Ниже приводятся основные идеи и концепции методологий блочного тестирования.
Основные аспекты при проектировании блочных тестов:
- Влияние тестов на дизайн (API),тест — первый клиент разрабатываемого API.
- Тесты как документация.
- Как часто нужно запускать тесты?
- Когда добавлять тесты:
- при разработке контракта класса;
- при обнаружении ошибки.
- Как изменять тесты при рефакторинге?
- это помогает найти проблемы, с которыми столкнутся клиенты.
- Полнота тестирования:
- стремиться к полным тестам;
- сосредоточиться на проблемных режимах;
- проверять реакции на нарушение контракта (исключения и коды ошибок).
- Что невозможно протестировать:
- утверждения;
- приемочные тесты.
Методология JUnit
- Класс тестов TestCase.
- testMethod().
- Методы assertTrue(), assertFalse(), assertEquals(), assertNull(), assertNotNull(), assertSame().
- Метод fail(), тестирование исключений.
- setUp(), fixture.
- tearDown(), external fixture.
- TestSuite, JUnit 4, TestNG, использование аннотаций зависимости между тестами.
Методология TDD (Test Driven Development)
- Связь с экстремальным программированием.
- Чистый код, который работает.
- Сначала пишутся тесты, потом код:
- заказ API от клиента;
- сначала подумайте, потом напишите;
- документация контракта;
- уверенность в изменениях.
- Цикл TDD:
- красный;
- зеленый;
- рефакторинг.
- Пять шагов:
- написание теста, компиляция;
- красная полоса;
- модификация;
- зеленая полоса;
- устранение дублирования.
- Действия на каждом шаге.
Методика TDD.
- Написав тест, сделать минимум действий, необходимых для компиляции.
- Удостовериться: что не должно работать, не работает. Если работает — разберитесь, почему.
- Минимальная модификация. Если из-за вашей модификации приходится писать новый тест,
значит она слишком большая:
- подделка реализации;
- тестирование теста.
- Необходимо добиться прохождения теста перед тем, как писать новый код (тест).
- Устранение дублирования во всем: в коде, константах, тестах.
- Влияние TDD на дизайн:
- Тест — это спецификация;
- Выявление проблем и задач;
- Дублирование где бы то ни было — повод для рефакторинга.
- зеленая полоса;
- устранение дублирования.
Основные паттерны TDD:
- Изолировать тесты
- Список тестов – список задач
- Вначале пишется тест
- Начать тест с assert
- Понятные тестовые данные
- Когда надо писать новый тест, выбирать из списка тот, который:
- можно написать;
- будет полезен для понимания задач на данном этапе.
- Объясняющий тест
- Тест для изучения библиотеки
- Любая посторонняя мысль – повод для добавления строки в список тестов.
- Нашли ошибку – пишем тест, который ее воспроизводит
- Если тест слишком велик, разделите его на части
- Поддельные объекты: если нужно тестировать что-то очень сложное и неуправляемое (например, пользовательский интерфейс), можно подделать (имитировать) это своим тестовым классом.