Java-модульные тесты, макет каталога
При создании набора модульных тестов для Java-кода существует ли соглашение о том, где разместить тестовый код относительно исходного кода?
Например, если у меня есть каталог /java
, который содержит пучку .java
исходных файлов, лучше ли разместить тестовые примеры в /java
или использовать что-то вроде /java/test
.
Если последнее предпочтительнее, как вы проверяете внутренности кода, когда члены класса private
/protected
недоступны вне пакета?
Ответы
Ответ 1
Вы можете поместить тесты в тот же пакет, что и исходные классы, даже если исходный код находится под собственным корнем каталога:
PROJECT_ROOT
+--- src/
+----test/
Вы можете объявить класс com.foo.MyClass
под src
и его тест com.foo.MyClassTest
в разделе test
.
Что касается доступа к закрытым членам, вы можете использовать отражение, чтобы вызвать методы (изменяя их доступность через Class.getDeclaredMethod.setAccessible
), или вы можете использовать что-то вроде testng/junit5, чтобы добавить некоторые аннотации тесты на самом исходном коде (я лично считаю, что это плохая идея).
Почему бы не проверить некоторые проекты на java.net
, чтобы увидеть, как они организовали вещи, например swinglabs (боюсь, хранилище SVN довольно медленно)?
Ответ 2
Я рекомендую следовать стандартной структуре каталогов Apache Software Foundation, которая дает следующее:
module/
src/
main/
java/
test/
java/
Это позволяет проводить тесты отдельно от источника, но на том же уровне в структуре каталогов. Если вы прочитаете, как Apache определяет их структуру, вы увидите, что он также помогает разделить другие проблемы, включая ресурсы, конфигурационные файлы, другие языки и т.д.
Эта структура также позволяет модульные тесты тестировать пакеты и методы защищенного уровня тестируемых устройств, предполагая, что вы размещаете тестовые примеры в том же пакете, что и те, которые они тестируют. Что касается тестирования частных методов - я бы не стал беспокоиться. Что-то еще, либо публичное, либо пакетное, либо защищенное, называет их, и вы должны иметь возможность получить полное тестовое покрытие, проверяющее эти вещи.
Кстати, ссылка выше - это инструмент Maven, Apache для стандартной сборки. Каждый проект Java, который они соответствуют этому стандарту, а также каждый проект, с которым я столкнулся, построен с помощью Maven.
Ответ 3
В большинстве случаев это делается следующим образом:
<SOME_DIR>/project/src/com/foo/Application.java
<SOME_DIR>/project/test/com/foo/ApplicationTest.java
Итак, вы их разделяете, и вы все еще можете проверить функциональность пакета/защиты, потому что тест находится в одном пакете.
Вы не можете проверять личные вещи, если они не объявлены внутри класса.
При доставке вы просто упаковываете .class
, сгенерированный с помощью src, а не тесты
Ответ 4
На самом деле имеет смысл разделить ваши проекты Production и Test на 2 отдельных объекта, но иметь одинаковые структуры пакетов в обоих проектах.
Итак, если у меня есть проект "my-project", я также создаю "my-project-test", поэтому у меня есть следующая структура каталогов:
my-project
+--- src/com/foo
my-project-test
+---test/com/foo
Этот подход гарантирует, что зависимости тестового кода не загрязняют производственный код.
По моему личному мнению, следует проверять и частные методы защиты пакетов, а также общедоступные методы. Поэтому я хочу, чтобы мои тестовые классы были в том же пакете, что и производственные классы.
Ответ 5
Вот как мы его настроили, и нам это нравится.
build/
src/
test/build/
test/src/
Весь тестовый код компилируется в свой собственный каталог сборки. Это связано с тем, что мы не хотим, чтобы производство содержало тестовые классы по ошибке.
Ответ 6
При создании модуля Java library в Android Studio он создает класс по умолчанию под:
[module]
+ src/main/java/[com/foo/bar]
Если вы посмотрите в файл [module].iml
, вы найдете этот путь, а также путь для тестов, который вы можете использовать. Ниже приведен итог:
<module>
<component>
<content>
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
</content>
</component>
</module>
Что вы можете сделать, в частности, создать каталог для тестов, чтобы иметь следующую структуру:
[module]
+ src/main/java/[com/foo/bar]
+ src/test/java/[com/foo/bar]
Вышеупомянутая структура будет распознана Android Studio, и ваши файлы под ней будут включены в модуль.
Я предполагаю, что эта структура является рекомендуемым макетом для кода и тестов.