Протестируйте пользовательский плагин Gradle после оценки

Я разрабатываю собственный плагин Gradle, и у меня возникают проблемы с его тестированием.

Плагин создает расширение для получения конфигурации и после оценки (project.afterEvaluate {) создает задачи с полученной конфигурацией, эти значения @Input в задачах.

Следуя документации https://docs.gradle.org/current/userguide/custom_plugins.html чтобы создать тест для плагина, я использую следующее, чтобы создать проект и применить плагин

@Before fun setup() {
  project = ProjectBuilder.builder().build()
  project.pluginManager.apply("my.plugin.name")

а затем проверьте, было ли создано расширение:

assertTrue(project.extensions.findByName("name") is MyConfigType)

и задача создана:

assertTrue(project.tasks.findByName("mytask") is MyTaskType)

У меня проблема в том, что задача создается только afterEvaluate, поэтому этот тест не проходит. Насколько я понял, он должен быть afterEvaluate, чтобы он мог получать значения конфигурации.

Так что единственный способ увидеть, смогу ли я на тесте заставить этот проект быть оцененным, но как?

Может быть, есть другой способ получить значения?


person Budius    schedule 02.04.2020    source источник
comment
Я столкнулся с точно такой же проблемой. Удалось ли вам найти решение?   -  person dpr    schedule 26.08.2020
comment
извините @dpr, у меня ничего нет. В конце я извлек всю логику, которую мог, из жизненного цикла gradle, чтобы я мог протестировать ее изолированно и вручную проверить, работает ли эта часть.   -  person Budius    schedule 31.08.2020


Ответы (1)


Я разместил свой аналогичный вопрос на форумах Gradle и смог решить проблему: https://discuss.gradle.org/t/unit-test-plugins-afterevaulate/37437/3

Судя по всему, afterEvaluate не лучшее/правильное место для создания задачи. Если у вас есть DomainObjectCollection в вашем расширении и вы хотите создать задачу для каждого элемента в коллекции, создание задачи должно быть выполнено в all-Обратный вызов коллекции:

final MyExtension extension = project.getExtensions().create("extension", MyExtension.class);
extension.configurations.all((c) -> {
  // register task here
});

Если у вас есть простые свойства в расширении, которые передаются задаче в качестве входных данных, вы должны использовать ленивую настройку:

public class MyExtension { 
  public final Property<String> property;
  public final NamedDomainObjectContainer<Configuration> configurations;

  @Inject
  public MyExtension(final ObjectFactory objectFactory) {
    property = objectFactory.property(String.class).convention("value");
    configurations = objectFactory.domainObjectContainer(Configuration.class);
  }
}

public abstract class MyTask extends DefaultTask {

  @Input
  private final Property<String> property = getProject().getObjects().property(String.class);

  public Property<String> getProperty() {
    return property;
  }
}

И метод применения:

public class MyPlugin implements Plugin<Project> {

  @Override
  public void apply(final Project aProject) {
    final MyExtension extension = aProject.getExtensions().create("extension", MyExtension.class);
    aProject.getTasks().register("myTask", MyTask.class).configure((t) -> {
      t.getProperty().set(extension.property);
    });
  }
}
person dpr    schedule 01.09.2020