下面是我的sonarqube属性片段:
sonarqube {
properties{
property "sonar.junit.reportPaths", "build/test-results/testDebugUnitTest/*.xml"
property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacocoTestReport.xml"
}
}
Jacoco的配置和属性工作正常,我是如何确认这一点的?我创建了一个java类,并为它编写了一个单元测试,sonarqube识别了这一点并将其记录为代码覆盖率的一部分,而它基本上忽略了所有Kotlin文件测试。我继续将一个 kotlin 文件更改为 java,并为它编写了一个 UnitTest,是的,它被重新计算并添加为代码覆盖率的一部分,再次,kotlin 文件测试被忽略了。
顺便说一句,这是我的雅各布.gradle:
apply plugin: 'jacoco'
ext {
coverageExclusions = [
'**/*Activity*.*',
'**/*Fragment*.*',
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
]
}
jacoco {
toolVersion = '0.8.6'
reportsDir = file("$buildDir/reports")
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
}
tasks.withType(Test) {
finalizedBy jacocoTestReport // report is always generated after tests run
}
task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest']) {
group = "Reporting"
description = "Generate Jacoco coverage reports for Debug build"
reports {
xml.enabled(true)
html.enabled(true)
xml.destination(file("build/reports/jacocoTestReport.xml"))
}
def debugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug/classes", excludes: coverageExclusions)
def mainSrc = "/src/main/java"
additionalSourceDirs.from = files(mainSrc)
sourceDirectories.from = files([mainSrc])
classDirectories.from = files([debugTree])
executionData.from = fileTree(dir: project.buildDir, includes: [
'jacoco/testDebugUnitTest.exec', 'outputs/code-coverage/connected/*coverage.ec'
])
请检查java kotlin项目的Jacoco配置:
http://vgaidarji.me/blog/2017/12/20/how-to-configure-jacoco-for-kotlin-and-java-project/
关键是在SourceDirectory和ClasseDirectory中包含kotlin目录
经过这么多的研究和调试,以及上面@LarryX的回答,我能够像他所说的那样玩这些类,下面是我的工作Jacoco.gradle
文件。
apply plugin: 'jacoco'
jacoco {
toolVersion = "0.8.4"
}
tasks.withType(Test) {
jacoco.includeNoLocationClasses = true
jacoco.excludes = ['jdk.internal.*']
}
project.afterEvaluate {
(android.hasProperty('applicationVariants')
? android.'applicationVariants'
: android.'libraryVariants')
.all { variant ->
def variantName = variant.name
def unitTestTask = "test${variantName.capitalize()}UnitTest"
def androidTestCoverageTask = "create${variantName.capitalize()}CoverageReport"
tasks.create(name: "${unitTestTask}Coverage", type: JacocoReport, dependsOn: [
"$unitTestTask",
"$androidTestCoverageTask"
]) {
group = "Reporting"
description = "Generate Jacoco coverage reports for the ${variantName.capitalize()} build"
reports {
html.enabled(true)
xml.enabled(true)
csv.enabled(true)
}
def excludes = [
// data binding
'android/databinding/**/*.class',
'**/android/databinding/*Binding.class',
'**/android/databinding/*',
'**/androidx/databinding/*',
'**/BR.*',
// android
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*',
// butterKnife
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
// dagger
'**/*_MembersInjector.class',
'**/Dagger*Component.class',
'**/Dagger*Component$Builder.class',
'**/*Module_*Factory.class',
'**/di/module/*',
'**/*_Factory*.*',
'**/*Module*.*',
'**/*Dagger*.*',
'**/*Hilt*.*',
// kotlin
'**/*MapperImpl*.*',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/BuildConfig.*',
'**/*Component*.*',
'**/*BR*.*',
'**/Manifest*.*',
'**/*$Lambda$*.*',
'**/*Companion*.*',
'**/*Module*.*',
'**/*Dagger*.*',
'**/*Hilt*.*',
'**/*MembersInjector*.*',
'**/*_MembersInjector.class',
'**/*_Factory*.*',
'**/*_Provide*Factory*.*',
'**/*Extensions*.*',
// sealed and data classes
'**/*$Result.*',
'**/*$Result$*.*'
]
def javaClasses = fileTree(dir: variant.javaCompileProvider.get().destinationDir,
excludes: excludes)
def kotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/${variantName}",
excludes: excludes)
classDirectories.setFrom(files([
javaClasses,
kotlinClasses
]))
def variantSourceSets = variant.sourceSets.java.srcDirs.collect { it.path }.flatten()
sourceDirectories.setFrom(project.files(variantSourceSets))
def androidTestsData = fileTree(dir: "${buildDir}/outputs/code_coverage/${variantName}AndroidTest/connected/", includes: ["**/*.ec"])
executionData(files([
"$project.buildDir/jacoco/${unitTestTask}.exec",
androidTestsData
]))
}
}
}
注意到:
def javaClasses = fileTree(dir: variant.javaCompileProvider.get().destinationDir,
excludes: excludes)
def kotlinClasses = fileTree(dir: "${buildDir}/tmp/kotlin-classes/${variantName}",
excludes: excludes)
classDirectories.setFrom(files([
javaClasses,
kotlinClasses
]))
另外,请注意project.after评估
我不确定这是否相关,但我认为您必须在本节运行之前运行并生成测试。如果不是实际的Android应用程序,此解决方案也适用于库。
然后是我的声纳qube。gradle
文件如下。
apply plugin: "org.sonarqube"
sonarqube {
properties {
property "sonar.host.url", "http://localhost:9000/"
property "sonar.projectKey", "fair"
property "sonar.projectName", "fair"
property "sonar.login", "de9d79fe4d3aef9879567afc91a2ce465038d9be"
property "sonar.projectVersion", "${android.defaultConfig.versionName}"
property "sonar.junit.reportsPath", "build/test-results/testDebugUnitTest"
property "sonar.java.coveragePlugin", "jacoco"
property "sonar.sourceEncoding", "UTF-8"
property "sonar.android.lint.report", "build/reports/lint-results.xml"
property "sonar.jacoco.reportPaths", "build/jacoco/testDebugUnitTest.exec"
property "sonar.jacoco.itReportPath", fileTree(dir: project.projectDir, includes: ["**/*.ec"])
property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/testDebugUnitTestCoverage/testDebugUnitTestCoverage.xml"
}
}
tasks.sonarqube.dependsOn ":app:testDebugUnitTestCoverage"
最后是我的<code>build.gradle(项目)
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32"
classpath "org.jacoco:org.jacoco.core:0.8.7"
classpath("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3")
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
我是Kotlin开发的新手,我不知道如何处理这个问题。我将以下Kotlin数据类映射到MongoDB集合(Spring data MongoDB): 我想覆盖默认的 id 获取器并返回一个字符串而不是对象 Id。似乎“id”字段名称无法更改,因为我收到消息“不允许自定义id属性的字段名称!自定义名称不会被考虑!“,因此我无法使用始终建议的_id解决方案。 如何才能做到这一点?我错过了什么吗?
在Kotlin中,我覆盖了这两个Google登录功能: 检查与谷歌的连接是否失败。 问题是,有时当我关闭包含用户帐户的对话框时,该对话框会在活动启动时弹出 像这样: 我得到了一个带有以下logcat的<code>IllegalArgumentException</code> E/AndroidRuntime:致命异常:主进程:com.dancam.subscriptions,PID:6346 Ja
我正在使用Sonarqube分析我的Nestjs项目。当我用jest运行单元测试时,它们都通过了,代码覆盖率约为80%。在Sonarqube上,它仍然显示为0%。 我的sonar-project.properties文件如下 我的jest.json如下 我package.json的相关部分 我的源代码和它们各自的单元测试在同一个位置。测试文件有扩展名。spec.ts 在本地运行测试时,所有测试都通
我正在尝试使用Jacoco为静态编程语言进行声纳设置以生成代码覆盖率报告,但它没有显示任何代码覆盖率。在检查声纳控制台时,它显示以下错误。任何人以前都面临过这个问题,任何建议都可能错过。 元信息 使用sonarqube版本“2.6.1”的插件 grad lever version = ' 3 . 0 . 1 ' kotlinVersion='1.2.21' 声纳库版本 = 版本 6.7.1 (内部
我在尝试将Jacoco代码覆盖导入SonarQube时遇到了一些问题。 我使用SonarQube和Jacoco来导入测试覆盖结果(https://docs.sonarqube.org/display/PLUG/Java单元测试和覆盖结果导入)。一切都很好,直到我用某种方法解决了每个问题。 如果我删除了每个文件,那么测试覆盖率会正确生成,但对于每个文件,我得到0%的覆盖率。 只有当我将它与sonar
我正在设置通过SonarQube服务器分析项目。使用的工具集是: Kotlin 1.3.61 Gradle 6.0.1 Jacoco 0.7.9 SonarQube 7.5 SonnarQube Gradle插件2.7 问题是,我在SonarQube中有0.0%的覆盖率,但同时我有一份格式良好的jacoco测试覆盖率报告。以下是中的片段: 在执行< code >期间,我有下一个日志条目。/grad