Home > Programming > Simple Scala project step-by-step

Simple Scala project step-by-step

BE AWARE!!! This post refers to an old SBT version, check the new one

 

Recently I have started a project that will be coded in Scala. Here I leave some instructions for setting up the the scala project that uses sbt for project management and creates unit tests with scalatests. This entry follows the structure of this post but introduces some changes and improvements.

  1. Install sbt
  2. Create a new project
    $ mkdir test-project
    $ cd test-project/
    $ sbt
    Project does not exist, create new project? (y/N/s) y
    Name: TestProject
    Organization: com.example
    Version [1.0]:
    Scala version [2.7.7]: 2.9.0
    sbt version [0.7.4]: 0.7.7
    
  3. First we need to install a sbt plugin that collects test results and creates a xUnit report for using in a Continuous Integration Server like Jenkins. Details of that plugin can be found here. Create the file project/plugins/TestProjectPlugins.scala that instructs sbt to download the junit_xml_listener plugin.
    import sbt._
    
    class TestProjectPlugins(info: ProjectInfo) extends PluginDefinition(info) {
        val repo = "Christoph's Maven Repo" at "http://maven.henkelmann.eu/"
        val junitXml = "eu.henkelmann" % "junit_xml_listener" % "0.2"
    }
    
  4. Once we have the configuration for getting the plugin, create the project dependencies and include the new listener into the available ones by overriding the defaults. So, create a build configuration file in project/build/TestProject.scala like:
    import sbt._
    import eu.henkelmann.sbt.JUnitXmlTestsListener
    
    class TestProject(info: ProjectInfo) extends DefaultProject(info) {
       val scalatest = "org.scalatest" %% "scalatest" % "1.6.1" % "test"
    
       //create a listener that writes to the normal output directory
       def junitXmlListener: TestReportListener = new JUnitXmlTestsListener(outputPath.toString)
       //add the new listener to the already configured ones
       override def testListeners: Seq[TestReportListener] = super.testListeners ++ Seq(junitXmlListener)
    }
    
  5. Now, we have the project setup in place. Let’s write some classes and tests in order to check that everything is OK. First create the class under test in src/main/scala/Calc.scala
    package com.example
    
    object Calc {
        def add(x:Int, y:Int) : Int = x + y
    }
    
  6. Now, create a test in src/test/scala/CaltTest.scala that assures that the class is working as expected
    package com.example.test
    
    import com.example.Calc
    import org.scalatest.Suite
    
    class CalcTest extends Suite {
    
        def testAddition() {
            assert(4 === Calc.add(2,2))
        }
    }
    
  7. Now just test that tests pass by doing
    sbt clean-plugins
    sbt clean
    sbt update
    sbt test
    

    you should see something like this:

    $ sbt test
    [info] Building project test 1.0 against Scala 2.9.0
    [info]    using TestProject with sbt 0.7.7 and Scala 2.7.7
    [info]
    [info] == compile ==
    [info]   Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
    [info] Compiling main sources...
    [info] Nothing to compile.
    [info]   Post-analysis: 3 classes.
    [info] == compile ==
    [info]
    [info] == test-compile ==
    [info]   Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
    [info] Compiling test sources...
    [info] Nothing to compile.
    [info]   Post-analysis: 1 classes.
    [info] == test-compile ==
    [info]
    [info] == copy-test-resources ==
    [info] == copy-test-resources ==
    [info]
    [info] == copy-resources ==
    [info] == copy-resources ==
    [info]
    [info] == test-start ==
    [info] == test-start ==
    [info]
    [info] == com.example.test.CalcTest ==
    [info] CalcTest:
    [info] - testAddition
    [info] - testAdditionWithJavaObject
    [info] == com.example.test.CalcTest ==
    [info]
    [info] == test-complete ==
    [info] == test-complete ==
    [info]
    [info] == Test cleanup 1 ==
    [info] Deleting directory /tmp/sbt_b7e36ab4
    [info] == Test cleanup 1 ==
    [info]
    [info] == test-finish ==
    [info] Passed: : Total 2, Failed 0, Errors 0, Passed 2, Skipped 0
    [info]
    [info] All tests PASSED.
    [info] == test-finish ==
    [info]
    [info] == test-cleanup ==
    [info] == test-cleanup ==
    [info]
    [info] == test ==
    [info] == test ==
    [success] Successful.
    [info]
    [info] Total time: 1 s, completed 24-ago-2011 15:40:26
    [info]
    [info] Total session time: 2 s, completed 24-ago-2011 15:40:26
    [success] Build completed successfully.
    

The test reports are located in target/scala_*/test-reports/*.xml. I have setup a Mercurial project with all this code for fast start up, check it out here.

Categories: Programming Tags: , , ,
  1. tonicebrian
    June 6th, 2011 at 09:11 | #1

    @Banooker scalatests 1.3 does not work for Scala 2.9. Try 1.4.1 instead.

  2. Banooker
    June 6th, 2011 at 17:34 | #2

    @tonicebrian Thanks! I believe this was a binary incompatibility issue, as you pointed out. When I forced everything to 2.7.7 it finally worked!

  3. August 23rd, 2011 at 13:20 | #3

    If you’re using Scala 2.9 the latest ScalaTest version for that is 1.6.1.

  4. tonicebrian
  5. February 10th, 2012 at 22:15 | #5

    Tony — did you try it under SBT 0.11.2, and what changes should be made for it? I think nowdays everything moves to 0.11 so we need an update for it. :)

  6. tonicebrian
    February 15th, 2012 at 10:43 | #6

    @Alexy Khrabrov Good point, I’ve just created another post with a minimal Scala and SBT 0.11.2 project. Check it out!!

  1. February 15th, 2012 at 10:30 | #1