Как вы определяете проблемы зависимостей с модульные тесты, когда используются макеты объектов?

У вас есть класс X, а вы пишите какие-то модульные тесты, которые проверяют поведение Х1. Там's также класса, который принимает X в качестве зависимостей.

Когда вы пишете юнит-тесты для, Вы издеваетесь над х. Другими словами, в то время как модульное тестирование, установить (постулат) поведение х'ы макет должен быть Х1. Время идет, люди делают использовать вашу систему, должен меняться, х развивается: изменения X, чтобы показать поведение Х2. Очевидно, что модульные тесты для X не удастся, и вам придется адаптировать их.

Но что с? Модульное тестирование не будет выполнена, когда x'ы поведения изменяется (из-за высмеивание х). Как определить, что'результаты будут разные при запуске с в "Реал" (изменены) х?

Я'м ожидая ответов вдоль линии: "Что's не цели тестирования и quot единицы;, но какое значение имеет тестирование блок есть? Действительно ли это только сказать вам, что, когда все тесты проходят, Вы не'т внесены критические изменения? И когда какая-класса'ы изменения поведения (вольно или невольно), как вы можете обнаружить (желательно в автоматическом режиме) все последствия? Должны'т мы ориентируемся больше на тестирование интеграции?

Комментарии к вопросу (16)

при написании модульных тестов Для, вы глумитесь х

Ты? Я Дон'т, если я абсолютно необходимо. Мне нужно, если:

  1. X - это медленный, или
  2. "Х" имеет побочные эффекты

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

Если у вас есть части вашего кода, используя глумится над другой части вашего кода, тогда я'd не согласен: в чем смысл таких тестов? Так Дон'т сделать это. Пусть эти тесты используют реальные зависимости, так как они образуют гораздо более ценное тесты таким образом.

И если некоторые народные расстраивайся ты называешь эти тесты, то "тесты" и называть их "на автоматических тестов" и вам на написание хороших автоматических тестов.

Комментарии (16)

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

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

С модульными тестами, вы только нужно 20 модульных тестов + 1 Тест на интеграцию, чтобы полностью покрыть все случаи.

С интеграционные тесты, вам понадобится 100 тестов, чтобы охватить все пути кода.

Здесь's очень хорошее видео про минусы опираясь только на интеграционных тестов [Дж комплексные тесты Rainsberger афера в HD][1]

Комментарии (8)

когда вы пишете юнит-тесты для, Вы издеваетесь над х. Другими словами, в то время как модульное тестирование, установить (постулат) поведение х'ы макет должен быть Х1. Время идет, люди делают использовать вашу систему, должен меняться, х развивается: изменения X, чтобы показать поведение Х2. Очевидно, что модульные тесты для X не удастся, и вам придется адаптировать их.

Эй, подождите минутку. Последствия тесты для X, не слишком важных замалчивать подобное.

Если меняется реализация х от Х1 до х2 нарушает модульные тесты для X, что означает, что вы'ве сделал обратно несовместимые изменения к договору Х.

Х2 разве'т х, в Лисков смысле, так что вы должны быть thinking о других способах удовлетворения потребностей своих заинтересованных сторон (например, внедрение новой спецификации Г, который реализуется Х2).

Для более глубокого понимания см. Питер Hinjens: конец версии программного обеспечения, или богатые Хики простой легко.

С точки зрения, там это условие, что партнер уважает контракт X. И ваши наблюдения эффективно, что изолированный тест на не'т дать вам никаких гарантий, что признает сотрудников, нарушающих х договора.

Комментарий комплексные тесты афера; в высоком уровне, вы должны иметь как множество разрозненных тестов, вы должны убедиться, что Х2 реализует контракт х правильно, и как множество разрозненных тестов, сколько нужно, чтобы убедиться, что все делает правильно дали интересные ответы от "Х", а некоторые меньшее количество integrated тестов, чтобы гарантировать, что Х2 и договориться о том, что X означает.

Вы будете иногда видеть это выраженные различия одиночное Тесты общительная против тесты; см. Джей поля эффективно работать с модульными тестами.

должны'т мы ориентируемся больше на тестирование интеграции?

Опять же, см. комплексные тесты лохотрон - Rainsberger подробно описывает положительную обратную связь, что является общим (в его опыте) в проектах, опираясь на интегрированные (обратите внимание на орфографию) тесты. В резюме, без изолированного/одиночные тесты applying давление на design, качество ухудшается, что приводит к ошибкам и более комплексных испытаний....

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

Комментарии (3)

Позвольте мне начать с того, что основной предпосылкой вопроса является некорректной.

Вам никогда не испытывать (или издевательски) реализации, тестировании (и насмешливо) интерфейсы.

Если у меня есть класс X, который реализует интерфейс Х1, я могу написать инсценировку Хм, что также соответствует Х1. Тогда мой класс должен использовать что-то, что реализует Х1, которое может быть класса X или макет хм.

Теперь предположим, что мы меняем X, чтобы реализовать новый интерфейс Х2. Ну, очевидно, мой код не компилируется. Это требует чего-то, что реализует Х1, и что больше не существует. Проблема была выявлена и могут быть исправлены.

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


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

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

Комментарии (11)

Что's правильное.

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

Модульные тесты не для того, чтобы проверить, что все работает.

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

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

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

и потом, вы'll по-прежнему нужно запускать полная интеграция тестирования на живой (или полу-Живые) системы, чтобы проверить, что он работает с условиями использования.

Комментарии (0)

Ответим на ваши вопросы по очереди:

какое значение имеет модульное тестирование тогда

Они'вновь дешевые для написания и запуска, и вы получите первые отзывы. Если вы ломаете х, вы'll найти более или менее немедленно, если у вас хорошие анализы. Дон'т даже считать, писать интеграционные тесты, Если вы'блок протестировал все слои (да, даже на базе).

это действительно только сказать вам, что, когда все тесты проходят, Вы не'т внесены критические изменения

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

И когда какая-класса'ы изменения поведения (вольно или невольно), как можно обнаружить (желательно в автоматическом режиме) все последствия

Больше тестов - хотя инструменты становятся все лучше и лучше. Но вы должны быть определяющими поведение класса в интерфейс (см. ниже). Б. Н. всегда будет место для ручного тестирования на тестирование пирамида.

должны'т мы ориентируемся больше на тестирование интеграции?

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

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

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

Комментарии (0)

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

М. Е. лучшая стратегия должна иметь хорошее разделение проблем (например, вы можете проверить Часть вашего приложения не принося в части б-з). Такая хорошая архитектура действительно помогает, чтобы написать хороший тест.

Кроме того, я более чем готов принять побочные эффекты, как долго, как я могу свернуть их обратно, например, если моя методика изменяет данные в БД, пусть! Как долго, как я могу бросить дБ обратно в предыдущее состояние, что'ы вред? Кроме того, есть благо, что мой тест можете проверить, если данные выглядят как ожидается. В памяти ДБС или определенные тест-версии ДБО действительно помочь (например RavenDBs в памяти тестовая версия).

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

Комментарии (0)

Модульные тесты не доказать правильность чего-либо. Это верно для всех тестов. Обычно юнит-тесты в сочетании с контрактного проектирования (проектирование по контракту-это еще один способ сказать это) и, возможно, автоматизированные правильность доказательства, если верность должна быть проверена на регулярной основе.

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

Комментарии (4)

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

Тестирование класса и модульного тестирования используются взаимозаменяемо, и они, возможно, должны'т быть. Некоторые модульные тесты просто быть реализован в классах. Вот и все. Модульное тестирование происходило на протяжении десятилетий в языках без классов.

Как для тестирования поведения, вполне можно сделать это в процессе тестирования класса, используя GWT и построить.

Кроме того, есть ли автоматические тесты перейти по классовому или линии поведения, а зависит от ваших приоритетов. Некоторым нужно быстро создать прототип и сделать что-то из двери, в то время как другие будут иметь ограничения покрытия за счет в стилях House. Многим причинам. Они're оба прекрасно действует подходов. Твои деньги-Твой выбор.

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

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

Где тестирование класса выигрывает, где вы должны изменить класс, который еще'т еще не подключены (из-за нехватки времени, сложности или любой другой). Это просто так гораздо проще, чтобы начать работу с классом, если он имеет комплексные испытания.

Комментарии (1)

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

когда вы пишете юнит-тесты для, Вы издеваетесь над х. Другими словами, в то время как модульное тестирование, установить (постулат) поведение х'ы макет должен быть Х1.

В идеале, макет из Х следует моделировать все возможно поведение х, а не только поведение ожидать от X. Поэтому неважно, что вы на самом деле реализовать в X, уже должны быть способны регулировать ее. Так что никаких изменений в X, другие, чем изменяющий интерфейс, будет иметь никакого эффекта на тест Блок А.

Например: предположим, что есть алгоритм сортировки, а также предоставляет данные для сортировки. Макет из Х следует предусмотреть, возвращаемое значение null, пустой список данных, один элемент, несколько элементов уже отсортированы, несколько элементов уже отсортированы, множественные элементы, отсортированные в обратном направлении, списков один и тот же элемент повторяется, нулевые значения смешались, смехотворно большое количество элементов, и она также должна выдать исключение.

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

Комментарии (3)

Вы должны смотреть на различные тесты.

Юнит-тесты сами только тест X. Они предназначены для предотвращения изменения поведения, но не надежности всей системы. Они убедитесь, что вы можете выполнить рефакторинг вы класса, не внося изменения в поведении. И если вы сломать х ты ее сломал...

**** А надо прикалываться Х для модульных тестов и тест с макетом должны держать проходящий даже после его изменения.

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

Также, если X должен иметь новое поведение, было бы лучше поставить новый метод, который будет поставлять желаемому результату

Комментарии (0)