Background
The project is using the small plugin. An app is divided into main and multiple plugins in order to count plug-in code coverage.
1 Modifying plugins
Modify Plugin Build.gradle
Buildtypes { release {... } debug{ minifyenabled false testcoverageenabled = True //Open Debug version of code coverage switch proguardfiles Getdefaultproguardfile (' Proguard-android.txt '), ' Proguard-rules.pro ' } }
The classes file generated by the plugin will change during the next generation because of the engineering reason. So to speak classes file copy to another location staging.
tasks.whentaskadded {task-and if (task.name = = ' Assemblerelease ' | | task.name = = ' Assembledebug ') {
task.dolast { "copy classes to Jacoco" = android.defaultConfig.applicationId def Artifactname = applicationid.substring (Applicationid.lastindexof (".") + 1, applicationid.length ()) project.copy { "build/intermediates/classes/debug" "${rootdir}/". /jacoco/${artifactname}/classes/debug " } }}}
2 Modifying Main
Main as a container for plugins, our test code is here. All test cases are inherited from Basetest.
Increase the coverage saving function for Basetest finishz.
@Overrideprotected voidfinished (Description Description) {Super. Finished (description); . ... generateecfile (true); } /*** Generate EC file * *@paramIsNew whether to re-create the EC file*/ Public Static voidGenerateecfile (Booleanisnew) {SimpleDateFormat DF=NewSimpleDateFormat ("Yyyymmdd_hhmmss"); FinalString Default_coverage_file_path = "/sdcard/coverage/" + String.Format ("Coverage_%s.ec", Df.format (NewDate ())); LOGUTILS.I ("Build Coverage File:" +Default_coverage_file_path); OutputStream out=NULL; File Mcoveragefilepath=NewFile (Default_coverage_file_path); Try { if(IsNew &&mcoveragefilepath.exists ()) {LOGUTILS.I ("Jacocoutils_generateecfile: Clear old EC file"); Mcoveragefilepath.delete (); } if(!mcoveragefilepath.exists ()) {File D=NewFile ("/sdcard/coverage/"); D.mkdirs (); Mcoveragefilepath.createnewfile (); } out=NewFileOutputStream (Mcoveragefilepath.getpath (),true); Object Agent= Class.forName ("Org.jacoco.agent.rt.RT"). GetMethod ("GetAgent"). Invoke (NULL); Out.write ((byte[]) Agent.getclass (). GetMethod ("Getexecutiondata",Boolean.class). Invoke (Agent,false)); } Catch(Exception e) {logutils.i ("Generateecfile:" +e.getmessage ()); } finally { if(out = =NULL) return; Try{out.close (); } Catch(IOException e) {e.printstacktrace (); } } }
Compile main, generate test apk and debug version of APK.
3. Testing
Testing using a test system
4. Collect all test data collected from the test.
ImportsubprocessImportOs,sys o= Subprocess.check_output (['adb','Devices']) LS= O.split ('\ n') forLineinchls:ifLine.endswith ('Device'): Id_= Line.split ('\ t') [0] Os.makedirs ('./report/'+id_) C1= ['adb','- S', Id_,' Pull','/sdcard/coverage','./report/'+Id_]Print ' '. Join (C1) O1=Subprocess.check_output (C1)PrintO1
5. Create a new Gradle project and generate a report.
New Folder Jacocreport.
Go to the folder to run Gradle init.
Modify Build.gradle
Apply plugin: ' Jacoco 'Buildscript {repositories {mavenlocal () Mavencenter () Maven {URL' Plugins '}} dependencies {Classpath' net.researchgate:gradle-release:2.4.1 'Classpath' com.android.tools.build:gradle:2.2.3 '}}allprojects {repositories {mavenlocal () Mavencenter () Flatdir {dirs' Libs ' } }}//first delete the old merge results filetask Removeoldmergeec (type:delete) {Delete"${rootdir}/. /jacoco/coveragemerged/mergedcoverage.ec "}task Mergereport (TYPE:JACOCOMERGE,DEPENDSON:REMOVEOLDMERGEEC) {Group= "Reporting"Description= "Merge Jacoco report."Destinationfile= File ("${rootdir}/. /jacoco/coveragemerged/mergedcoverage.ec ") //The Ec_dir here is the folder where the EC files are storedFiletree tree = Filetree ("$projectDir/.. /jacoco/report ") {include' **/*.ec '} def CNT=0tree.each{CNT++} println"EC file Conut:" +CNT//tree.each{f->println F}Executiondata = Tree//executiondata (Files)}["Plugin1", ' plugin2 '].each {it1->Task"Report$it1" (Type:jacocoreport,dependson: [Mergereport]) {IT-println"I ' m task $it"Group= "Reporting"Description= "Generate Jacoco coverage reports after running tests."def pluginName1= "$it 1"println pluginName1 Reports {xml.enabled=truehtml.enabled=true} classdirectories=Filetree (dir:"${rootdir}/. /jacoco/${pluginname1}/classes/debug ", excludes: [' **/r*.class ', ' **/* $InjectAdapter. class ', ' **/* $ModuleAdapter. class ', ' **/* $ViewInjector *.class ']) def coveragesourcedirs=[ //No code path required] Sourcedirectories=files (coveragesourcedirs) File F=NewFile ("${rootdir}/. /jacoco/coveragemerged/mergedcoverage.ec ") println""+f.exists () println"" + f.length () + "bytes"Executiondata= Files ("${rootdir}/. /jacoco/coveragemerged/mergedcoverage.ec ") Dofirst {//Modify the Claess filePrintln "${rootdir}/. /jacoco/${pluginname1}/classes/debug "NewFile ("${rootdir}/. /jacoco/${pluginname1}/classes/debug "). eachfilerecurse {file-if(File.name.contains (' $$ ') ) {println"Modify" +file.name File.renameto (File.path.replace (' $$ ', ' $ ')) } } }}}task Allreport (dependsOn: [reportplugin1,reportplugin2]) {dolast{println"Done!" }}
Last Top list
# main APK code directory ├──jacoco # Data Directory-hold EC file, classes file ├──jacocoreport # Generate report of the project catalog Build.gradle in this ├──plugin1 # plugin 1├──plugin2 # plugin 2< /c15>
Android Code Coverage