Существует ли тип логических ошибок / ошибок потока, которые не могут быть обнаружены в модульных тестах? - PullRequest
0 голосов
/ 26 апреля 2018

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

class Engine
{
   int RPM;

   void SetRPMtoZero()
   {
      RPM=0;
   }
}

class Display
{
  CalculateAverage(Engine e)
  {
    if (e.IsRunning)
    {
      int X=smth/e.RPM;  //could be division by 0
    }
  }
}

class IntegratingClass
{
  Engine e
  Display d..

  ...

  e.SetRPMtoZero();
  d.CalculateAverage(e);

  //this sequence would lead to the division by zero

}

Я не думаю, что это показывает ошибку интеграции - у CalculateAverage просто отсутствует проверка RPM! = 0.

Существует ли тип логических ошибок (или потока управления), которые не могут быть обнаружены при модульном тестировании?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Я согласен с вами, что в данном примере речь идет о пропущенном модульном тесте для класса Display.

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

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

  • Даже на первом этапе интеграционного теста - сама интеграция (например, связывание модулей вместе, если мы говорим о языке, подобном c ++), может потерпеть неудачу, если интерфейс был изменен в одном устройстве, но не адаптирован соответствующим образом в других устройствах.
  • Если устройства используют общие ресурсы (например, файл, память), резервирование / освобождение ресурса может привести к заблокированным состояниям или повреждению данных.
  • Если вы покрываете исходный код модуля по модульному тесту на 100%, это не означает, что весь код действительно необходим. По интеграции На уровне вы можете понять, что существует много кода, который даже не может быть достигнут при объединении модулей. Это может помочь вам выяснить, какие части вашего кода, вероятно, являются "мертвым кодом".
  • Ограничения производительности или ограничения ресурсов (например, ограниченная память)
  • Неверное толкование договора или ошибки в его исполнении
0 голосов
/ 30 апреля 2018

Интересный вопрос. Это глупо с одной стороны. Ясно, что должна быть какая-то логика, которую нельзя обнаружить с помощью модульного тестирования, иначе модульное тестирование будет Oracle of Delphi.

Я думаю, что важным философским соображением здесь является концепция ЧРЕЗВЫЧАЙНОЙ СЛОЖНОСТИ. Многие мыслители указывали на это в прошлом. Закон Мура, вероятно, является лучшим примером [сложность транзисторов удваивается примерно каждые 2,5 года]. Но это общий принцип.

Итак, чтобы абстрагировать закон возникающей сложности для тестирования программного обеспечения: будут ли 5 ​​единиц программного обеспечения более, одинаковыми или менее сложными по отдельности или более сложными вместе? Когда вы говорите так, очевидно, что 5 единиц, работающих вместе, ДОЛЖНЫ быть более сложными, чем отдельные блоки по отдельности. Это известно как «Больше, чем сумма его частей» и является общим правилом для систем.

...