Подтвердить что ты не робот

Тестирование блока черного ящика

В моем последнем проекте у нас было Unit Testing с почти 100% cc, и в результате у нас почти не было ошибок. Однако, поскольку Unit Testing должен быть White Box (вы должны издеваться над внутренними функциями, чтобы получить желаемый результат, поэтому ваши тесты должны знать о внутренней структуре вашего кода) в любое время, когда мы меняли реализацию функции, нам приходилось также измените тесты. Обратите внимание, что мы не изменили логику функций, а только реализацию. Это было очень много времени, и мне казалось, что мы работаем не так. Поскольку мы использовали все надлежащие рекомендации ООП (в частности, инкапсуляцию), каждый раз, когда мы меняли реализацию, нам не приходилось менять остальную часть нашего кода, но приходилось менять модульные тесты. Мне казалось, что мы проводим тесты, а не обслуживаем нас.

Чтобы этого не случилось, некоторые из нас утверждали, что модульные тесты должны проводиться в Black Box Testing. Это было бы возможно, если мы создадим один большой макет нашего всего Домена и создадим заглушку для каждой функции в каждом классе в одном месте и будем использовать ее в каждом unit test. Конечно, если конкретный тест нуждается в конкретной внутренней функции, которую нужно вызвать (например, чтобы мы записывали в БД), мы можем переопределить наш заглушку.

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

Другие утверждают, что модульные тесты должны быть White Box, так как вы не только хотите, чтобы ваше приложение записывалось в БД в определенном месте, вы хотите, чтобы ваше приложение не записывалось в базу данных где-нибудь еще, ожидайте этого. Хотя это действительный момент, я не думаю, что это стоит времени для написания тестов White Box вместо тестов Black Box.

Итак, в заключение, 2 вопроса:

  • Что вы думаете о концепции тестирования модулей Black Box?

  • Что вы думаете о том, как мы хотим реализовать эту концепцию? У вас есть лучшие идеи?

4b9b3361

Ответ 1

Вам нужны разные типы тестов.

  • Единичные тесты, которые должны быть белыми, как вы делали

  • Интеграционные тесты (или системные тесты), которые проверяют возможность использования фактических реализаций вашей системы и ее связи с внешними слоями (внешними системами, базой данных и т.д.), которые должны быть в стиле черного ящика, но каждый один для конкретной функции (например, тесты CRUD)

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

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

Ответ 2

и в результате у нас почти не было никаких ошибок

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

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

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

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

Ответ 3

tl; dr версия:

  • Тестирование модулей Black Box - это именно то, как следует проводить модульное тестирование.
  • Тестирование модулей Black Box - это именно то, как следует проводить модульное тестирование. Правильная практика TDD делает именно это.

Полная версия.

В тестировании частных методов объектов абсолютно нет необходимости. Это также не повлияет на покрытие кода.

Когда вы TDD класса, вы пишете тесты, которые проверяют поведение этого класса. Поведение выражается через общедоступные методы этого класса. Вы никогда не должны беспокоиться о том, как эти методы действительно реализованы. Люди Google описали это намного лучше, чем я когда-либо смогу: http://googletesting.blogspot.ru/2013/08/testing-on-toilet-test-behavior-not.html

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

Ответ 4

Думаю, вам следует продолжать писать модульные тесты - просто сделайте их менее хрупкими.

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

Существует несколько правил большого пальца - например, "не тестировать частные методы" и использовать макетные объекты.

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

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

Ответ 5

", в результате у нас почти не было никаких ошибок" - так что держите его таким образом. Единственной причиной разочарования является необходимость проведения модульных тестов, что на самом деле не так уж плохо (альтернатива намного хуже). Просто сделайте их более удобными. "Искусство Unit Testing" Роя Ошерова дал мне хорошее начало таким образом. Так 1) Не вариант. (Сама идея противоречит принципам TDD, например) 2) У вас будет больше проблем с обслуживанием с таким подходом. Философия модульного тестирования заключается в том, чтобы вырезать SUT из другой системы и протестировать его с помощью заглушек в качестве входных данных и mocks как выход (сигналы?), Имитирующие реальные жизненные ситуации (или mb я просто не поймаю идею "один большой макет нашего всего домена" ).