12

我正在为 gradle 编写自定义插件,作为单元测试的一部分,我想调用我的任务,但前提是它的先决任务已被执行。

不幸的是,实际的插件是一个内部项目,所以我不能确定确切的来源,但我准备了一个单元测试来演示这个问题:

package toy

import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.junit.Test

class ToyTasksTest {

    boolean task1Run = false
    boolean task2Run = false

    @Test
    public void taskDependencies(){


        Project p = ProjectBuilder.builder().build()

        p.task("task1") << {
            p.logger.info("task1 running")
            task1Run = true
        }

        def task2 = p.task("task2", dependsOn: 'task1') << {
            p.logger.info("task2 running")
            task2Run = true
        }
        task2.execute() // <--- what magic do I need here instead of .execute()

        assert task2Run == true
        assert task1Run == true
    }
}

输出是:

Assertion failed: 

assert task2Run == true
       |        |
       false    false

如果您想快速运行测试,可以在 github 上找到该项目。

另一种说法而不是写作方式:

task2.execute()

我想运行相当于:

gradle task2

在单元测试中。

4

4 回答 4

7

在我看来,您试图在这里获得的更多的是集成测试而不是单元测试。Gradle 团队成员过去曾向我建议,在编写插件和任务时,您想要做的是尽可能多地/有意义地从您的任务中分离到 POJO 并对其进行单元测试。对于 Gradle 为您和管道所做的所有其他事情,例如执行任务图、测试增量任务功能等等,您可能希望进行绝对较慢的集成测试,这就是您希望尽可能多地进行单元测试的原因。

唯一的问题是 Gradle 目前没有提供用于编写​​这些集成测试的工具集。有一个设计规范,但目前如果需要,您仍然必须手工制作解决方案。

你可以看看我在这里使用的那个,但请记住它有一些类路径问题,这就是为什么这条线是必要的。

我最近发现的另一个使用 GradleConnector 的解决方案的示例可以在这里找到。

于 2013-04-28T19:26:51.600 回答
3

Luke Daley(Gradle 核心开发人员)为我的 Gradle 插件开发了一个很酷的功能测试系统,在此处使用。

与@erdi 的回答类似,这是一个功能测试解决方案,不使用 Gradle 的 ProjectBuilder。它要求您包含这些实用程序类以进行测试。

我意识到这不是您可能希望的简洁答案,但是当我开发一些 Gradle 插件时,这个系统为我提供了很好的服务。

于 2013-04-29T02:20:38.440 回答
1

代替:

task2.execute() // <--- what magic do I need here instead of .execute()

和:

task2.actions.each { Action action ->
     action.execute(task2)
}
于 2014-06-02T16:41:58.170 回答
0

我使用这种方法在测试中执行任务:

void executeTask(Task task) {
    task.taskDependencies.getDependencies(task).each {
        subTask -> executeTask(subTask)
    }

    task.execute()
}

例子:

@Test
void testTasksDependency() {
    def first = project.task("first").doLast {
        println "Doing First"
    }

    def second = project.task("second", dependsOn: first).doLast {
        println "Doing Second"
    }

    def third = project.task("third", dependsOn: second).doLast {
        println "Doing Third"
    }

    // Let's call our method
    executeTask(third)

    assertTrue(first.state.executed)
    assertTrue(second.state.executed)
    assertTrue(third.state.executed)
}

输出:

Doing First
Doing Second
Doing Third
于 2017-04-17T14:26:14.600 回答