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

Где должны проводиться модульные тесты?

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

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

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

EDIT: Для тех, кто интересуется конкретным языком, я в основном работаю на Java. Тем не менее, я бы хотел найти решение, относительно языковое агностическое, чтобы я мог применять его независимо от того, на какой платформе я работаю.

4b9b3361

Ответ 1

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

Вы всегда можете фильтровать классы на основе некоторого соглашения об именах, например, специального суффикса или префикса при упаковке (например, не включать **/*Test.class с Java). Мне не нравится этот подход, хотя я нахожу его грязным и хрупким.

для второго, как бы вы протестировали функциональность, которая видна только на уровне пакета?

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

  • src/main/java для источников приложений
    • src/main/java/foo/Bar.java
  • src/test/java для источников тестов
    • src/test/java/foo/BarTest.java

Оба Bar.java и BarTest.java находятся в одном пакете foo, но в разных каталогах. Это подход, который я использую.

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

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

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

Ответ 2

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

Ответ 3

Вы не указываете используемую платформу и инструменты и которые влияют на параметры. Я отвечаю с точки зрения .NET и Visual Studio:

Моя команда (работающая над довольно крупным проектом) успешно применила подход к размещению кода и тестов вместе. Для данного (вспомогательного) пространства имен в решении есть папка "_Test" внутри этого (вспомогательного) пространства имен ( "_" - это взлом, чтобы заставить Visual Studio отображать его выше всего остального в этом пространстве имен в браузере решений).

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

Что имеет смысл, когда вы об этом думаете. Код и тест принадлежат друг другу, как инь и ян. Это также означает, что при изменении типов в 1 сборке необходимо перестроить только 1 сборку (у нас есть более 30 проектов в нашем решении, поэтому это позволяет нам безопасно уйти с Build Current Project только при разработке класса через TDD, что намного быстрее, чем полная сборка решений).

Наличие кода и тестов вместе также решает проблему проверки внутренних классов. Однако на платформе .NET вы также можете использовать атрибут уровня InternalsVisibleTo Assembly для предоставления доступа к отдельной тестовой сборке, если вы хотите, чтобы все было в порядке.

Единственная причина, по которой я могу видеть тесты в отдельной сборке, - это не отправлять этот код. Однако этот аспект тривиально решается по-другому, если вы используете автоматизацию построения. Поскольку файлы проектов Visual Studio являются XML, у нас просто есть сервер сборки, предварительно обрабатывающий файлы проекта, используя небольшой XSLT, чтобы разделить все в папке */_ Test/* из компиляции в версиях выпуска.

Ответ 4

Я предлагаю вам иметь отдельный проект (или проекты) для ваших модульных тестов.

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

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

Ответ 5

Вероятно, это зависит от того, что вы сейчас используете. С визуальной студией /.net обычная практика, похоже, является тестовой dll для каждой производственной dll и неопределенным зеркалированием классов и тестовых классов в DLL. Для ruby ​​/python и т.д. - отдельный тестовый каталог и внутри него - иерархия, которая отражает проверяемые вещи.

Что вы подразумеваете под "извлечением" этих тестов? Для вас полная сборка связана с компиляцией и запуском тестов или нет?

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

Ответ 6

Что такое тест и что такое приложение?

Давайте подумаем о том, как тест вписывается в изображение...

  • Тест не применим непосредственно к чему-либо, что касается общественности - они просто хотят, чтобы он работал.
  • Тест для разработчиков и обычно бизнес
  • Тесты могут быть в том же масштабе, что и модули, но находятся в дихотомическом расположении
  • Если тестовые файлы могут существовать бок о бок с его модулем в данной инкапсулирующей структуре, то логически - в фрактальной архитектуре - часть теста также должна быть распределена по шкале объекта в пределах данного модуля. (Think, directory | _file | _module | _object - где system == component && component == system && (system == system || system == subsystem ))

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

Однако спецификация приложения может радикально изменить, какие у вас есть параметры...

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

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

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

Как правило, используйте стандартные леса:

/app
    |-lib
    |-src
    |-test

.. вы, вероятно, не ошибетесь.