Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running Android unit tests with Spock framework

I am using:

  • Android Studio 2.1.3
  • Gradle 2.14.1 (I tried with 2.14 also)
  • OpenJDK version "1.8.0_91"

I want to write some Unit tests with Groovy and Spock for sample Android application.

I have already read about RoboSpock.

When I am trying to run simple test:

package a.b.regex

class TestSum extends spock.lang.Specification {

    def "test adding some numbers"() {
        when:
        def a = 5 + 4

        then:
        a == 9
    }
}

When I try to run this test in Android Studio I have an error:

Process finished with exit code 1
Class not found: "a.b.regex.TestSum"Empty test suite.

Configurations that I used:

1)

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'org.codehaus.groovy:gradle-groovy-android-plugin:0.3.6'
    }
}

apply plugin: 'groovyx.grooid.groovy-android'
// ...
dependencies {
    testCompile 'org.robospock:robospock:1.0.0'
}

2)

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'org.codehaus.groovy:groovy-android-gradle-plugin:1.0.0'
    }
}

apply plugin: 'groovyx.android'
dependencies {
    testCompile "org.codehaus.groovy:groovy-all:2.4.1"
    testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
    testCompile 'org.codehaus.groovy:groovy:2.4.6:grooid'
}

From the console no tests are run at all. With testing Java applications I have no problem.

Here is the project code where I want to use Spock: GitHub repository

Thankfully to Pieces I found the answer.

You should use the following configuration:

apply plugin: 'groovyx.android'

buildscript {
    repositories {
        jcenter() // or mavenCentral, etc.
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'org.codehaus.groovy:groovy-android-gradle-plugin:1.0.0'
    }
}

testCompile 'org.codehaus.groovy:groovy:2.4.7:grooid'
testCompile('org.spockframework:spock-core:1.0-groovy-2.4') {
    exclude group: 'org.codehaus.groovy'
    exclude group: 'junit'
}
like image 235
Andrii Abramov Avatar asked Aug 27 '16 22:08

Andrii Abramov


People also ask

Is Spock better than JUnit?

The main difference between Spock and JUnit is in breadth of capabilities. Both frameworks can be used for unit testing. However, Spock offers much more — including mocking and integration testing. JUnit requires a third party library for mocking.

How do I run unit test on Android?

To run all tests in a class or a specific method, open the test file in the Code Editor and do either of the following: Press the Run test icon in the gutter. Right-click on the test class or method and click Run . Select the test class or method and use shortcut Control+Shift+R .

Does Spock run on JUnit?

Spock uses the JUnit runner infrastructure and therefore is compatible with all existing Java infrastructure. For example, code coverage with Spock is possible in the same way as JUnit.

What is Spock unit testing?

Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers.


2 Answers

1) This should work great other than you are using an outdated version of the groovy android plugin. The current version is 1.0.0. The error you are seeing is that you included your tests in androidTest source folder, when they should be included in the test source folder.

2) You do not want groovy-all, and want to exclude that from the spock transitive dependencies as well.

This would look similar to

dependencies {
    testCompile 'org.codehaus.groovy:groovy:2.4.7:grooid'
    testCompile('org.spockframework:spock-core:1.0-groovy-2.4') {
      exclude group: 'org.codehaus.groovy'
      exclude group: 'junit'
    }
  }

Same as the problem with #1 you probably have the source under androidTest folder instead of the test folder.

The androidTest folder is for test that will run on the device, and the test folder if for tests that will run on your machines JVM.

like image 80
Pieces Avatar answered Sep 22 '22 05:09

Pieces


If you reached here trying to configure for gradle 6.6 this will help you:

I stepped multiple times into this while trying to configure Spock in android having gradle 6.6, there has been multiple changes in gradle, so they made this plugin deprecated 'groovyx.android': https://github.com/groovy/groovy-android-gradle-plugin

Deprecated: This plugin has been deprecated in favor of Kotlin which has the full support of JetBrains and Google. The changes that go into each Android Plugin Version make it really hard for this plugin to keep up. As of Gradle 6.0 this plugin does not work.

Found out that gradle have a separate plugin for groovy support: https://plugins.gradle.org/plugin/org.codehaus.groovy.android

This is the configuration for gradle 6.6 using groovy DSL for gradle

buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }

    dependencies {
        classpath "com.android.tools.build:gradle:4.0.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        classpath "gradle.plugin.org.codehaus.groovy:groovy-android-gradle-plugin:3.0.0"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

And then in the app configuration:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: "org.codehaus.groovy.android"


def groovyVersion = "3.0.5"
def spockVersion = "2.0-M3-groovy-3.0"
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.1'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
    testImplementation 'junit:junit:4.13'

    testImplementation("org.codehaus.groovy:groovy:${groovyVersion}")
    testImplementation("org.codehaus.groovy:groovy-all:${groovyVersion}")
    testImplementation("org.spockframework:spock-core:${spockVersion}")
    testImplementation("org.spockframework:spock-spring:${spockVersion}")


    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

}
like image 35
Damonio Avatar answered Sep 26 '22 05:09

Damonio