В чем разница между интеграционным и модульным тестами?

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

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

Действительно ли эти тесты стали интеграционными тестами, потому что теперь они проверяют интеграцию этих двух классов, или это просто модульный тест, охватывающий два класса?

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
322
0
54 311
20

Ответы 20

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

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

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

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

Например, если ваши тесты связаны с созданием контента, это модульный тест: если ваш тест касается только записи на диск, это все еще модульный тест, но как только вы проверите как ввод-вывод, так и содержимое файла, тогда у вас есть интеграционный тест. Когда вы тестируете вывод функции внутри службы, это модульный тест, но как только вы выполняете вызов службы и видите, совпадает ли результат функции, то это интеграционный тест.

Технически вы все равно не можете тестировать только один класс. Что, если ваш класс состоит из нескольких других классов? Это автоматически делает его интеграционным тестом? Я так не думаю.

«Технически вы в любом случае не можете проводить модульное тестирование только одного класса. Что, если ваш класс состоит из нескольких других классов?» Что ж, «строгий» модульный тест просто имитирует / заглушает все зависимости. Однако остается спорным, всегда ли это практично ...

sleske 03.10.2010 20:12

Это правда, sieske - важно иметь возможность свести зависимости к абсолютному минимуму.

Jon Limjap 04.10.2010 13:58

-1, модульный тест тестирует не одну функцию, а одну программную функцию или класс, то есть тестирует логическую единицу программного обеспечения.

CharlesB 17.09.2013 21:41

Модульное тестирование - это тестирование с использованием единицы работы или блока кода, если хотите. Обычно выполняется одним разработчиком.

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

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

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

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

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

Немного академический вопрос, не правда ли? ;-) Моя точка зрения: Для меня интеграционный тест - это проверка всей части, а не того, идут ли вместе две части из десяти. Наш интеграционный тест показывает, удастся ли выполнить главную сборку (содержащую 40 проектов). Для проектов у нас есть масса юнит-тестов. Самая важная вещь в отношении модульных тестов для меня - это то, что один модульный тест не должен зависеть от другого модульного теста. Итак, для меня оба теста, которые вы описываете выше, являются модульными, если они независимы. Для интеграционных тестов это не должно быть важным.

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

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

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

Мои 10 бит: D

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

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

Хотя это настоящая подвижная линия ... Я бы предпочел больше сосредоточиться на том, чтобы чертов код работал полностью ^ _ ^

Модульное тестирование - это метод тестирования, который проверяет правильность работы отдельных модулей исходного кода.

Интеграционное тестирование - это этап тестирования программного обеспечения, на котором отдельные программные модули объединяются и тестируются как группа.

Википедия определяет модуль как наименьшую тестируемую часть приложения, которая в Java / C# является методом. Но в вашем примере с классом Word и Sentence я, вероятно, просто написал бы тесты для предложения, поскольку я, вероятно, счел бы излишним использовать класс слов насмехаться для тестирования класса предложения. Таким образом, предложение будет моей единицей, а слово - деталью реализации этой единицы.

Я называю модульными тестами те тесты, которые тестируют по методу белого ящика как класс. Любые зависимости, которые требует класс, заменяются фальшивыми (моковыми).

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

Я бы не стал называть интеграционные тесты контроллера, если одна из их зависимостей не является реальной (т. Е. Не подделкой) (например, IFormsAuthentication).

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

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

Когда я пишу модульные тесты, я ограничиваю объем тестируемого кода классом, который я сейчас пишу, имитируя зависимости. Если я пишу класс Sentence, а Sentence зависит от Word, я буду использовать фиктивное Word. Насмехаясь над Word, я могу сосредоточиться только на его интерфейсе и протестировать различные варианты поведения моего класса Sentence при его взаимодействии с интерфейсом Word. Таким образом, я только тестирую поведение и реализацию предложения, но не тестирую в то же время реализацию Word.

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

Have these tests essentially become integration tests because they now test the integration of these 2 classes? Or is it just a unit test that spans 2 classes?

