Plugin development: How to programmatically "run" a Gradle project in the unit tests?


(sander) #1

Hey guys,

Let’s say I’m writing a unit test (well, I am):

@Test
  public void testWeb() throws Exception {
    Project project = ProjectBuilder.builder().build();
    project.getPlugins().apply(WarPlugin.class);
    project.getPlugins().apply(RebelPlugin.class);
          // Configure the rebel plugin
    RebelDslMain rebelExtension = (RebelDslMain) project.getExtensions().getByName(RebelPlugin.REBEL_EXTENSION_NAME);
      // [set some configuration properties on my extension]
      // HERE .. here i want to somehow say "run this project" (or at least, finish the configuration phase)
      RebelGenerateTask task = (RebelGenerateTask) project.getTasks().getByName(RebelPlugin.GENERATE_REBEL_TASK_NAME);
      // execute the task
    task.generate();
      // [ a bunch of asserts that i want to actually test]
    }

My problem is that, although i can “run” my task by hand (by calling it’s @TaskAction method “generate()” by hand), my task is not totally configured as in the real situation, as the project’s “afterEvaluate” method is not called (and my plugin is using that callback to propagate a lot of plugin-specific configuration from the extension class to the task class). Could I simulate this somehow or what would be the right thing for me to do?

Thanks! :slight_smile:


Writing unit/integration tests for Gradle plugins
(Peter Niederwieser) #2

‘ProjectBuilder’ is meant for lower-level (plugin) tests that don’t actually execute the build. Higher-level tests can make use of the tooling API to kick off real builds. There is a plan to provide more testing support out-of-the-box, but it’s not yet available.


(sander) #3

Ok thanks, I’ll have a look for the tooling API for higher level tests.

Meanwhile, I at least managed to pull off something dirty to make my tests run the “afterEvaluated” block of my plugin and thus behave quite like the real situation… obviously dirty and internal-API-dependendent:

@Test
  public void testWeb() throws Exception {
    Project project = ProjectBuilder.builder().build();
    // [set up my project]
      // [artificial call to 'afterEvaluated()']
    ProjectStateInternal projectState = new ProjectStateInternal();
    projectState.executed();
    ProjectEvaluationListener evaluationListener = ((AbstractProject) project).getProjectEvaluationBroadcaster();
    evaluationListener.afterEvaluate(project, projectState);
      // execute the task
    task.generate();
      // [ a bunch of asserts that i want to actually test]
  }