JAL-4167 Allow a test to run in multiple testTasks
[jalview.git] / build.gradle
index 84b84e7..c23ba06 100644 (file)
@@ -50,7 +50,7 @@ plugins {
   id "com.diffplug.gradle.spotless" version "3.28.0"
   id 'com.github.johnrengelman.shadow' version '4.0.3'
   id 'com.install4j.gradle' version '10.0.3'
-  id 'com.dorongold.task-tree' version '2.1.0' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
+  id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
   id 'com.palantir.git-version' version '0.13.0' apply false
 }
 
@@ -1064,7 +1064,7 @@ compileJava {
   // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
   sourceCompatibility = compile_source_compatibility
   targetCompatibility = compile_target_compatibility
-  options.compilerArgs = additional_compiler_args
+  options.compilerArgs += additional_compiler_args
   options.encoding = "UTF-8"
   doFirst {
     print ("Setting target compatibility to "+compile_target_compatibility+"\n")
@@ -1076,7 +1076,7 @@ compileJava {
 compileTestJava {
   sourceCompatibility = compile_source_compatibility
   targetCompatibility = compile_target_compatibility
-  options.compilerArgs = additional_compiler_args
+  options.compilerArgs += additional_compiler_args
   doFirst {
     print ("Setting target compatibility to "+targetCompatibility+"\n")
   }
@@ -1732,35 +1732,102 @@ task prepare {
 
 compileJava.dependsOn prepare
 run.dependsOn compileJava
-//run.dependsOn prepare
+compileTestJava.dependsOn compileJava
 
 
-//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
-test {
-  dependsOn prepare
-
-  if (useClover) {
-    dependsOn cloverClasses
-   } else { //?
-    dependsOn compileJava //?
+ext.testsFailed = false
+/* testTask0 is the main test task */
+task testTask0(type: Test) {
+  group = "Verification"
+  description = "The main test task. Runs all non-testTaskN-labelled tests (unless excluded)"
+  useTestNG() {
+    includeGroups testng_groups.split(",")
+    excludeGroups testng_excluded_groups.split(",")
+    tasks.withType(Test).matching {it.name.startsWith("testTask") && it.name != name}.all {t -> excludeGroups t.name}
+    preserveOrder true
+    useDefaultListeners=true
   }
+}
 
+/* separated tests */
+task testTask1(type: Test) {
+  group = "Verification"
+  description = "Tests that need to be isolated from the main test run"
   useTestNG() {
-    includeGroups testng_groups
-    excludeGroups testng_excluded_groups
+    includeGroups name
+    excludeGroups testng_excluded_groups.split(",")
     preserveOrder true
     useDefaultListeners=true
   }
+}
 
-  maxHeapSize = "4096m"
-  jvmArgs '-Xmx4096m', '-Xms4096m'
+/*
+ * adapted from https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c
+ * to summarise test results from all Test tasks
+ */
+/* START of test tasks results summary */
+import groovy.time.TimeCategory
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
 
-/* delete these! 
-  maxParallelForks = 1
-  forkEvery = 1
-  failFast = true
-  jvmArgs '-Xmx2048m', '-Xms2048m'
-*/
+rootProject.ext.testsResults = [] // Container for tests summaries
+
+tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { testTask ->
+
+  // from original test task
+  if (useClover) {
+    dependsOn cloverClasses
+  } else { //?
+    dependsOn testClasses //?
+  }
+
+  // run main tests first
+  if (!testTask.name.equals("testTask0"))
+    testTask.mustRunAfter "testTask0"
+
+  testTask.testLogging { logging ->
+    events TestLogEvent.FAILED,
+      TestLogEvent.SKIPPED,
+      TestLogEvent.STANDARD_OUT,
+      TestLogEvent.STANDARD_ERROR
+
+    exceptionFormat TestExceptionFormat.FULL
+    showExceptions true
+    showCauses true
+    showStackTraces true
+  }
+
+  ignoreFailures = true // Always try to run all tests for all modules
+
+  afterSuite { desc, result ->
+
+    if (desc.parent) return // Only summarize results for whole modules
+
+    String summary = "${testTask.project.name}:${testTask.name} results: ${result.resultType} " +
+      "(" +
+      "${result.testCount} tests, " +
+      "${result.successfulTestCount} successes, " +
+      "${result.failedTestCount} failures, " +
+      "${result.skippedTestCount} skipped" +
+      ") " +
+      "in ${TimeCategory.minus(new Date(result.endTime), new Date(result.startTime))}" +
+      "\n" +
+          "Report file: ${testTask.reports.html.entryPoint}"
+
+    // Add reports in `testsResults`, keep failed suites at the end
+    if (result.resultType == TestResult.ResultType.SUCCESS) {
+      rootProject.ext.testsResults.add(0, summary)
+    } else {
+      rootProject.ext.testsResults += summary
+    }
+
+    if (result.resultType == TestResult.ResultType.FAILURE) {
+      testsFailed = true
+    }
+  }
+
+  // from original test task
+  maxHeapSize = "1024m"
 
   workingDir = jalviewDir
   def testLaf = project.findProperty("test_laf")
@@ -1782,6 +1849,55 @@ test {
       println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
     }
   }
+
+}
+
+gradle.buildFinished {
+    def allResults = rootProject.ext.testsResults
+
+    if (!allResults.isEmpty()) {
+        printResults allResults
+    }
+}
+
+private static void printResults(allResults) {
+    def maxLength = allResults*.readLines().flatten().collect { it.length() }.max()
+
+    println "┌${"${"─" * maxLength}"}┐"
+
+    println allResults.collect {
+        it.readLines().collect {
+            "│" + it + " " * (maxLength - it.length()) + "│"
+        }.join("\n")
+    }.join("\n├${"${"─" * maxLength}"}┤\n")
+
+    println "└${"${"─" * maxLength}"}┘"
+}
+/* END of test tasks results summary */
+
+task verifyTestStatus {
+  group = "Verification"
+  description = "Task that FAILs the build if any tests failed"
+  doLast {
+    if (testsFailed) {
+      throw new GradleException("There were failing tests!")
+    }
+  }
+}
+
+test {
+  // from original test task
+  if (useClover) {
+    dependsOn cloverClasses
+  } else { //?
+    dependsOn testClasses
+  }
+  dependsOn tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}
+  finalizedBy verifyTestStatus
+
+
+  // not running tests in this task
+  exclude "**/*"
 }