首先gradle 文件配置如下:
apply plugin: 'jacoco'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.javaandroidunittestdemo"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
testCoverageEnabled true
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.+'
testCompile 'junit:junit:4.12'
}
jacoco{
toolVersion = "0.7.7.201606060606"
}
task jacocoTestReport(type: JacocoReport,dependsOn:"testDebugUnitTest") {
def coverageSourceDirs = [
"src"
]
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
//ignoreFailures = true
jacoco {
reportsDir = file("../report/test-results/")
}
def utilTest = '/build/jacoco/testDebugUnitTest.exec'
executionData = fileTree(utilTest)
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"
}
}
classDirectories = fileTree(
dir: "./build/intermediates/classes/debug",
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
sourceDirectories = files(coverageSourceDirs)
additionalSourceDirs = files(coverageSourceDirs)
}
注意:这个
debug{
testCoverageEnabled true
}
一定要打开,因为我们对debug进行单元测试。
在jenkins上我们配置gradle script:
然后配置sonar-scanner:
指明 jacoco.exec文件和 test-result文件路径。
有的用户直接在gradle 脚本里面添加build.
这样就是直接执行用户的 gradle脚本。
但是用户有时候在脚本里面配置了其他测试:
def coverageSourceDirs = [
'../epa_new_android/src/main/java'
]
task jacocoTestReport(type: JacocoReport, dependsOn: ["testDebugUnitTest", "connectedDebugAndroidTest"]) {
doFirst {
delete('../report/testUnitTest.exec')
delete('../report/androidTestUnitTest.ec')
// File file1 = new File('../report/test-results/jacocoTestReport');
// file1.deleteDir();
delete('../report/test-results/')
}
jacoco {
reportsDir = file("../report/test-results/")
}
group = "Reporting"
description = "Generate Jacoco coverage reports"
classDirectories = fileTree(
dir: '/build/intermediates/classes/debug',
excludes: ['**/R.class',
'**/R$*.class',
'**/*$ViewInjector*.*',
'**/BuildConfig.*',
'**/Manifest*.*']
)
def utilTest = '/build/jacoco/testDebugUnitTest.exec'
def androidTestDir = '/build/outputs/code-coverage/connected/'
def androidTest
def androidTestFileName;
FileTree iotTree = fileTree(dir: androidTestDir, includes: ['*.ec'])
iotTree.each {
File file ->
androidTestFileName = file.name
androidTest = file.path
}
additionalSourceDirs = files(coverageSourceDirs)
sourceDirectories = files(coverageSourceDirs)
executionData = files(utilTest, androidTest)
reports {
xml.enabled = true
html.enabled = true
}
doLast {
copy {
from utilTest
into '../report'
rename("testDebugUnitTest.exec", 'testUnitTest.exec')
}
copy {
from androidTest
into '../report'
rename(androidTestFileName, 'androidTestUnitTest.ec')
}
copy {
from "/build/test-results"
into '../report/test-results/unittest'
}
}
}
connectedDebugAndroidTest是关于模拟机的测试,这样在执行build gradle 之前需要改造。
但是 android 项目规则不能使用java 规则,要安装 android Lint 插件,然后指定规则:
sonar.projectKey=SDKDemo
sonar.projectName=SDKDemosonar.projectVersion=1.0
sonar.sources=app/src/main/java
sonar.binaries=app/build/intermediates/classes/
sonar.language=java
sonar.sourceEncoding=UTF-8
sonar.profile=Android Lint
其中,sonar.projectKey和sonar.projectName随便填不与其他项目重复的就好,一般是项目名;sonar.sources指向Java代码目录;sonar.binaries指向build后产生classes目录,一般AS和eclipse不同;sonar.profile为代码检查规则,就是我们需要安装的 android lint.
android lint的下载:
在 sonarqube官网,选择sonar plugin ,选择java :
First Analysis of a Java Project
- Install SonarQube Server (see Setup and Upgrade for more details)
- Install SonarJava (see Installing a Plugin for more details). By default SonarJava is provided out of the box with SonarQube.
- Execute analysis:
For Maven projects, use the SonarQube Scanner for Maven by executing the following command from the root directory of the project:
mvn sonar:sonar -Dsonar.host.url=[your SonarQube URL]
For Gradle projects, declare the
org.sonarqube
plugin in your build.gradle file:plugins {
id
"org.sonarqube"
version
"2.5"
}
Then use the SonarQube Scanner for Gradle by executing the following command from the root directory of the project:
.
/gradlew
sonarqube -Dsonar.host.url=[your SonarQube URL]
Follow the link provided at the end of the analysis to browse your project's quality in SonarQube UI.
Java bytecode is required
Analyzing a Java project without providing the Java bytecode produced by javac
(Android users: Jack doesn't provide the required .class
files) and all project dependencies (jar files) is possible, but will result in an increased number of false negatives, i.e. legitimate issues will be missed by the analyzer.
From SonarJava version 4.12 binary files are required for java projects with more than one java file. If not provided properly, analysis will fail with the message
Please provide compiled classes of your project with sonar.java.binaries property
See Java Plugin and Bytecode for how to provide the Java bytecode if you are not using Maven to run your analysis.
Advanced Usage
With SonarJava, you can :
- deal with Unit Tests and Code Coverage : Code Coverage by Unit Tests for Java Project tutorial
- provide the Java Bytecode for more accurate analysis
- handle correctly the java version used by source code within projects: Handling Java Source Version
- analyse other java-related files: Analyse maven pom.xml files
- use additional java-specific plugins like Cobertura or Android Lint
- create your own Custom Rules