Где должны жить юнит-тесты?

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

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

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

РЕДАКТИРОВАТЬ: Для тех, кто интересуется конкретным языком, я в основном работаю на Java. Тем не менее, я хотел бы найти решение, которое относительно не зависит от языка, поэтому я могу применять его независимо от того, на какой платформе я работаю.

20
задан derekerdmann 9 August 2016 в 18:58
поделиться

5 ответов

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

Вы всегда можете фильтровать классы на основе некоторого соглашения об именах, например специального суффикса или префикса, когда упаковка (например, не включайте ** / * 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 (см. Введение в стандартный макет каталога ). Какой бы язык вы ни использовали, это может дать вам некоторые идеи.

4
ответ дан 30 November 2019 в 01:18
поделиться

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

5
ответ дан 30 November 2019 в 01:18
поделиться

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

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

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

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

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

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

5
ответ дан 30 November 2019 в 01:18
поделиться

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

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

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

1
ответ дан 30 November 2019 в 01:18
поделиться

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

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

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

1
ответ дан 30 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: