Getting started with Scala, Scalatest, and Maven

MrDrews picture MrDrews · Oct 10, 2012 · Viewed 15.1k times · Source

I created a new scala project with the following:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.2:generate 
    -DarchetypeGroupId=org.scala-tools.archetypes 
    -DarchetypeArtifactId=scala-archetype-simple 
    -DarchetypeVersion=1.3 
    -DgroupId=myGroup 
    -DartifactId=myProject
    -Dversion=0.1.0 
    -DinteractiveMode=false

Which gives me the following POM:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>myGroup</groupId>
   <artifactId>myProject</artifactId>
   <version>0.1.0</version>
   <name>${project.artifactId}</name>
   <description>My wonderfull scala app</description>
   <inceptionYear>2010</inceptionYear>
   <licenses>
     <license>
       <name>My License</name>
       <url>http://....</url>
       <distribution>repo</distribution>
     </license>
   </licenses>

   <properties>
     <maven.compiler.source>1.5</maven.compiler.source>
     <maven.compiler.target>1.5</maven.compiler.target>
     <encoding>UTF-8</encoding>
     <scala.version>2.8.0</scala.version>
   </properties>

 <!--
   <repositories>
     <repository>
       <id>scala-tools.org</id>
       <name>Scala-Tools Maven2 Repository</name>
       <url>http://scala-tools.org/repo-releases</url>
     </repository>
   </repositories>

   <pluginRepositories>
     <pluginRepository>
       <id>scala-tools.org</id>
       <name>Scala-Tools Maven2 Repository</name>
       <url>http://scala-tools.org/repo-releases</url>
     </pluginRepository>
   </pluginRepositories>
 -->
   <dependencies>
     <dependency>
       <groupId>org.scala-lang</groupId>
       <artifactId>scala-library</artifactId>
       <version>${scala.version}</version>
     </dependency>

     <!-- Test -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.8.1</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.scala-tools.testing</groupId>
       <artifactId>specs_${scala.version}</artifactId>
       <version>1.6.5</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.scalatest</groupId>
       <artifactId>scalatest</artifactId>
       <version>1.2</version>
       <scope>test</scope>
     </dependency>
   </dependencies>

   <build>
     <sourceDirectory>src/main/scala</sourceDirectory>
     <testSourceDirectory>src/test/scala</testSourceDirectory>
     <plugins>
       <plugin>
         <groupId>org.scala-tools</groupId>
         <artifactId>maven-scala-plugin</artifactId>
         <version>2.15.0</version>
         <executions>
           <execution>
             <goals>
               <goal>compile</goal>
               <goal>testCompile</goal>
             </goals>
             <configuration>
               <args>
                 <arg>-make:transitive</arg>
                 <arg>-dependencyfile</arg>
                 <arg>${project.build.directory}/.scala_dependencies</arg>
               </args>
             </configuration>
           </execution>
         </executions>
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>2.6</version>
         <configuration>
           <useFile>false</useFile>
           <disableXmlReport>true</disableXmlReport>
           <!-- If you have classpath issue like NoDefClassError,... -->
           <!-- useManifestOnlyJar>false</useManifestOnlyJar -->
           <includes>
             <include>**/*Test.*</include>
             <include>**/*Suite.*</include>
           </includes>
         </configuration>
       </plugin>
     </plugins>
   </build>
 </project>

I can run mvn test and the sample tests run successfully. I'd like to use the most recent version of scala (I downloaded / installed 2.9.2...), but the most recent version of the org.scala-tools.testing scala_VERSION dependency seems to be 2.9.1. I made the following changes in my POM:

    <scala.version>2.9.1</scala.version>

and

    <dependency>
       <groupId>org.scala-tools.testing</groupId>
       <artifactId>specs_${scala.version}</artifactId>
       <version>1.6.5</version>
       <scope>test</scope>
    </dependency>

Now, running mvn test gives

 -------------------------------------------------------
  T E S T S
 -------------------------------------------------------
 Running samples.ListSuite
 Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.674 sec <<< FAILURE!
 initializationError(samples.ListSuite)  Time elapsed: 0.003 sec  <<< ERROR!
 java.lang.ClassCastException: scala.collection.immutable.Set$EmptySet$ cannot be
  cast to scala.collection.generic.Addable
         at org.scalatest.FunSuite$class.test(FunSuite.scala:1039)
         at samples.ListSuite.test(scalatest.scala:59)
         at samples.ListSuite.<init>(scalatest.scala:61)
         at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

         at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
         at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
         at java.lang.Class.newInstance0(Class.java:372)
         at java.lang.Class.newInstance(Class.java:325)
         at org.scalatest.junit.JUnitRunner.<init>(JUnitRunner.scala:62)
         at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

         at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
         at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
         at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
         at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
         at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
         at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
         at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
         at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
         at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:51)
         at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120)
         at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103)
         at org.apache.maven.surefire.Surefire.run(Surefire.java:169)
         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
         at java.lang.reflect.Method.invoke(Method.java:601)
         at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
         at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)

 Running samples.StackSuite
 Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.12 sec
 Running samples.AppTest
 Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec

 Results :

 Tests in error:
   initializationError(samples.ListSuite)

 Tests run: 4, Failures: 0, Errors: 1, Skipped: 0

 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD FAILURE
 [INFO] ------------------------------------------------------------------------
 [INFO] Total time: 6.880s
 [INFO] Finished at: Wed Oct 10 01:10:56 ADT 2012
 [INFO] Final Memory: 9M/112M
 [INFO] ------------------------------------------------------------------------
 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.6:test (default-test) on project myProject: There are test failures.
 [ERROR]
 [ERROR] Please refer to C:\Dropbox\work\dev\scalasandbox\target\surefire-reports for the individual test results.
 [ERROR] -> [Help 1]
 [ERROR]
 [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
 [ERROR] Re-run Maven using the -X switch to enable full debug logging.
 [ERROR]
 [ERROR] For more information about the errors and possible solutions, please read the following articles:
 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

I presumably have some of the most simple tests possible (samples created by the maven archetype plugin), and bumping scala by a single minor version is breaking them? Should I just stick with scala 2.8 until the maven tools catch up?

Answer

Nikita Volkov picture Nikita Volkov · Oct 10, 2012

Your artifact is outdated.

The latest version of Scala is 2.10. Currently ScalaTest is being distributed under different groupid and it supports the latest version of Scala. Here's the dependecy:

<dependency>
  <groupId>org.scalatest</groupId>
  <artifactId>scalatest_2.10</artifactId>
  <version>2.0.M5b</version>
  <scope>test</scope>
</dependency>

You will also require a different plugin:

  <plugin>
    <groupId>net.alchim31.maven</groupId>
    <artifactId>scala-maven-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
      <execution>
        <phase>compile</phase>
        <goals>
          <goal>compile</goal>
          <goal>testCompile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

You don't need to specify any repositories, since all those artifacts are being distributed with the central repo.

Here's an example of a complete pom of a project depending on the Scala 2.10.