Search code examples
javakotlingradlecucumber

Error when I try to build tests with Gradle and Cucumber


I am trying to write functional tests using Cucumber lib, Unfortunately, I can't use Cucumber and Gradle together, an error occurs when building the tests. I am a real beginner in the Java environment. I use for this project: Kotlin / Gradle / Cucumber.

Here is what my build.gradle.kts looks like

import org.gradle.jvm.tasks.Jar

plugins {
    application
    `java-library`
    `maven-publish`
    signing
    jacoco
    kotlin("jvm") version "1.3.61"
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))

    testImplementation("org.mock-server:mockserver-netty:5.3.0")
    testImplementation("io.cucumber:cucumber-java8:7.0.0")
    testImplementation("io.cucumber:cucumber-junit:7.0.0")
}

tasks.register<Jar>("fatJar") {
    archiveFileName.set("${artifactName}-${artifactVersion}.jar")
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    manifest {
      attributes("Main-Class" to application.mainClassName)
    }
    from(configurations.runtimeClasspath.get()
        .onEach { println("Add from dependencies: ${it.name}") }
        .map { if (it.isDirectory) it else zipTree(it) })
    val sourcesMain = sourceSets.main.get()
    sourcesMain.allSource.forEach { println("Add from sources: ${it.name}") }
    from(sourcesMain.output)
}

tasks.register<Jar>("sourcesJar") {
    from(sourceSets.main.get().allJava)
    archiveClassifier.set("sources")
}

tasks.register("cucumber") {
     dependsOn compileTestKotlin
     doLast {
         javaexec {
             main = "io.cucumber.core.cli.Main"
             classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
         }
     }
}

here is the error

* What went wrong:
Script compilation errors:

  Line 104:      dependsOn compileTestKotlin
                           ^ Unresolved reference: compileTestKotlin

  Line 108:              classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
                                                    ^ Unresolved reference: cucumberRuntime

  Line 108:              classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
                                                                                      ^ Unresolved reference: output

  Line 108:              classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
                                                                                                               ^ Unresolved reference: output

4 errors

Thanks for your help.


Solution

  • Looks like you're trying to convert from the Groovy DSL to Kotlin. Remember that in the Kotlin DSL, everything is strongly typed since Kotlin is strongly typed.

    You need to wrap all tasks creations within the tasks { } block in order to access compileTestKotlin. Currently, the scope of this in your cucumber task registration is the task itself which is of type DefaultTask which does not know about compileTestKotlin.

    Additionally:

    • mainClassName is deprecated and mainClass should be used instead.
    • The java extension provides the capability to create sources JAR for you, so no need to create the task yourself unless you have specific requirements for the JAR which does not seem to be the case from your snippet.
    • Since the goal of the cucumber task is to execute a Java main class, you can utilize JavaExec as your task type instead of DefaultTask

    Polished sample (untested):

    plugins {
        id("org.jetbrains.kotlin.jvm") version "1.5.31"
        application
    }
    
    repositories {
        mavenCentral()
    }
    
    configurations {
        register("cucumberRuntime") {
            extendsFrom(testImplementation.get())
        }
    }
    
    dependencies {
        implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    
        testImplementation(platform("io.cucumber:cucumber-bom:7.2.3"))
        testImplementation("io.cucumber:cucumber-java8")
        testImplementation("io.cucumber:cucumber-junit")
    }
    
    java {
        withSourcesJar()
    }
    
    application {
        mainClass.set("io.mateo.ExampleKt")
    }
    
    tasks {
        register<Jar>("fatJar") {
            archiveFileName.set("foo-bar.jar")
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
            manifest {
                attributes("Main-Class" to application.mainClass.get())
            }
            from(configurations.runtimeClasspath.get()
                    .onEach { println("Add from dependencies: ${it.name}") }
                    .map { if (it.isDirectory) it else zipTree(it) })
            val sourcesMain = sourceSets.main.get()
            sourcesMain.allSource.forEach { println("Add from sources: ${it.name}") }
            from(sourcesMain.output)
        }
        register<JavaExec>("cucumber") {
            dependsOn(compileTestKotlin)
            mainClass.set("io.cucumber.core.cli.Main")
            classpath = configurations["cucumberRuntime"] + sourceSets.main.get().output + sourceSets.test.get().output
        }
    }
    

    References: