com.stanfy.spoon.gradle.SpoonPlugin.groovy Maven / Gradle / Ivy
package com.stanfy.spoon.gradle
import com.android.build.gradle.AppPlugin
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryPlugin
import com.android.build.gradle.api.ApkVariantOutput
import com.android.build.gradle.api.TestVariant
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaBasePlugin
/**
* Gradle plugin for Spoon.
*/
class SpoonPlugin implements Plugin {
/** Task name prefix. */
private static final String TASK_PREFIX = "spoon"
@Override
void apply(final Project project) {
if (!project.plugins.findPlugin(AppPlugin) && !project.plugins.findPlugin(LibraryPlugin)) {
throw new IllegalStateException("Android plugin is not found")
}
project.extensions.add "spoon", SpoonExtension
def spoonTask = project.task(TASK_PREFIX) {
group = JavaBasePlugin.VERIFICATION_GROUP
description = "Runs all the instrumentation test variations on all the connected devices"
}
BaseExtension android = project.android
android.testVariants.all { TestVariant variant ->
String taskName = "${TASK_PREFIX}${variant.name.capitalize()}"
List tasks = createTask(variant, project, "")
tasks.each {
it.configure {
title = "$project.name $variant.name"
description = "Runs instrumentation tests on all the connected devices for '${variant.name}' variation and generates a report with screenshots"
}
}
spoonTask.dependsOn tasks
project.tasks.addRule(patternString(taskName)) { String ruleTaskName ->
if (ruleTaskName.startsWith(taskName)) {
String size = (ruleTaskName - taskName).toLowerCase(Locale.US)
if (isValidSize(size)) {
List sizeTasks = createTask(variant, project, size.capitalize())
sizeTasks.each {
it.configure {
title = "$project.name $variant.name - $size tests"
testSize = size
}
}
}
}
}
}
project.tasks.addRule(patternString("spoon")) { String ruleTaskName ->
if (ruleTaskName.startsWith("spoon")) {
String suffix = lowercase(ruleTaskName - "spoon")
if (android.testVariants.find { suffix.startsWith(it.name) } != null) {
// variant specific, not our case
return
}
String size = suffix.toLowerCase(Locale.US)
if (isValidSize(size)) {
def variantTaskNames = spoonTask.taskDependencies.getDependencies(spoonTask).collect() { it.name }
project.task(ruleTaskName, dependsOn: variantTaskNames.collect() { "${it}${size.capitalize()}" })
}
}
}
}
private static boolean isValidSize(String size) {
return size in ['small', 'medium', 'large']
}
private static String lowercase(final String s) {
return s[0].toLowerCase(Locale.US) + s.substring(1)
}
private static String patternString(final String taskName) {
return "Pattern: $taskName: run instrumentation tests of particular size"
}
private static List createTask(final TestVariant testVariant, final Project project, final String suffix) {
if (testVariant.outputs.size() > 1) {
throw new UnsupportedOperationException("Spoon plugin for gradle currently does not support abi/density splits for test apks")
}
SpoonExtension config = project.spoon
return testVariant.testedVariant.outputs.collect { def projectOutput ->
SpoonRunTask task = project.tasks.create("${TASK_PREFIX}${testVariant.name.capitalize()}${suffix}", SpoonRunTask)
task.configure {
group = JavaBasePlugin.VERIFICATION_GROUP
def instrumentationPackage = testVariant.outputs[0].outputFile
if (projectOutput instanceof ApkVariantOutput) {
applicationApk = projectOutput.outputFile
} else {
// This is a hack for library projects.
// We supply the same apk as an application and instrumentation to the soon runner.
applicationApk = instrumentationPackage
}
instrumentationApk = instrumentationPackage
File outputBase = config.baseOutputDir
if (!outputBase) {
outputBase = new File(project.buildDir, "spoon")
}
output = new File(outputBase, projectOutput.dirName)
debug = config.debug
ignoreFailures = config.ignoreFailures
devices = config.devices
allDevices = !config.devices
noAnimations = config.noAnimations
failIfNoDeviceConnected = config.failIfNoDeviceConnected
testSize = SpoonRunTask.TEST_SIZE_ALL
if (config.className) {
className = config.className
if (config.methodName) {
methodName = config.methodName
}
}
dependsOn projectOutput.assemble, testVariant.assemble
}
} as List
}
}