Scala Tools

by Sebastien Mirolo on Tue, 6 Mar 2012

There are basic tasks you need in any development stack: Style Checking, Code Coverage and Reference Documentation. As it reaches maturity, all language ecosystem provides tools for managing those activities. Scala is not exception.

Style Checking

First there is an official Scala Style Guide and an application that can be used to check a source repository against a particular style: scalastyle. The good thing about scalastyle is that it generates a checkstyle compatible XML file. This means it is a no brainer to add scalastyle to your jenkins continuous build infrastructure.

At first, I planned to put all scalastyle related stuff into my personal sbt environment, aka ~/.sbt. Unfortunately after trials and errors, I couldn't get all the required environment there. Some modifications had to be made in the local project files themselves. Splitting half-half would break everyone else so I made all required dependencies available in the local project sbt files.

$ diff -u prev project/plugins.sbt

+resolvers ++= Seq(
+  "Sonatype Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots",
+  "Sonatype Releases" at "http://oss.sonatype.org/content/repositories/releases"
+)
+
+addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.2.0")

$ diff -u prev build.sbt

+org.scalastyle.sbt.ScalastylePlugin.Settings

I haven't found yet if it is sbt, maven or a problem inherent to Scala or Java, but exact version numbers do matter. While you might be used to linux distributions, pip or gem versions whitelists and blacklists, there is no such luck here. I had to bump sbt version number to 0.12.2 in order to fetch an actual scalastyle package without error.

$ diff -u prev project/build.properties
-sbt.version=0.11.3
+sbt.version=0.12.2

Once the project files are correct and the packages available on the local system, it is straightforward to follow the online instructions, create a config file and run the scalastyle analysis.

$ sbt scalastyle-generate-config
$ sbt scalastyle

If you think (like I do) the whole sbt stuff is more complex than it should for no apparent reason, you might want to try using the command-line tools directly:

$ wget https://oss.sonatype.org/content/repositories/releases/org/scalastyle/scalastyle-batch_2.9.2/0.2.0/scalastyle-batch_2.9.2-0.2.0-distribution.zip
$ unzip scalastyle-batch_2.9.2-0.2.0-distribution.zip
$ wget http://www.scalastyle.org/scalastyle_config.xml
$ java -jar ./scalastyle-batch_2.9.2-0.2.0/scalastyle-batch_2.9.2.jar \
    --config ./scalastyle_config.xml src/main/scala

On a side note, scalastyle, as most editors rely on scalariform, the Scala code formatter.

Apart from scalastyle, there is linter, an attempt at producing a scala lint tool, though it is not sure this project is still active.

Unit Tests and Coverage

Unit Tests and Coverage go hand-in-hand. Once you spent the time to write any kind of tests for your project, the effort to actually measure the amount of code covered is only a step away.

There are a few frameworks for writing unit tests in Scala (scalatest, specs2, scalascheck). Many of them include some attempts to implement Behavior-Driven Development (BDD) as an embed Domain Specific Language (DSL) into Scala.

For now we are solely interested to setup a flow where we can run a test, extract code coverage and display into into our jenkins metrics. Since scalatest is able to provide easy access to an underlying JUnit Java implementation, we will start there.

$ diff -u prev build.sbt

+libraryDependencies += "com.novocode" % "junit-interface" % "0.10-M1" % "test"
+
+libraryDependencies += "org.scalatest" %% "scalatest" % "1.9.1" % "test"
+
+seq(ScctPlugin.instrumentSettings : _*)

$ cat src/test/scala/Example.scala

import org.scalatest.junit.AssertionsForJUnit
import scala.collection.mutable.ListBuffer
import org.junit.Assert._
import org.junit.Test
import org.junit.Before

import Chisel._

class MyFloat extends Bundle {
  val sign = Bool()
  val exponent = Bits(width = 8)
  val significand = Bits(width = 23)
}

class MyFPUnit extends Component {
  val io = new MyFloat()
}

class ExampleSuite extends AssertionsForJUnit {

  @Test def verifyEasy() {
    // Uses JUnit-style assertions, we are only interested
    // in generating code coverage for now.
    chiselMain(Array[String](), () => new MyFPUnit())
    assertTrue(true)
  }
}

# To enable JUnit XML output compatible with Jenkins,
# follow these instructions.
$ cat project/project/plugins.scala
import sbt._

object Plugins extends Build {
  lazy val plugins = Project("plugins", file("."))
    .dependsOn(
      uri("git://github.com/bseibel/sbt-simple-junit-xml-reporter-plugin.git")
    )
}

$ sbt test
$ ls -la test-reports
ExampleSuite.xml

Great! Now that we have unit test output, let's get some code coverage for it.

The top link for Scala code coverage returns scct. Notice to say that any JVM based code coverage tool could also do. For example: undercover, Cobertura or JaCoco.

Since we don't really have a preference at this point, let's start playing with scct.

$ diff -u prev project/plugins.sbt
+resolvers += Classpaths.typesafeResolver
+
+resolvers += "scct-github-repository" at "http://mtkopone.github.com/scct/maven-repo"
+
+addSbtPlugin("reaktor" % "sbt-scct" % "0.2-SNAPSHOT")

$ diff -u prev build.sbt
+
+seq(ScctPlugin.instrumentSettings : _*)

$ sbt clean scct:test
$ find . -name 'coverage-report'
target/scala-2.9.1/coverage-report

XXX Missing coverage for source files ==> scct: [tutorialSolutions] Timed out waiting for coverage report.

by Sebastien Mirolo on Tue, 6 Mar 2012