Skip to content


Running Scala specs tests in Maven with JUnit 4

My first foray into Scala unit testing wasn’t quite as smooth as I’d wanted, but I have it working now. The specs doc is pretty good. However what it doesn’t tell you is that JUnit 4.0 doesn’t work. Or 4.1. If you try these you’ll run into a “No runnable methods” found, with the following trace

java.lang.Exception: No runnable methods
        at org.junit.internal.runners.TestClassMethodsRunner.testAborted(TestClassMethodsRunner.java:42)
        at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:33)
        at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
        at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
        at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)

Upgrading to JUnit 4.4 did the trick. Pom snippet is

        <dependency>
            <groupId>org.scala-tools.testing</groupId>
            <artifactId>specs</artifactId>
            <version>1.5.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.4</version>
            <scope>test</scope>
        </dependency>

Test snippet is

package org.mccv.cassandra
 
import org.specs._
import org.specs.runner._
/**
 * Created by IntelliJ IDEA.
 * User: mmcbride
 * Date: Jul 24, 2009
 * Time: 10:43:31 AM
 * To change this template use File | Settings | File Templates.
 */
 
class cassandraTest extends JUnit4(BasicCassandra)
 
object BasicCassandra extends Specification {
  val cass = Cassandra("localhost",9160)
  doBefore {
    cass.connect()
  }
  doAfter {
    cass.close()
  }
  "Cassandra(\"localhost\",9160)" should {
    setSequential()
    "create a Cassandra instance" in {
      cass must_!= null
    }
    "provide for creation of a Db" in {
      cass.db("SocialGraph") must_!= null
    }
    "allow insertion of values" in {
      cass.insert("SocialGraph","mccv","Details:name","Mark McBride".getBytes("UTF-8"))
    }
  }
 
  "cass.Db(\"SocialGraph\")" should {
 
  }
}

Posted in maven, scala.

  • etorreborre
    Hi Mark,

    Thanks for your post.

    2 tips for making your specification even more concise (with specs.1.6.0-SNAPSHOT or 1.5.1 SNAPSHOT):

    This will make your specification class a JUnit test:
    class BasicCassandra extends SpecificationWithJUnit { ... }

    It is still runnable in the console with:

    scala -cp <...> run BasicCassandra

    And you can write (if you like it):

    cass.connect().before
    cass.close().after

    Cheers,

    Eric.
  • Excellent, that would be quite a bit nicer. Having the object/class pair is a bit clunky... Overall the framework is very nice though.
blog comments powered by Disqus