Тестовое задание Gradle - Gradle 1.6 и Gradle 2.3 или новее

У меня есть проект Java.

PS: В моем проекте у меня нет java-программы / исходного кода в src/test/java.
- Эта папка просто содержит пустой файл.txt.

У меня есть две разные версии Gradle:

  1. Gradle 1.6 с Java 7 (поскольку Java 8 НЕ совместима с Gradle 1.6 или любой версией <версии ниже 1.10, если я прав).

  2. Другая версия: 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
Другие вопросы по тегам