2017-08-03 159 views
0

我有一個SBT(Play Framework)多項目應用程序設置,如下所示。所有的子模塊都在modules之下,但所有覆蓋所有子模塊的測試用例都在「root」項目中。SBT + JaCoCo未涵蓋來自不同項目的所有「jacoco.includes」類

|-application 
    |-src 
    |-conf 
    |-modules 
    | |-proj1 
    | | |-src 
    | | |-conf 
    | | |-target 
    | |-proj2 
    | | |-src 
    | | |-conf 
    | | |-target 
    | |-proj3 
    | | |-src 
    | | |-conf 
    | | |-target 
    | |-proj4 
    |  |-src 
    |  |-conf 
    |  |-target 
    |-test 
    | |-src //I have test cases of all other projs here 
    |-build.sbt 
    |-plugins.sbt 

我的build.sbt看起來像這樣。

name := """my-proj""" 

lazy val IntegrationTest = config("it") extend(Test) 

lazy val commonSettings = jacoco.settings ++ itJacoco.settings ++ Seq(
    organization := "me.abc", 
    version := "0.1.0", 
    scalaVersion := "2.11.7", 
    crossPaths := false, 
    routesGenerator := InjectedRoutesGenerator 
) 
lazy val appDependencies = Seq(
    cache, 
    "org.mockito" % "mockito-all" % "1.10.19" 
) 

lazy val scalacheck = "org.scalacheck" %% "scalacheck" % "1.13.4" 

lazy val aaRoot = (project in file(".")).configs(IntegrationTest).settings(commonSettings: _*).settings(
    libraryDependencies ++= appDependencies, 
    libraryDependencies += scalacheck % Test, 
    parallelExecution in Test := false, 
    javaOptions in Test += "-Dconfig.file=conf/" + Option(System.getProperty("test.config")).getOrElse("application") + ".conf", 
    parallelExecution in jacoco.Config := false, 
    jacoco.includes in jacoco.Config := Seq("./modules/*/target/classes/com/me/**/*"), 
    parallelExecution in itJacoco.Config := false, 
    itJacoco.includes in itJacoco.Config := Seq("./modules/*/target/classes/com/me/**/*"), 
    Keys.fork in itJacoco.Config := true, 
    Keys.fork in jacoco.Config := true 
).enablePlugins(PlayJava).disablePlugins(plugins.JUnitXmlReportPlugin).dependsOn(
    proj1 % "compile->compile", 
    proj2 % "compile->compile", 
    proj3 % "compile->compile", 
    proj4 % "compile->compile", 
).aggregate(
    proj1, 
    proj2, 
    proj3, 
    proj4 
) 

lazy val proj1 = (project in file("modules/proj1")).configs(IntegrationTest).settings(commonSettings: _*).settings(
    libraryDependencies ++= appDependencies 
).enablePlugins(PlayJava) 


fork in run := false 

PlayKeys.externalizeResources := false 

正如你所看到的,在aaRoot,我試圖從jacoco.includes其他模塊的目標文件夾中的類文件(我曾嘗試其他幾種方法,但是毫無效果)。所有的測試案例運行良好,但jacoco不能覆蓋任何東西。

[info] ------- Jacoco Coverage Report -------- 
[info] 
[info] Lines: 0% (>= required 0.0%) covered, 0 of 0 missed, OK 
[info] Instructions: 0% (>= required 0.0%) covered, 0 of 0 missed, OK 
[info] Branches: 0% (>= required 0.0%) covered, 0 of 0 missed, OK 
[info] Methods: 0% (>= required 0.0%) covered, 0 of 0 missed, OK 
[info] Complexity: 0% (>= required 0.0%) covered, 0 of 0 missed, OK 
[info] Class: 0% (>= required 0.0%) covered, 0 of 0 missed, OK 
[info] Check /Users/RP/application/target/jacoco for detail report 

很明顯,jacoco.includes不看我請求看的任何類。

我已經嘗試了很多方法,並嘗試使用it-jacoco:cover以及但沒有任何工作。任何提示或幫助將appriciated。

回答

0

這是一個棘手的問題。我解決了我的問題,並使jacocosbt與我的項目設置一起工作,我認爲我的項目設置不算太糟糕,也很正常。

我所擁有的是,根項目下的幾個子項目和所有與子項目相關的測試用例都在根/測試中,以便我可以測試跨模塊功能測試。

解決方案 閱讀和理解jacocosbt插件的源代碼後,我意識到,這取決於兩個主要的事情。一種是classesToCover,另一種是「儀器類別」。

對於「儀器類」它取決於products in Compile這是當前項目中的「目標/類」文件夾。在我的情況下,「root/target/classes」沒有任何內容,裝備。我所有的課程都在「根/模塊/模塊1 /目標/類」等。

我只需要重寫此行爲。第一個很容易,第二個是解決方法。

在我build.sbt,我要補充以下修改

//Gets all the target/classes directories from sub projects 
lazy val myProducts = Def.task { 
    streams.value.log.info("Constructing the products!!!") 
    val finder: PathFinder = ((baseDirectory.value/"modules") ** "target" * "classes") filter {_.getAbsolutePath.indexOf("/project/") == -1} 
    finder.get 
} 

//Gets the classesToCover from all the sub projects 
lazy val myClassesToCover = Def.task { 
    val targetFolders: Seq[java.io.File] = myProducts.value 
    val inclFilters = Seq("*") map GlobFilter.apply 
    val exclFilters = Seq("Routes*","*Routes*","*Reverse*","*anonfun*", "*routes*") map GlobFilter.apply 

    targetFolders flatMap (classes => { 
    PathFinder(classes) ** new FileFilter { 
     def accept(f: File) = IO.relativize(classes, f) match { 
     case Some(file) if !f.isDirectory && file.endsWith(".class") => 
      val name = sbt.inc.Locate.toClassName(file) 
      inclFilters.exists(_ accept name) && !exclFilters.exists(_ accept name) 
     case _ => false 
    } 
    } get 
    }) 
} 

//Add them as settings for my root project 

lazy val root = (project in file(".")).settings(commonSettings: _*).settings(
    jacoco.settings, 
    parallelExecution in jacoco.Config := false, 
    Keys.fork in jacoco.Config := true, 
    jacoco.classesToCover in jacoco.Config ++= myClassesToCover.value, 
    products in Compile ++= myProducts.value 
).enablePlugins(PlayJava).disablePlugins(plugins.JUnitXmlReportPlugin).dependsOn(
    module1 % "test->test;compile->compile", 
    module2 % "test->test;compile->compile" 
).aggregate(
    module1, 
    module2 
) 

由於SBT compile任務依賴於products目標,我們應始終運行編譯第一像>sbt compile jacoco:cover

我測試過這個只有jacocosbt插件版本2.1.6

相關問題