In console output, we are getting jacoco coverage report. but on sonar it shows 0% and project using build.sbt file. and in jenkins -Dsonar.coverage.jacoco.xmlReportPaths=".../jacoco.xml" instead of - Dsonar.jacoco.reportPath="../jacoco.exec" still coverage shows 0% on sonarqube.
I faced the same issue and I have updated configurations of my project. I am able to see the code coverage in SonarQube 8.9 version
Under project/plugins.sbt file
addSbtPlugin("com.github.sbt" % "sbt-jacoco" % "3.0.3")
updates in build.sbt
lazy val jacoco = Seq(jacocoReportSettings in Test := JacocoReportSettings().withTitle("Your service name").withFormats(JacocoReportFormats.XML))
lazy val root = (project in file(".")).enablePlugins(PlayJava).settings(jacoco: _*)
scala version - 2.12.8
References:
https://blog.developer.atlassian.com/using-jacoco-a-code-coverage-tool-for-scala/
Related
Disclaimer: I am new to sbt and Scala so I might be missing obvious things.
My objective here is to use the Scala compiler as a library from my main project. I was initially doing that by manually placing the scala jars in a libs directory in my project and then including that dir in my classpath. Note that at the time I wasn't using sbt. Now, I want to use sbt and also download the scala sources from github, build the scala jars and then build my project. I start by creating 2 directories: myProject and myProject/project. I then create the following 4 files:
The sbt version file:
// File 1: project/build.properties
sbt.version=0.13.17
The plugins file (not relevant to this question):
// File 2: project/plugins.sbt
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0")
The build.sbt file:
// File 3: build.sbt
lazy val root = (project in file(".")).
settings(
inThisBuild(List(
organization := "me",
scalaVersion := "2.11.12",
version := "0.1.0-SNAPSHOT"
)),
name := "a name"
).dependsOn(ScalaDep)
lazy val ScalaDep = RootProject(uri("https://github.com/scala/scala.git"))
My source file:
// File 4: Test.scala
import scala.tools.nsc.MainClass
object Test extends App {
println("Hello World !")
}
If I run sbt inside myProject then sbt will download the scala sources from github and then try to compile them. The problem is that the base-directory is still myProject. This means that if the scala sbt source files refer to something that is in the scala base-directory they won't find it. For example, the scala/project/VersionUtil.scala file tries to open the scala/versions.properties file that lies in the scala base-directory.
Question: How can I set sbt to download a github repo and then build it using that project's base-directory instead of mine's (by that I mean the base-directory of myProject in the above example) ??
Hope that makes sense.
I would really appreciate any feedback on this.
Thanks in advance !
In the Scala ecosystem you usually depend on binary artifacts (libraries) that are published in Maven or Ivy repositories. Virtually all Scala projects publish binaries, including the compiler. So all you have to do is add the line below to your project settings:
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
dependsOn is used for dependencies between sub-projects in the same build.
For browsing sources you could use an IDE. IntelliJ IDEA can readily import Sbt projects and download/attach sources for library dependencies. Eclipse has an Sbt plugin that does the same. Ensime also, etc. Or just git clone the repository.
I added the scoverage plugin to projects/plugins.sbt
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5")
I was able to generate test coverage using
sbt clean coverage test
sbt coveragereport
However when I try to add socverage config to my build.sbt. I see build errors
error: value ScoverageKeys is not a member of object scoverage.ScoverageSbtPlugin
ScoverageSbtPlugin.ScoverageKeys.coverageMinimum := 70
Looks like build.sbt does not find Scoverage classes. What is going on here?
check that out. Seems like what you need is:
scoverage.ScoverageKeys.coverageMinimum := 70
I am working on a multi project build. I have followed same instructions, as mentioned here http://mtkopone.github.io/scct/, to generate code coverage report.
I am able to see this message scct: [testProject] Saving coverage data. on console while running sbt scct:test. But can't see coverage report in this folder
$childProjectDir/target/scala_/coverage-report/
Here is some source code of build.scala
lazy val root = Project("platform3", file("."))
.settings(ScctPlugin.mergeReportSettings: _*)
.aggregate(
testProject
)
.settings(basicSettings: _*)
lazy val testProject = Project("testProject", file("testProject"))
.dependsOn(testUtil)
.settings(noPublishing: _*)
.settings(libraryDependencies ++= Seq(
akkaKernel,
akkaSlf4j,
jacksonScala,
jodaTime,
prettyTime,
logback,
sprayCan,
sprayRouting,
specs2
))
.settings(ScctPlugin.instrumentSettings: _*)
The dependency, which I am using
// Scct Plugin
addSbtPlugin("com.sqality.scct" %% "sbt-scct" % "0.3")
Can anyone help me to resolve this? Thanks in advance.
Ayush
SCCT is obsolete, use Scoverage instead. Check out my working example of a multi-module SBT project which creates coverage reports for individual projects.
https://github.com/RadoBuransky/sonar-scoverage-plugin/tree/master/samples/sbt/multi-module
As part of a CI setup the very first step is to create a package/jar using SBT dist. The following steps are to run unit, integration and functional tests with the dist-created jar.
Is it possible to do that with SBT?
Normally I use sbt testOnly "Unit.*", but that works in the context of a project. I can't find any documentation showing how to do this when there is already a jar.
I'm using ScalaTest and I know there is a runner for it I could use http://www.scalatest.org/user_guide/using_the_runner. But using SBT would be simpler, if that is possible.
As an example, something like this is what I am looking for:
sbt testOnly "Unit.* -jar myjar.jar"
Will my tests even be included in the jar when I use the following:
sbt dist
?
EDIT
I created a new folder
I added build.sbt with the following content:
name := "abc"
version := "1.0-SNAPSHOT"
scalaVersion := "2.10.0"
I added the lib folder and copied my tests jar into it
I ran sbt testOnly Unit.*
It could not find any tests
EDIT 2
I tried with the following "proper" SBT file:
name := "ihs2tests"
version := "1.0-SNAPSHOT"
scalaVersion := "2.10.0"
unmanagedBase in Test := new java.io.File(".")
and moved test.jar into the root of the project. Again, no tests found.
Normally I use sbt testOnly "Unit.*", but that works in the context of a project. I can't find any documentation showing how to do this when there is already a jar.
The test-family tasks in SBT (with testOnly as an example) work with compile task that returns a list of compiled files through an sbt.inc.Analysis instance. I couldn't figure out how to amend it and inject the changed Analysis instance to testOnly so it knows the test I'm going to run exists.
I'm proposing another solution - a trick.
Package the tests classes to a jar with test:package task as follows:
[test-lib]> test:package
[info] Updating {file:/Users/jacek/sandbox/so/test-lib/}test-lib...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-classes...
[info] Packaging /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-lib_2.10-0.1-SNAPSHOT-tests.jar ...
[info] Done packaging.
[success] Total time: 9 s, completed Mar 4, 2014 11:34:13 PM
When you have the test jar, you can execute the test framework on the command line without SBT (I assume you use ScalaTest given the scalatest tag, but I'll use Specs2). Read the documentation of the test framework on how to do it and for Specs2 it's specs2.run as described in Console output.
Executing tests from the test jar requires defining a proper CLASSPATH that may or may not be easy to get right. That's where SBT can be of great help - to manage dependencies and hence the CLASSPATH.
Create another SBT project and save the test jar in lib subdirectory to have it on CLASSPATH (as described in Unmanaged dependencies).
Dependencies in lib go on all the classpaths (for compile, test, run, and console).
Add a sample build.sbt where you define your test framework as a dependency of the project. For Specs2 it's as follows (I used the default configuration as described in the Specs2 home page):
libraryDependencies += "org.specs2" %% "specs2" % "2.3.8" % "test"
scalacOptions in Test ++= Seq("-Yrangepos")
The trick is to execute the main class of the test framework, e.g. specs2.run for Specs2, as if the class were executed on the command line. SBT helps with test:runMain.
[my-another-project]> test:runMain specs2.run HelloWorldSpec
[info] Running specs2.run HelloWorldSpec
HelloWorldSpec
The 'Hello world' string should
+ contain 11 characters
+ start with 'Hello'
+ end with 'world'
Total for specification HelloWorldSpec
Finished in 62 ms
3 examples, 0 failure, 0 error
Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0"
[success] Total time: 5 s, completed Mar 4, 2014 11:15:14 PM
Don't worry about this Exception as it comes from SBT that catches exit from Specs2 (after test execution) so SBT remains up.
It seems that SBT can't read jar file without any additional/manual setup - I might be wrong but I didn't find anything in the docs. So I tried something like this to make the task simpler:
unzip some-test.jar
java -jar sbt-launch.jar \
'set scalaSource in Test := new java.io.File(".")' \
'set fullClasspath in Test += Attributed.blank(file("."))' \
'test'
This runs without errors but does not find tests.
If I add 'set includeFilter in (Test, unmanagedSources) := "*Suite*.class"' to force it to find tests it obviously fails because it expects *.scala files, not the compiled *.class files.
I'm not an SBT expert, but I think this must be close to a solution. There must be a way to read all files from a jar path programmatically and then tell test framework to use *.class files.
At this point is seems more reasonable to run tests using a Scalatest test runner or from sbt using the project.
If you wish to dig deeper take a look at SBT source code and the default sbt shell script that does lots of setup before it runs the sbt launcher jar.
I'm running integration tests in Scala - these are found in the src/it/scala directory, and I've added the following to my build.sbt:
seq(Defaults.itSettings: _*)
However, when I run SCCT to calculate code coverage, the integration tests are not run. How can I make them be run?
I am using scct 0.3-SNAPSHOT / sbt 0.13
for mergin test + it:test try the following setting:
ScctPlugin.instrumentSettings ++ Defaults.itSettings ++ Seq(
resourceDirectory in ScctPlugin.ScctTest <<= (resourceDirectory in Test),
sources in ScctPlugin.ScctTest ++= (sources in IntegrationTest).value
)
this might get tricky if you have different resources