Тестовое задание Gradle - Gradle 1.6 и Gradle 2.3 или новее
У меня есть проект Java.
PS: В моем проекте у меня нет java-программы / исходного кода в src/test/java.
- Эта папка просто содержит пустой файл.txt.
У меня есть две разные версии Gradle:
Gradle 1.6 с Java 7 (поскольку Java 8 НЕ совместима с Gradle 1.6 или любой версией <версии ниже 1.10, если я прав).
Другая версия: Gradle 2.3 с Java 8.
Используя обе вышеупомянутые версии Gradle 1.6 + Java7 ИЛИ Gradle 2.3 + Java 8, мой проект успешно собран.
Однако я заметил одну вещь: при запуске сборки она автоматически вызывает "тестовую" задачу (в соответствии с дизайном Gradle тестовая задача запускается бесплатно); Я нашел во время Gradle 1.6 + Java7 run --- я вижу следующий вывод.
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources
:testClasses
:test
:check
Как вы заметите, он говорит, что у меня нет никакого тестового исходного кода (то есть src/test/java не содержит никакого исходного кода ИЛИ нет ничего нового для Gradle, чтобы скомпилировать на этот раз, возможно, ничего не изменилось с момента последнего запуска gradle сборка), и именно поэтому задача compileTestJava показывает перед ней ОБНОВЛЕНИЕ.
Но : тестовое задание показывает, что оно успешно выполнено. Я использовал раздел jacoco (покрытие кода) в задании test {..}, затем он фактически выполнил эту часть (поскольку перед тестовым заданием нет UP-TO-DATE). Раздел Jacoco НЕ определен в build.gradle моего проекта, но на самом деле он взят из файла верхнего уровня / GRADLE_HOME/init.d/some-common-top-level.gradle (где test { ... has jacoco { ... } .. } раздел в нем).
Как я упоминал выше,тестовое задание не показывало UP-TO-DATE, поэтому после завершения процесса сборки Gradle я вижу, что оно создало следующую структуру папок / файлов внутри build/tmp/extendedArchives/org.jacoco... папка
$ ls -ltr build/tmp/expandedArchives/
total 4
drwxr-xr-x+ 1 e020001 Domain Users 0 Jul 7 20:45 org.jacoco.agent-0.7.2.201409121644.jar_778m6tp3jrtvcetasufl59dmau
$ ls -ltr build/tmp/expandedArchives/org.jacoco.agent-0.7.2.201409121644.jar_778m6tp3jrtvcetasufl59dmau/
total 272
drwxr-xr-x+ 1 e020001 Domain Users 0 Jul 7 20:58 META-INF
-rwxr-xr-x 1 e020001 Domain Users 2652 Jul 7 20:58 about.html
-rwxr-xr-x 1 e020001 Domain Users 272311 Jul 7 20:58 jacocoagent.jar
drwxr-xr-x+ 1 e020001 Domain Users 0 Jul 7 20:58 org
Этого не происходит, когда я использую Gradle 2.3 и Java8.
Сборка прошла успешно, но я не получаю папку build/tmp/extendedArchives/org.jacoco...., содержащую файл jacocoagent.jar.
Любая идея, почему Gradle 2.3 не создает этот специфичный для jacoco файл.jar.
В Gradle 2.3 + Java8 следующий вывод показывает UP-TO-DATE перед обоими :compileTestJava и : тестовые задачи (чего не было в Gradle 1.6 для тестовой задачи).
Я побежал " Gradle чистой сборки".
:compileTestJava UP-TO-DATE
:compileTestGroovy UP-TO-DATE
:processTestResources
:testClasses
:test UP-TO-DATE
:check
Мне нужен Gradle 2.3, чтобы сгенерировать этот jacocoagent.jar в папке build/tmp/extendedArchives/org.jacoco....., чтобы я мог использовать его в последующем задании Jenkins (которое запускает не-модульные тесты), так как этот проект имеет некоторые интеграционные тесты, и я извлекаю jacocoagent.jar из родительского основного задания сборки (которое запускаетчистую сборку, включая тестовое задание) в последующем задании, чтобы я мог передать его в TOMCAT JVM при запуске Tomcat (чтобы я мог получить jacocoIT.exec покрытие кода для ИТ-тестов). Но после того, как я переключился на Gradle 2.3, все проекты, в которых у меня нет src/test/java ... теперь jacocoagent.jar не создается, и плагин копирования артефактов завершается неудачно при попытке скопировать файл.jar из родительского задания.,
Еще один момент:
В Gradle 1.6 + Java7, если я запускаюgradle clean build, он успешно создает этот jacocoagent.jar в папке build/tmp/extendedArchives/org.jacoco....., но это работает таким образом, только когда я запускаю gradle clean build или " Gradle Clean; Gradle Test ".
Если я запускаю gradle clean build, затем удаляю папку build / tmp, а теперь просто запускаю:gradle test, он показывает мне UP-TO-DATE перед обоими :compileTestJava и :test задачи и не создает build / tmp / папка extendedArchives/org.jacoco...., содержащая файл jacocoagent.jar.
Для получения дополнительной информации я прикрепляю запуск профиля (т.Е. С помощью параметра --profile) при выполнении задачи тестирования gradle для Gradle 1.6 + Java 7.
Я вижу, что в html- файле профиля при запуске тестового задания он сначала вызывает compileJava в соответствии с логикой процесса Gradle, а затем тестовое задание, а также вызывает зависимости --- : jacocoAgent (согласно вкладке разрешения зависимостей):
Но,
в Gradle 2.3 + Java8 шаг разрешения / порядка зависимости и шаг выполнения задачи не совпадают (или в порядке по сравнению с Gradle 1.6) для генерации или отображения какой-либо ссылки на зависимость jacocoAgent, поскольку она даже не вызывает ее.
Запуск тестового задания Gradle1.6 + Java7 с параметром -i (или --info) показывает, почему он выполнял тестовое задание, хотя у меня не было тестового исходного кода, см. Причину:
Note: Recompile with -Xlint:unchecked for details.
:processResources
Skipping task ':processResources' as it has no source files.
:processResources UP-TO-DATE
:classes
Skipping task ':classes' as it has no actions.
:compileTestJava
Skipping task ':compileTestJava' as it has no source files.
:compileTestJava UP-TO-DATE
:processTestResources
Executing task ':processTestResources' due to:
No history is available.
:testClasses
Skipping task ':testClasses' as it has no actions.
:test
file or directory '/my/workspace/project/build/classes/test', not found
Executing task ':test' due to:
No history is available.
file or directory '/my/workspace/project/build/classes/test', not found
Finished generating test XML results (0.001 secs)
Generating HTML test report...
Finished generating test html results (0.012 secs)
BUILD SUCCESSFUL
2 ответа
Резюме:
В Gradle 2.3, если нет действительного тестового кода.java/.groovy (или др.), Тестовое задание даже не запустится, и, следовательно, не будет никакого jacocoagent.jar, созданного где-то глубоко в build/tmp/exapandedArchives/org.jacoco.xxx.... папка.
Решением было включить следующее (в верхнем уровне $GRADLE_HOME/init.d/some-global-file.gradle) в раздел allprojects { .... }. Все, что мы делаем, - это если у src/test/java (стандарт) или какой-либо устаревшей структуры папок (src / java, если структура вашего проекта такая) нет допустимого исходного кода теста, тогда мы можем добавить фиктивный тестовый файл (DummyTestXYZ.java или groovy) и запустите тестовое задание, которое сгенерирует jacocoagent.jar (который мы можем использовать / tie в опциях Tomcat для генерации отчета jacoco для неединичных интегральных тестов). Таким образом, если ваше основное задание сборки вызывает нижестоящее / дочернее задание для выполнения ваших ИТ-тестов, оно не завершится с ошибкой, поскольку может извлечь jacocoagent.jar (из рабочей области основного задания сборки), так как тестовое задание создаст jacocoagent.jar в build / Папка tmp / extendedArchives/org.jacoco.xx.x.xx..x (которую можно получить с помощью плагина Copy Artifact в Jenkins).
PS: изменить логику оператора if в соотв. в настройках вашей собственной папки, т.е. в какой папке вы хотите создать файл DummyTestXYZ.java. В нашем случае во всех новых проектах использовалась src/test/java (стандартная структура папок в соответствии со стандартом Maven/Gradle), и во время создания нового проекта мы добавляем проверенные тестовые модульные тесты, зарегистрированные в системе контроля версий. Таким образом, в приведенной ниже логике мы фактически игнорируем создание этого DummyTestXYZ.java в случае, если существует src / test / java, и создаем этот файл, только если папка src / test / java не существует в проекте (т. Е. Это проект который имеет унаследованную структуру папок) + test/java (унаследованная папка для хранения модульных тестов JUnit) не имеет программ.java и / или, если test / java не существует, сначала создайте его, а затем создайте фиктивный файл. Я знаю, что мы могли бы загрузить jacocoagent.jar в каком-то месте на сервере Jenkins и использовать этот файл при запуске Tomcat для получения покрытия кода для ИТ-тестов. Для добавления фиктивного тестового файла, который мы добавили, требуется библиотека библиотеки junit:junit:4.10 или 4.11, чтобы задача:compileTestJava успешно выполнялась.
compileJava {
doLast {
def dirName = "${projectDir}/test/java"
if(!file( "${projectDir}/src/test/java" ).exists())
if(!file( dirName ).exists())
new File( dirName ).mkdirs()
if(file( dirName ).exists()) {
def javaCnt = new FileNameByRegexFinder().getFileNames(dirName, /.*\.java/).size()
if(javaCnt == 0) {
def f = new File( dirName , 'DummyTestXYZ.java' )
def w = f.newPrintWriter()
w.println('import org.junit.Test;')
w.println('')
w.println('public class DummyTestXYZ {')
w.println('@Test' )
w.println('public void test() {')
w.println('}')
w.println('}')
w.close()
}
}
}
}
test {
doFirst {
testResultsDirName = "test-results/UT"
testReportDirName = "tests/UT"
}
maxParallelForks = 5
forkEvery = 50
//ignoreFailures = true
// Following Jacoco section is required only in Jenkins
// But a developer can uncomment them if they want this feature to work for their
// Desktop local Gradle builds.
jacoco {
//Following vars works only with versions >= 1.7 version of Gradle
destinationFile = file("$buildDir/jacoco/UT/jacocoUT.exec")
}
doLast {
if (file("${projectDir}/test/java/DummyTestXYZ.java").exists()) {
println "++"
println "++"
println "++"
println "======================================================="
println "DEV Team – Please add valid Unit tests in this project."
println "======================================================="
println "++"
println "++"
println "++"
sleep(30 * 1000)
new File("${projectDir}/build/classes/test").deleteDir()
new File("${buildDir}/jacoco/UT").deleteDir()
new File("${buildDir}/test-results/UT").deleteDir()
delete "${projectDir}/test/java/DummyTestXYZ.java"
}
}
}
//Do the same (as above test code) for any other similar test tasks like integartionTest, acceptanceTest etc..
jacocoTestReport {
//cleaning any compile time generated (for ex: JiBx classes files) so that jacoco task won't fail for not finding the actual source files (.java/.groovy for the compile time generated .class files)
doFirst {
delete fileTree (dir: "${buildDir}/classes", include: "**/JiBX_*.class")
}
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
//ignoreFailures = true
executionData = fileTree(dir: 'build/jacoco', include: '**/*.exec')
reports {
xml{
enabled true
//Following value is a file
destination "${buildDir}/reports/jacoco/xml/jacoco.xml"
}
csv.enabled false
html{
enabled true
//Following value is a folder
destination "${buildDir}/reports/jacoco/html"
}
}
sourceDirectories = files(['src/java','src/main/java', 'src/main/groovy'])
classDirectories = files('build/classes/main')
doLast {
if (file("${projectDir}/test/java/DummyTestXYZ.java").exists()) {
delete "${projectDir}/test/java/DummyTestXYZ.java"
}
}
}
Вы можете принудительно выполнить тестовое задание независимо от состояния входов и выходов:
test{
outputs.upToDateWhen{false}
}
для более ранних версий Gradle вы можете убедиться, что каталог классов существует
task createTestClassesDir << {sourceSets.test.output.classesDir.mkdirs()}
test.dependsOn createTestClassesDir