Фільтруйте звіти про покриття JaCoCo за допомогою Gradle


113

Проблема:

У мене є проект с і я хочу мати можливість фільтрувати певні класи та / або пакети.

Супутня документація:

Я прочитав таку документацію:

Офіційна сайт: http://www.eclemma.org/jacoco/index.html

Офіційна документи для : https://gradle.org/docs/current/userguide/jacoco_plugin.html

Офіційна Githubпитань, працюючи над висвітленням: https://github.com/jacoco/jacoco/wiki/FilteringOptions https://github.com/jacoco/jacoco/isissue/14

Пов'язані посилання StackOverflow:

JaCoCo & Gradle - Параметри фільтрації (немає відповіді)

Виключіть пакунки зі звіту Якоко за допомогою Sonarrunner та Gradle (Не використовується)

JaCoCo - виключити JSP із звіту (здається, він працює для, Я використовую )

Конфігурація Maven Jacoco - Виключіть класи / пакети із звіту, які не працюють (це, здається, працює для, Я використовую )

Плагін JaCoCo gradle виключити (не вдалося це зробити)

Gradle Jacoco - звіти про охоплення включають класи, виключені в конфігурації (здається, дуже близько, він використовувався doFirst, не працював для мене)

Приклад того, що я спробував:

apply plugin: 'java'
apply plugin: 'jacoco'

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }
}

repositories {
    jcenter()
}

jacocoTestReport {
    reports {
        xml {
            enabled true // coveralls plugin depends on xml format report
        }

        html {
            enabled true
        }
    }

    test {
        jacoco {
            destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
            classDumpFile = file("$buildDir/jacoco/classpathdumps")
            excludes = ["projecteuler/**"] // <-- does not work
            // excludes = ["projecteuler"]
        }
    }
}

Питання:

Як я можу виключити певні пакети та класи при генерації звіти про покриття?


Варіант третьої сторони (FD Я засновник): Якщо ви завантажуєте звіти в Codecov, ви можете ігнорувати будь-які файли, які вам подобаються після факту, у розділі функцій продукту. Дякую.
Стів Пік

@StevePeak Отже, ви можете фільтрувати, packagesвикористовуючи Інтернет Codecov? Крім того, я бачив те Github, що про Androidпідтримку, я бачив Java. Мені все одно доведеться надсилати всі звіти, після чого фільтрувати після фільтрації проти.
Джаред Берроуз

Ви можете фільтрувати на основі методу regexp будь-якого поданого файлу, який ви не хочете включати. Усі Java підтримуються через звіти Jacoco. Просто фільтрування після факту на Codecov працює. Він запам'ятає ваші фільтри та застосує їх до всіх майбутніх звітів. Дякую!
Стів Пік

6
Мені цікаво; що робить excludesз офіційної документації на насправді робити те? Це в значній мірі марно?
Вівін Паліаф

Це excludesстосується не завдання покриття, а тестового завдання. Це виключає, що файли не підлягають інструментам JaCoCo і таким чином записуються покриття. Ви можете використовувати це, якщо ви не хочете записувати покриття для деяких класів, якщо ви не можете через конфлікт з іншим інструментом приладів або через попередні інструментальні класи. Це не виключає клас із звіту, особливо в останньому згаданому випадку, це було б жахливою ідеєю.
Вампір

Відповіді:


115

Завдяки Yannick Welsch:

Після пошуку в Google, читання документів Gradle та перегляду старих публікацій StackOverflow я знайшов цю відповідь на Офіційному форуми!

jacocoTestReport {
    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/blah/**')
        })
    }
}

Джерело: https://isissue.gradle.org/browse/GRADLE-2955

Моє рішення build.gradleдля проектів Java / Groovy:

apply plugin: 'java'
apply plugin: 'jacoco'

jacocoTestReport {
    reports {
        xml {
            enabled true // coveralls plugin depends on xml format report
        }

        html {
            enabled true
        }
    }

    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: ['codeeval/**',
                              'crackingthecode/part3knowledgebased/**',
                              '**/Chapter7ObjectOrientedDesign**',
                              '**/Chapter11Testing**',
                              '**/Chapter12SystemDesignAndMemoryLimits**',
                              'projecteuler/**'])
        })
    }
}

Як бачите, мені вдалося додати більше exclude:, щоб відфільтрувати кілька пакетів.

Джерело: https://github.com/jaredsburrows/CS-Interview-Questions/blob/master/build.gradle

Спеціальні завдання для інших проектів, таких як Android:

apply plugin: 'jacoco'

task jacocoReport(type: JacocoReport) {
    reports {
        xml {
            enabled true // coveralls plugin depends on xml format report
        }

        html {
            enabled true
        }
    }

    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: ['codeeval/**',
                              'crackingthecode/part3knowledgebased/**',
                              '**/Chapter7ObjectOrientedDesign**',
                              '**/Chapter11Testing**',
                              '**/Chapter12SystemDesignAndMemoryLimits**',
                              'projecteuler/**'])
        })
    }
}

Джерело: https://github.com/jaredsburrows/android-gradle-java-app-template/blob/master/gradle/quality.gradle#L59


1
@BradPitcher Немає проблем! Мені знадобився певний час, щоб знайти правильну відповідь. Це просто здається таким "хакітським". Я сподіваюся, що вони придумають приємніший спосіб.
Джаред Берроуз

Отже, який правильний підхід, якщо я просто хочу виключити один клас із пакета?
Педро Анріке

2
Щось на кшталт:exclude: ['**/*Test*.*'])
Джаред Берроуз

1
jacocoTestReportпрацює лише з обома jacocoта javaплагінами. Це не для Android. Будь ласка, дивіться мою репо тут для android: github.com/jaredsburrows/android-gradle-java-template/blob/…
Джаред Берроуз