Я думаю, что да и да. Ваш модульный тест, охватывающий 2 класса, стал интеграционным тестом.

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

Пример реальной разницы может быть следующим 1) Массив из 1000000 элементов легко тестируется и отлично работает. 2) BubbleSort легко тестируется на макетном массиве из 10 элементов, а также отлично работает. 3) Интеграционное тестирование показывает, что что-то не так.

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

Модульные тесты используют макеты

Речь идет о интеграционных тестах, которые фактически проверяют всю интеграцию вашей системы. Но когда вы проводите модульное тестирование, вы должны тестировать каждый модуль отдельно. Над всем остальным надо издеваться. Итак, в вашем случае класса Sentence, если он использует класс Word, тогда ваш класс Word должен быть высмеян. Таким образом, вы только протестируете функциональность своего класса Sentence.

Я знаю, что это старый пост, но я только что наткнулся на него. Что, если бы у вас был третий класс под названием Font, с которым взаимодействует класс Sentence, и вы хотите протестировать функциональность между классом Word и Sentence, тогда вам пришлось бы имитировать класс Font, но это не сделает его модульным тестом. Я говорю о том, что использование mocks не обязательно делает его модульным тестом, mocks также можно использовать в интеграционных тестах.

n.Stenvang 11.12.2014 16:53

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

Robert Koritnik 12.12.2014 01:01

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

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

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

Скажем, у вас есть такой метод:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  Log.TrackTheFactYouDidYourJob();
  return someResults;
}

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

Feature: To be able to do something
  In order to do something
  As someone
  I want the system to do this thing

Scenario: A sample one
  Given this situation
  When I do something
  Then what I get is what I was expecting for

Без сомнения: если тест пройден, вы можете утверждать, что предоставляете работающую функцию. Это то, что вы можете назвать Ценность бизнеса.

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

На практике вы делаете что-то вроде:

public SomeResults DoSomething(someInput) {
  var someResult = [Do your job with someInput];
  FakeAlwaysWorkingLog.TrackTheFactYouDidYourJob(); // Using a mock Log
  return someResults;
}

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

Допустим, в Log.DoSomething() есть ошибка. К счастью, спецификация Gherkin найдет это, и ваши сквозные тесты не пройдут.

Эта функция не будет работать, потому что Log сломан, а не потому, что [Do your job with someInput] не выполняет свою работу. И, кстати, [Do your job with someInput] несет полную ответственность за этот метод.

Также предположим, что Log используется в 100 других функциях, в 100 других методах 100 других классов.

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

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

Тем не менее, модульный тест DoSomething является зеленым, потому что он использует поддельный Log, созданный, чтобы никогда не ломаться. И, да: это явно вранье. Он сообщает, что неработающая функция работает. Чем это может быть полезно?

(Если модульный тест DoSomething() завершится неудачно, убедитесь: в [Do your job with someInput] есть ошибки.)

Предположим, это система с неработающим классом: A system with a broken class

Одна ошибка нарушит работу нескольких функций, а несколько интеграционных тестов не пройдут.

A single bug will break several features, and several integration tests will fail

С другой стороны, та же ошибка нарушит только один модульный тест.

The same bug will break just one unit test

Теперь сравните два сценария.

Эта же ошибка нарушит только один модульный тест.

  • Все ваши функции, использующие сломанный Log, красные
  • Все ваши модульные тесты зеленые, только модульный тест для Log красный

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

Разница

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

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

Вот почему я думаю, что ваше предложение «Или это просто модульный тест, охватывающий 2 класса» как-то смещено. Модульный тест никогда не должен охватывать 2 класса.

Этот ответ в основном является резюме того, что я написал здесь: Модульные тесты врут, поэтому я их люблю.

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

n.Stenvang 11.12.2014 16:19

Отличный ответ! Я просто не совсем согласен с двумя пунктами: 1) что интеграционные тесты «бесполезны в угадывании того, где может быть проблема»; и 2) что «модульный тест никогда не должен охватывать 2 класса». Я создал множество интеграционных тестов, и когда они ломаются, обычно нетрудно определить источник проблемы, при условии, что вы получаете полную трассировку стека или одно неудачное утверждение (в этом случае найти источник может быть труднее, но не столько, сколько интеграционный тест предоставляет ограниченный контекст для отладки). (продолжает)

Rogério 23.04.2015 00:53

Модульные тесты может проверяют несколько классов при условии, что они не являются общедоступными классами, которые должны иметь свои собственные отдельные модульные тесты. Один случай - это когда общедоступный тестируемый класс использует другие непубличные вспомогательные классы, которые существуют только для поддержки общедоступного класса; в этом случае «единица» включает два или более классов. Другой случай состоит в том, что большинство классов используют сторонние классы (класс String / string, классы коллекций и т. д.), Которые не имеют смысла издеваться или изолироваться от них; мы просто рассматриваем их как стабильные и надежные зависимости, выходящие за рамки тестирования.

Rogério 23.04.2015 00:58

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

BornToCode 11.08.2015 18:20

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

user74754 30.08.2016 01:47

Ариалдо Мартини, не уверен, что вы получите уведомление об этом комментарии, поскольку это теперь сообщение вики сообщества, но не могли бы вы предоставить рабочую ссылку на свою статью Модульные тесты врут, поэтому я их люблю. Похоже, что указанная ссылка не работает, но я хотел бы ее прочитать. (Будь ты проклят, StackOverflow, когда ты наконец реализуешь личные сообщения?)

GProst 16.03.2017 12:14

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

Arialdo Martini 25.06.2019 09:06

Интеграционные тесты: проверяется устойчивость базы данных. Модульные тесты: доступ к базе данных имитируется. Кодовые методы протестированы.

На мой взгляд, ответ - "Почему это важно?"

Это потому, что вы делаете юнит-тесты, а интеграционные тесты - нет? Или наоборот? Конечно, нет, вы должны попробовать сделать и то, и другое.

Причина в том, что модульные тесты должны быть быстрыми, изолированными, повторяемыми, самопроверяющимися и своевременными, а интеграционные тесты - нет? Конечно, нет, все тесты должны быть такими.

Это потому, что вы используете mocks в модульных тестах, но не используете их в интеграционных тестах? Конечно, нет. Это означало бы, что если у меня есть полезный интеграционный тест, мне не разрешено добавлять макет для какой-то части, опасаясь, что мне придется переименовать свой тест в «модульный тест» или передать его другому программисту для работы.

Причина в том, что модульные тесты тестируют один модуль, а интеграционные тесты тестируют несколько модулей? Конечно, нет. Какое это практическое значение? Теоретическое обсуждение объема тестов в любом случае не работает на практике, потому что термин «единица» полностью зависит от контекста. На уровне класса единицей может быть метод. На уровне сборки юнит может быть классом, а на уровне обслуживания юнит может быть компонентом. И даже классы используют другие классы, так что это за единица?

Это не имеет значения.

Тестирование важно, F.I.R.S.T. важно, разбивать волосы на определения - пустая трата времени, которая только сбивает с толку новичков в тестировании.

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

CharlesB 22.07.2013 12:48

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

Shane 17.10.2017 21:41

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

Lutz Prechelt 19.03.2018 15:54

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

user924272 12.02.2019 21:47

Кроме того, важно помнить, что как модульные, так и интеграционные тесты можно автоматизировать и писать, например, с использованием JUnit. В интеграционных тестах JUnit можно использовать класс org.junit.Assume для проверки доступности элементов среды (например, подключения к базе данных) или других условий.

Характер ваших тестов

модульный тест модуля X - это тест, который ожидает (и проверяет) проблемы только в модуле X.

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

