Программный вызов графа задачи Gradle в модульном тесте

Я нахожусь в процессе написания собственного плагина для 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 ответа

Мне кажется, что вы пытаетесь получить здесь скорее интеграционный тест, чем модульный тест. В прошлом члены команды Gradle предлагали мне, что при написании плагинов и заданий вы хотите отделить как можно больше смысла от вашего задания в POJO и выполнить его модульное тестирование. Для всего остального, что Gradle делает для вас и для сантехники, таких как выполнение графа задач, тестирование функций инкрементных задач и так далее, вы, вероятно, захотите провести интеграционные тесты, которые определенно медленнее, поэтому вы хотите проводить как можно больше модульных тестов.

Единственная проблема заключается в том, что в настоящее время Gradle не предоставляет набор инструментов для написания этих интеграционных тестов. Для этого есть спецификация дизайна, но в настоящее время вам все равно придется вручную разработать решение, если оно вам нужно.

Вы можете посмотреть тот, который я использовал здесь, но имейте в виду, что у него есть некоторые проблемы с classpath, поэтому эта строка необходима.

Пример другого решения, использующего GradleConnector и обнаруженного недавно, можно найти здесь.

Люк Дейли (Gradle core dev) разработал классную систему функционального тестирования для моих плагинов Gradle, которую можно увидеть здесь.

Подобно ответу @erdi, это решение для функционального тестирования, не использующее ProjectBuilder от Gradle. Это требует, чтобы вы включили эти служебные классы для тестирования.

Я понимаю, что это не тот краткий ответ, на который вы, возможно, надеялись, но эта система очень хорошо мне помогла, пока я разрабатывал несколько плагинов Gradle.

Заменить:

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

С:

task2.actions.each { Action action ->
     action.execute(task2)
}

Я использую этот метод для выполнения задач в тестах:

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
Другие вопросы по тегам