9
У classDirectories =результатах цього попередження. The JacocoReportBase.setClassDirectories(FileCollection) method has been deprecated. This is scheduled to be removed in Gradle 6.0. Use getClassDirectories().from(...). Було б чудово показати рішення, сумісне з Gradle 6.0.
Thunderforge

61

Для Gradle версії 5.x classDirectories = files(...)подає попередження про депресію і зовсім не працює, починаючи з Gradle 6.0. Це неперевірений спосіб виключення класів:

jacocoTestReport {
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it, exclude: 'com/exclude/**')
        }))
    }
}

2
Або просто скористайтеся classDirectories.from (щоб додати до списку замість переліку списків)
Mohamed El-Beltagy

1
Ви додасте []після exclude: включення декількох шляхів.
WesternGun

Чудово, я використовую gradle 6.0.1, і це рішення працювало на мене.
Дарген

14

для мене це прекрасно працювати

test {
  jacoco {
    excludes += ['codeeval/**',
                 'crackingthecode/part3knowledgebased/**',
                 '**/Chapter7ObjectOrientedDesign**',
                 '**/Chapter11Testing**',
                 '**/Chapter12SystemDesignAndMemoryLimits**',
                 'projecteuler/**']
  }
}

як зазначено в документації https://docs.gradle.org/current/userguide/jacoco_plugin.html#N16E62 і спочатку запитується, тому відповідь така:

тож якщо ви запитаєте мене: це не питання

excludes = ["projecteuler/**"]

або

excludes += ["projecteuler/**"]

але

excludes = ["**/projecteuler/**"]

виключити пакет *.projecteuler.*

і test {}на рівні проекту, не вкладеного вjacocoTestReport


1
Це, здається, дає класам 0% охоплення, а не взагалі їх опускає. Я використовую JaCoCi 0.8.5 та Gradle 6.0
tschumann

Це правильний спосіб сказати jacoco не втручатися в деякі класи, інші підходи впливають лише на частину звіту.
Бріс

9

Для Gradle6 Використовуйте щось на кшталт нижче, оскільки вони зроблені classDirectories as final, ми не можемо перепризначити його, але існує метод сеттера, classDirectories.setFromякий можна використовувати

    jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled true
        html.destination file("$buildDir/reports/jacoco")
    }

    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: ['**/server/**',
                              '**/model/**',
                              '**/command/**'
                    ]
            )
        }))
    }
}

6

Ось вирішення цієї проблеми в ANT. Це можна адаптувати до градуля, додавши в jacocoTestReportзавдання наступне . Хоча насправді це не документально підтверджено компанією jacoco, це здається єдиним способом фільтрації результатів тестів.

afterEvaluate {
    classDirectories = files(classDirectories.files.collect {
        fileTree(dir: it, exclude: 'excluded/files/**')
    })
}

Добре, дякую, що підтвердили, що мої висновки є правильними! Я сподіваюся, що вони спростять фільтрування в майбутньому або просто документують, як фільтрувати за допомогою Gradle.
Джаред Берроуз

Чи є спосіб виключити набір джерел із включення до звіту про jacoco? Я хочу виключити всі вихідні файли, які розміщені generated/java/замість main/java.
Амір Пашазаде

4

Це вже деякий час, але я просто перебіг це. Я боровся з усіма необхідними виключеннями. Я виявив, що це для мене щось набагато простіше. Якщо ви дотримуєтесь стилю макетування проекту Maven / src / main / java та / src / test / java, вам просто потрібно поставити buildDir / class / main у конфігурацію classDirectories так:

afterEvaluate {
    jacocoTestReport {
        def coverageSourceDirs = ['src/main/java']
        reports {
            xml.enabled false
            csv.enabled false
            html.destination "${buildDir}/reports/jacocoHtml"
        }
        sourceDirectories = files(coverageSourceDirs)
        classDirectories = fileTree(
                dir: "${project.buildDir}/classes/main",
                excludes: [
                      //whatever here like JavaConfig etc. in /src/main/java
                     ]
        )
    }
}

Просто побачив це знову. Це було взято безпосередньо з робочого конфігурації. Можливо, ваша версія Градле і Якоко була іншою, ніж моя. Вибачте.
Ренді

4

Нижче наведений код виключає класи перевірки покриття:

jacocoTestCoverageVerification {
    afterEvaluate {
        classDirectories = files(classDirectories.files.collect {
            fileTree(dir: "${project.buildDir}/classes/main",
                    exclude: ['**/packagename/**'])
        })
    }
}

2

деякі коментарі згадували попередження про депресію. для вирішення просто скористайтеся геттером:

afterEvaluate {
    getClassDirectories().from(files(classDirectories.files.collect {
        fileTree(dir: it, exclude: 'com/blah/**')
    }))
}

2

Для фільтрації у звіті про jacoco потрібно виключити два завдання jacocoTestReportта jacocoTestCoverageVerification.

зразок коду

    def jacocoExclude = ['**/example/**', '**/*Module*.class']

    jacocoTestReport {
        afterEvaluate {
            getClassDirectories().setFrom(classDirectories.files.collect {
                fileTree(dir: it, exclude: jacocoExclude)
            })
        }
    }

    jacocoTestCoverageVerification {
        afterEvaluate {
            getClassDirectories().setFrom(classDirectories.files.collect {
                fileTree(dir: it, exclude: jacocoExclude)
            })
        }

        ...
    }



0

додати нижче конфігурацію у файл gradle.properties

coverageExcludeClasses=["com.example.package.elasticsearch.*", "com.example.package2.*",]


coverageExcludeClassesздається, що це не річ у JaCoCo / Gradle
Gus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.