How to unit test gradle task?
Asked Answered
D

0

8

I want to test logic of my build.gradle script.
Excerpt of the script would be:

(...other tasks and methods...)
def readCustomerFile(File file) {
    def schema = <prepare schema>
    def report = schema.validate(JsonLoader.fromFile(file))
    if (!report.success) {
        throw new GradleException("File is not valid! " + report.toString())
    }
    return new groovy.json.JsonSlurper().parse(file)
}

task readFiles {
    mustRunAfter 'prepareCustomerProject'
    doLast {
        if (System.env.CUSTOMER_FILE_OVERRIDE) {
            project.ext.customerFileData = readCustomerFile(System.env.CUSTOMER_FILE_OVERRIDE)
        }
        else if (customerFile.exists()) {
            project.ext.customerFileData = readCustomerFile(customerFile)
        }
        else {
            throw new GradleException("Customer File is not provided! It is expected to be in CUSTOMER_FILE_OVERRIDE variable or in ${customerFile}")
        }
    }
}
(...other tasks and methods...)

I would like to test both method and task itself.
The 'prepareProject' task is quite lengthy in execution, but in 'real' setup it does magic necessary to set properties necessary for not only task above.
For testing I only want to e.g. set run readFiles task and validate results, making sure that either property on project was correctly set or exception was thrown.

I have looked into gradle test kit, but it is not what I need, as I was unable to find anything that would allow me to e.g. inspect project.
I have seen Guide for Testing Gradle Scripts, but this post is quite old and does not address my need / problem. I have also had a look at gradle docs Testing Build Logic with TestKit, but looking GradleRunner does not seem to offer any real inspection or project preparing abilities.
Plus, it would make us use jUnit, effectively adding whole classes structure only for testing purposes. Not clean and hard to maintain. Googling gradle + test + task and other variations finds tons of ways of running xUnit tests, but that's not what I need here.

Summarizing, what I need is:

  • test gradle tasks and methods from build.gradle in separation (test kit will run task with all its dependencies, I don't want this)
  • prepare project before test run (test kit does not seem to allow this)
  • verify task / method output

Has anyone successfully done this?
Or am I approaching this in a wrong way?
I'm fairly new to gradle, searching for good options to test my build scripts.

Doughty answered 29/3, 2018 at 14:53 Comment(3)
Here Gradle documentation how to write test for a custom task: docs.gradle.org/current/userguide/… I don't know how it would work for a task defined in script. It might be easier if you create a task class, it is also described in document.Squamulose
As previous comment hinted, you can organize logic like that in the buildSrc folder implicitly or as a custom plugin. The buildSrc folder defines an independent gradle project, so there you can add a build.gradle with any dependencies and tests you like. Else you are free to define a new task testReadFiles that runs after readFiles and check results, or a task that calls readCustomerFile() with some arguments and asserts the result. TestKit uses a temporary folder and allows you to make any changes to that folder, so not sure what "project preparing abilities" you miss.Supernaturalism
What I miss is ability to call my task in isolation. prepareCustomerProject task is doing some preparations (project specific) that are fairly long and not all needed for this task, but needed for tasks downstream. I would like to be able to set properties needed by readFiles tasks and run it without any dependencies.Doughty

© 2022 - 2024 — McMap. All rights reserved.