How do I run both ScalaTest and JUnit tests with Gradle?
Asked Answered
O

4

21

I've got a mixed Java / Scala project with both JUnit and ScalaTest tests. With the scalatest plugin, Gradle runs the ScalaTest tests in src/test/scala, but ignores the JUnit tests in src/test/java. Without the plugin, Gradle runs the JUnit tests but ignores the Scala. What trick am I missing?

My build.gradle:

plugins {
  id 'java'
  id 'maven'
  id 'scala'
  id "com.github.maiflai.scalatest" version "0.6-5-g9065d91"
}

sourceCompatibility = 1.8

group = 'org.chrononaut'
version = '1.0-SNAPSHOT'

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

ext {
    scalaMajorVersion = '2.11'
    scalaVersion = "${scalaMajorVersion}.5"
}

repositories {
    mavenCentral()
    mavenLocal()
}

dependencies {
    compile "org.scala-lang:scala-library:${scalaVersion}"
    compile "org.scala-lang.modules:scala-xml_${scalaMajorVersion}:1.0.3"
    compile 'com.google.guava:guava:18.0'
    compile 'javax.xml.bind:jaxb-api:2.2.12'
    compile 'jaxen:jaxen:1.1.6'
    compile 'joda-time:joda-time:2.7'
    compile 'org.joda:joda-convert:1.7'
    compile 'org.apache.commons:commons-lang3:3.3.2'
    compile 'org.jdom:jdom2:2.0.5'

    testCompile 'junit:junit:4.12'
    testCompile 'org.easytesting:fest-assert:1.4'
    testCompile 'org.mockito:mockito-core:1.10.19'
    testCompile "org.scalatest:scalatest_${scalaMajorVersion}:2.2.4"
    testRuntime 'org.pegdown:pegdown:1.1.0' // required by scalatest plugin
}

compileScala {
    scalaCompileOptions.additionalParameters = [
            "-feature",
            "-language:reflectiveCalls", // used for config structural typing
            "-language:postfixOps"
    ]
}

ETA: I know it's possible to annotate Scala tests to force them to run with the JUnit test runner. I'm looking for a one-stop build.gradle solution that doesn't require editing every test file (or messing with the tests to get around limitations in the build system, in general).

Olla answered 18/2, 2015 at 19:35 Comment(4)
What happens if you remove com.github.maiflai.scalatest and what does it fix?Wrongdoer
If I remove com.github.maiflai.scalatest then the Scala tests don't get run, only the JUnit ones (see original post).Olla
Maybe if you slap on this to make ScalaTests run with Gradle: @RunWith(classOf[org.scalatest.junit.JUnitRunner])Wrongdoer
Sorry about the bad reading of the original post...Wrongdoer
O
12

Another alternative to running with JUnit (and to creating an Ant task as suggested in comments) - is creating a task that runs ScalaTest's Runner directly:

task scalaTest(dependsOn: ['testClasses'], type: JavaExec) {
  main = 'org.scalatest.tools.Runner'
  args = ['-R', 'build/classes/test', '-o']
  classpath = sourceSets.test.runtimeClasspath
}

test.dependsOn scalaTest // so that running "test" would run this first, then the JUnit tests
Outmarch answered 5/7, 2016 at 8:51 Comment(0)
M
10
  1. Get rid of the plugin, as it makes test task to run ScalaTest only (so JUnit gets ignored).
  2. Annotate your ScalaTests with @RunWith(classOf[JUnitRunner])so they can be run by gradle as JUnit tests.
Mysticism answered 13/10, 2015 at 9:51 Comment(2)
I'm aware of that option (and it was also suggested in comments), but I don't think I should have to edit every test file to get this to work.Olla
Then you should extend your build and add a new task (e.g. scalaTest.mustRunAfter test) and employ Ant task under the hood. Something like issues.gradle.org/browse/GRADLE-2659. This way gradle check will run both JUnit tests and ScalaTests.Mysticism
B
4

With the latest version of scala-test plugin you can choose whether the existing (junit)-test task is replaced or not by the scala-tests-task. In your case you could use the following in

gradle.properties:

com.github.maiflai.gradle-scalatest.mode = append

Now you can execute both tests:

  • junit: gradle test
  • scala-test: gradle scalatest

or combine them into one task

task allTests {
    dependsOn test
    dependsOn scalatest
}

That worked for me.

Branham answered 24/7, 2018 at 15:11 Comment(0)
M
1

There is an easier solution these days. You can just specify multiple junit test engines in useJUnitPlatform using scalatest-junit-runner for scala:

dependencies {
    // junit platform
    testRuntimeOnly("org.junit.platform:junit-platform-engine")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")

    // junit5 engine
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
    // junit4 engine
    testRuntimeOnly("org.junit.vintage:junit-vintage-engine")
    // scalatest engine
    testRuntimeOnly("co.helmethair:scalatest-junit-runner")
}

test {
    useJUnitPlatform {
        includeEngines "junit-jupiter", "junit-vintage", "scalatest"
        testLogging {
            events("passed", "skipped", "failed")
        }
    }
}

You can even implement your own similar to ScalatestEngine this library provides.

One more useful link https://github.com/junit-team/junit5-samples/blob/main/junit5-migration-gradle/README.md

Matabele answered 26/9, 2022 at 15:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.