Gradle rocking scala specs2 tests

In preparation of the upcoming Coursera course „Reactive Programming“ I just want to refresh my Scala skills by porting the Coursera Downloader from Python to Scala.

Setting up the initial build with Gradle is quite easy using the Scala Plugin. Looking around for some testing framework I have chosen Specs2 . Running Gradle after building some simple unit tests shows up that the tests are not executed at all. The build passes without running one single tests. Even declaring the tests to be processed by a JUnit4 runner did not want show up a single tests result. So I came up with the following simple solution. I add a new specs2 task to my Gradle build using the specs2 file runner:

/**
 * Run Spec2 tests
 */
task specs(type: JavaExec, dependsOn: testClasses) {
    main = 'org.specs2.files'
    args = ['console']
    classpath sourceSets.main.runtimeClasspath
    classpath sourceSets.test.runtimeClasspath
    classpath configurations.testRuntime
    classpath configurations.runtime
}

The file runner will select all files matching .*Spec in the test source directory which default (src/test/scala) nicely conforms the default project setup. If necessary it could be adjusted by setting the specs2.srcTestDir system property. For more information on the Specs2 Runners refer to the Specs2 documentation.

Now you have only to hook in the test step execution which could be easily achieved by extending the test task to depend on the specs2 tasks as well:

/*
 * and  add them to the default test set
 */
test.dependsOn specs

Running the test target of the Gradle build once again shows up the execution of the specs2 target and all tests and specifications.

Update(09/04/2014)

Marino Borra points out that he could run the specs tests successfully with the default gradle test task by simply adding the @RunWith(classOf[JUnitRunner]) annotation.

8 Gedanken zu „Gradle rocking scala specs2 tests“

  1. Hi Michael, why you don’t annotate Specs with @RunWith( classOf[JUnitRunner] ) or extends SpecificationWithJUnit, I have tested the first solution, and apparently it works fine.

    Thanks
    –Marino

    1. Hi Marino,
      thanks for your feedback. I justed tested your suggestion of using a @RunWith annotation again and you are right it works (now). I could not reconstruct why I am failing on it last time. I will incorporate your advice into the article soon.

      Cheers!

      Michael

    1. Hi John,
      thanks for your feedback.

      This line configures the gradle java execution task setting from which class the main method should be executed. Due to the fact that Scala has no static class methods, but using Object types instead, it refers to object which provides the main method to run (see https://static.javadoc.io/org.specs2/specs2_2.10/2.2.3/index.html#org.specs2.files$ for details on that version).

      It seems that the package structure was reorganized in one of the previous versions. Please try to change that line to point to ‚org.specs2.runners.files‘ instead (here you can find the recent scaladoc for version 4.6.0. https://etorreborre.github.io/specs2/api/SPECS2-4.6.0/org/specs2/runner/files$.html).

      (updated 19/07/2019 9:13am – fix typo: missing s in object name)

      1. Hi,

        Thank you for your response. For me the following is working now;
        main = ‚org.specs2.runner.files‘

        However I came across a situation where this setup runs all the tests that extend Specification however if a test class extends SpecificationLike (which is basically the same thing one is an abstract class one is a trait) it does not include it in the set of tests that it runs when you run gradle test.

        Do you have any idea about this situation ?

        1. Hi John,
          you are right – the object reference was missing an ’s‘ at the end. I fixed this typo in my answers. Regarding your question, the runners documentation for sbt (https://etorreborre.github.io/specs2/guide/SPECS2-4.6.0/org.specs2.guide.Runners.html#via-sbt) points out that „This means that any class or object extending the Specification abstract class can be executed by sbt.“ (https://etorreborre.github.io/specs2/guide/SPECS2-4.6.0/org.specs2.guide.Runners.html#via-sbt). I suppose this is the same for all other runner implementations. The SpecificationLike trait does not implement Specification and that is probably the reason the classes / objects are not found. Is there any specific reason not to extend from Specification?

          1. Well I’m using Gradle so… Also I am using TestKit for defining ActorSystem and that is an abstract class as well so I need to `extend` that one and then add `with SpecificationLike`.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

fünfzehn − 13 =