Как проверить скомпилированный JAR-файл с помощью Gradle - PullRequest
0 голосов
/ 03 июля 2019

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

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

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

Некоторые подробности о проекте - простая библиотека Java с несколькими классами, использующая Gradle 5.5 в качестве системы сборки и travis-ci в качестве инструмента CI / CD, для тестирования я использую TestNG, но я могу легко переключиться на JUnit, если он потребуется.

Если вам интересно, какой код не работал, когда он был скомпилирован в пакет, вот упрощенная версия:

public String readResourceByURI() throws IOException, URISyntaxException
{
  new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemClassLoader().getResource("resource.txt").toURI())));
}

Эта функция генерирует исключение java.nio.file.FileSystemNotFoundException, если оно упаковано в файл jar. Но, как я уже сказал, проблема не в коде ...

В идеале я хочу создать конвейер сборки, который будет генерировать артефакты jar, которые затем будут проверены, и если тесты пройдут успешно, эти jar будут автоматически развернуты в хранилище (maven и / или bintray).

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

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

Ответы [ 3 ]

0 голосов
/ 03 июля 2019

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

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

Вы должны спросить себя, достаточно ли потенциальных ошибок такого рода, чтобы оправдать это:

  • Я не думаю, что вы скоро совершите эту ошибку снова.
  • Другие проблемы такого рода могут включать предположения в вашей библиотеке о платформе ОС или (иногда) версиях Java ... которые действительно могут быть протестированы только при запуске приложения на разных платформах.

Может быть, прагматичный ответ - признать, что вы не можете (или не можете себе позволить) проверить все.


Сказав это, одним из возможных подходов может быть выбор автономного тестового прогона (упакованного как Java-приложение без графического интерфейса). Затем попросите Gradle запустить тестовый прогон в виде скриптовой задачи с JAR-файлами для вашей библиотеки и модульными тестами на пути к классам.

0 голосов
/ 04 июля 2019

Вот что я придумал:

test {

    // Add dependency on jar task, since it will be main target for testing
    dependsOn jar

    // Rearrange test classpath, add compiled JAR instead of main classes
    classpath = project.sourceSets.test.output + configurations.testRuntimeClasspath + files(jar.archiveFile)

    useTestNG()
}

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

0 голосов
/ 03 июля 2019

В Gradle вы можете попытаться выполнить некоторую задачу скриптинга, которая запускает код из вашего jar. Или сложный, но на простом POC это работает. В основном проекте Gradle создайте подпроект 'child'. Добавьте информацию об этом в settings.gradle:

include 'child'

В build.gradle добавьте это:

task externalTest {
    copy {
        from 'src/test'
        into './child/src/test'
    }
}
externalTest.dependsOn(':child:build')

jar.doLast {
    externalTest
}

А в child / settings.gradle в зависимости добавьте родительский jar:

compile files('../build/libs/parent.jar')

Теперь в основном проекте по сборке, дочерний проект будет собран после создания jar.

...