Подумайте о природе ваших тестов в следующих терминах:

  • Сокращение рисков: Вот для чего нужны тесты. Только комбинация модульных тестов и интеграционных тестов может дать вам полное снижение риска, потому что, с одной стороны, модульные тесты по своей сути не могут тестировать правильное взаимодействие между модулями, а с другой стороны, интеграционные тесты могут реализовать функциональность нетривиального модуля только в небольшой степени.
  • Написание теста: Интеграционные тесты могут сэкономить усилия, потому что тогда вам может не понадобиться писать заглушки / фейки / моки. Но модульные тесты также могут сэкономить усилия, поскольку реализация (и поддержка!) Этих заглушек / фейков / имитаций оказывается проще, чем настройка тестовой установки без них.
  • Задержка выполнения теста: Интеграционные тесты, включающие тяжелые операции (такие как доступ к внешним системам, таким как БД или удаленные серверы), как правило, медленны (э-э). Это означает, что модульные тесты могут выполняться гораздо чаще, что снижает усилия по отладке, если что-то не удается, потому что вы лучше понимаете, что вы изменили за это время. Это становится особенно важным, если вы используете разработку через тестирование (TDD).
  • Усилия по отладке: Если интеграционный тест не прошел, но ни один из модульных тестов не прошел, это может быть очень неудобно, потому что задействовано так много кода, что май содержит проблему. Это не большая проблема, если вы ранее изменили только несколько строк, но поскольку интеграционные тесты выполняются медленно, вы, возможно, запускали их нет с такими короткими интервалами ...

Помните, что интеграционный тест может по-прежнему заглушать / подделывать / имитировать немного своих зависимостей. Это обеспечивает достаточную золотую середину между модульными тестами и системными тестами (наиболее полными интеграционными тестами, тестирующими всю систему).

Прагматический подход к использованию обоих

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

Простое объяснение с аналогиями

Приведенные выше примеры очень хороши, и мне не нужно их повторять. Поэтому я сосредоточусь на примерах, которые помогут вам понять.

Интеграционные тесты

Интеграционные тесты проверяют, все ли работает вместе. Представьте себе, что в часах работают вместе винтики. Интеграционный тест будет выглядеть так: часы показывают правильное время? Он все еще показывает точное время через 3 дня?

Все, что он вам говорит, это то, работает ли вся деталь в целом. Если он терпит неудачу: он не сообщает вам, где именно он терпит неудачу.

Единичные тесты

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

Пример: Давайте подробнее рассмотрим этот момент на примере:

  • Возьмем, к примеру, машину.
  • Интеграция тест для автомобиля: например, машина едет в Вуп Вуп и обратно? Если это произойдет, вы можете с уверенностью сказать, что автомобиль работает с общей точки зрения. Это интеграционный тест. Если он не работает, вы не знаете, где он на самом деле выходит из строя: радиатор, трансмиссия, двигатель или карбюратор? У тебя нет идей. Это могло быть что угодно.
  • Модульный тест для автомобиля: Двигатель работает? Этот тест предполагает, что все остальное в машине работает нормально. Таким образом, если этот конкретный модульный тест завершится неудачно: вы можете быть уверены, что проблема кроется в движке, поэтому вы можете быстро изолировать и исправить проблему.

Использование заглушек

  • Предположим, ваш автомобильный интеграционный тест не прошел. Он не добирается до Эчуки. В чем проблема?

  • Теперь предположим, что в вашем двигателе используется специальная система впрыска топлива, и что этот тест двигателя также не прошел. Другими словами, ни интеграционный тест, ни модульный тест двигателя не дали результата. В чем же тогда проблема? (Дайте себе 10 секунд, чтобы получить ответ.)

  • Проблема в двигателе или в системе впрыска топлива?

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

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

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

В модульном тесте вы тестируете каждую изолированную часть:

в интеграционном тесте вы тестируете многие модули своей системы:

и вот что происходит, когда вы используете только модульные тесты (обычно оба окна работают, к сожалению, не вместе):

Источники: источник1источник2

У вас есть три изображения, но только два источника.

gerrit 05.12.2019 19:47

@gerrit загляните в первый источник - две картинки оттуда

Michu93 06.12.2019 11:04

Люблю этот ответ ?

Dzenis H. 02.04.2020 22:06

Другие вопросы по теме