diff --git a/README.md b/README.md index 53dc3714..a8a2fd8a 100644 --- a/README.md +++ b/README.md @@ -55,15 +55,16 @@ exportUnityPackage { inputFiles file('Assets') } -test { +testEditMode { // unity 5.5 // categories = [...,] // filter = [...,] // verbose = true - // teamcity = false - - // unity 5.6 - // testPlatform + // teamcity = false +} + +// only runs on > 5.5 +testPlayMode { } task(performBuild, type:wooga.gradle.unity.tasks.Unity) { @@ -106,7 +107,9 @@ The plugin will add a number of tasks you can use | activateUnity | | `wooga.gradle.unity.tasks.Activate` | Activates unity with provides credentials. Gets skipped when credentials are missing | | returnUnityLicense | | `wooga.gradle.unity.tasks.ReturnLicense` | Returns the current licesne to license server. Gets skipped when license directory is empty | | exportUnityPackage | activationTask, setup | `wooga.gradle.unity.tasks.UnityPackage` | exports configured assets into an `.unitypackage` file | -| test | activationTask, setup | `wooga.gradle.unity.tasks.Test` | runs unity editor tests and writes reports to `reportsDir` | +| test | testEditMode, testPlayMode | `DefaultTask` | runs editMode and playMode tasks | +| testEditMode | activationTask, setup | `wooga.gradle.unity.tasks.Test` | runs unity editor tests and writes reports to `reportsDir` | +| testPlayMode | activationTask, setup | `wooga.gradle.unity.tasks.Test` | runs unity playMode tests and writes reports to `reportsDir` | | setup | | `DefaultTask` | lifecycle task to initialize unity project and all dependencies | | assembleResources | setup | `DefaultTask` | copies all android/ios dependencies to the unity `Plugins` folder | diff --git a/build.gradle b/build.gradle index b3017725..f51fb2a6 100644 --- a/build.gradle +++ b/build.gradle @@ -79,6 +79,7 @@ dependencies { } compile 'org.apache.maven:maven-artifact:3.0.3' + compile "org.yaml:snakeyaml:1.17" compile gradleApi() compile localGroovy() } @@ -126,4 +127,4 @@ project.tasks.publishPlugins.mustRunAfter project.tasks.postRelease project.tasks.snapshot.dependsOn project.tasks.publishToMavenLocal -project.tasks.publishToMavenLocal.mustRunAfter project.tasks.postRelease \ No newline at end of file +project.tasks.publishToMavenLocal.mustRunAfter project.tasks.postRelease diff --git a/src/integrationTest/groovy/wooga/gradle/unity/TestIntegrationSpec.groovy b/src/integrationTest/groovy/wooga/gradle/unity/TestIntegrationSpec.groovy index b276c945..d21faa27 100644 --- a/src/integrationTest/groovy/wooga/gradle/unity/TestIntegrationSpec.groovy +++ b/src/integrationTest/groovy/wooga/gradle/unity/TestIntegrationSpec.groovy @@ -17,6 +17,7 @@ package wooga.gradle.unity +import spock.lang.IgnoreIf import wooga.gradle.unity.batchMode.BatchModeFlags class TestIntegrationSpec extends UnityIntegrationSpec { @@ -221,4 +222,32 @@ class TestIntegrationSpec extends UnityIntegrationSpec { !result.standardOutput.contains(BatchModeFlags.EDITOR_TEST_VERBOSE_LOG + " teamcity") } + @IgnoreIf({ os.windows }) + def "can set testPlatform to playMode"() { + given: "a build script with fake test unity location" + buildFile << """ + task (mUnity, type: wooga.gradle.unity.tasks.Test) { + testPlatform = "playmode" + } + """.stripIndent() + + and: "a mocked project setting" + def settings = createFile("ProjectSettings/ProjectSettings.asset") + settings << """ + PlayerSettings: + wiiUDrcBufferDisabled: 0 + wiiUProfilerLibPath: + playModeTestRunnerEnabled: 0 + actionOnDotNetUnhandledException: 1 + + """.stripIndent() + + and: "unity version > 5.5" + + when: + def result = runTasksSuccessfully("mUnity", "-PdefaultUnityTestVersion=2017.1.1f3") + + then: + result.standardOutput.contains("PlayMode tests not activated") + } } diff --git a/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy b/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy index 4c627cb6..3484ca8f 100644 --- a/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy +++ b/src/main/groovy/wooga/gradle/unity/UnityPlugin.groovy @@ -35,6 +35,7 @@ import org.gradle.api.specs.Spec import org.gradle.api.tasks.Delete import org.gradle.internal.reflect.Instantiator import org.gradle.language.base.plugins.LifecycleBasePlugin +import wooga.gradle.unity.batchMode.TestPlatform import wooga.gradle.unity.tasks.* import javax.inject.Inject @@ -43,6 +44,8 @@ import java.util.concurrent.Callable class UnityPlugin implements Plugin { static String TEST_TASK_NAME = "test" + static String TEST_EDITOMODE_TASK_NAME = "testEditMode" + static String TEST_PLAYMODE_TASK_NAME = "testPlayMode" static String ACTIVATE_TASK_NAME = "activateUnity" static String RETURN_LICENSE_TASK_NAME = "returnUnityLicense" static String EXPORT_PACKAGE_TASK_NAME = "exportUnityPackage" @@ -105,7 +108,7 @@ class UnityPlugin implements Plugin { BasePluginConvention convention = new BasePluginConvention(project) addLifecycleTasks() - addTestTask() + addTestTasks() addPackageTask() addActivateAndReturnLicenseTasks(extension) @@ -264,9 +267,17 @@ class UnityPlugin implements Plugin { project.tasks[BasePlugin.ASSEMBLE_TASK_NAME].dependsOn task } - private void addTestTask() { - def task = project.tasks.create(name: TEST_TASK_NAME, type: Test, group: GROUP) - project.tasks[LifecycleBasePlugin.CHECK_TASK_NAME].dependsOn task + private void addTestTasks() { + def editModeTask = project.tasks.create(name: TEST_EDITOMODE_TASK_NAME, type: Test, group: GROUP) as Test + editModeTask.testPlatform = TestPlatform.editmode + + def playModeTask = project.tasks.create(name: TEST_PLAYMODE_TASK_NAME, type: Test, group: GROUP) as Test + playModeTask.testPlatform = TestPlatform.playmode + + def testTask = project.tasks.create(name: TEST_TASK_NAME, group: GROUP) + testTask.dependsOn editModeTask, playModeTask + + project.tasks[LifecycleBasePlugin.CHECK_TASK_NAME].dependsOn testTask } private void addDefaultReportTasks(final UnityPluginExtension extension) { diff --git a/src/main/groovy/wooga/gradle/unity/tasks/Test.groovy b/src/main/groovy/wooga/gradle/unity/tasks/Test.groovy index bbb6b4e8..e558e48c 100644 --- a/src/main/groovy/wooga/gradle/unity/tasks/Test.groovy +++ b/src/main/groovy/wooga/gradle/unity/tasks/Test.groovy @@ -23,11 +23,7 @@ import org.gradle.api.internal.ClosureBackedAction import org.gradle.api.internal.file.FileResolver import org.gradle.api.logging.Logging import org.gradle.api.reporting.Reporting -import org.gradle.api.tasks.Console -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.StopExecutionException -import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.* import org.gradle.internal.reflect.Instantiator import org.gradle.process.ExecSpec import org.gradle.util.GUtil @@ -36,6 +32,7 @@ import wooga.gradle.unity.batchMode.TestPlatform import wooga.gradle.unity.testing.UnityTestTaskReport import wooga.gradle.unity.testing.UnityTestTaskReportsImpl import wooga.gradle.unity.utils.NUnitReportNormalizer +import wooga.gradle.unity.utils.ProjectSettings import javax.inject.Inject @@ -204,7 +201,7 @@ class Test extends AbstractUnityTask implements Reporting { //https://issues.jenkins-ci.org/browse/JENKINS-44072 protected void normalizeTestResult() { File report = this.getReports().getXml().getDestination() - if(report.exists()) { + if (report.exists()) { def result = NUnitReportNormalizer.normalize(report) logger.info("NUnitReportNormalizer result ${result}") } @@ -262,6 +259,11 @@ class Test extends AbstractUnityTask implements Reporting { } testArgs << BatchModeFlags.TEST_PLATFORM << testPlatform + + if (testPlatform == TestPlatform.playmode && !getPlayModeTestsEnabled()) { + throw new StopExecutionException("PlayMode tests not activated for this project. please activate playMode tests first") + } + } else { throw new StopExecutionException("Unit test feature not supported with unity version: ${unityVersion.toString()}") } @@ -269,12 +271,12 @@ class Test extends AbstractUnityTask implements Reporting { } DefaultArtifactVersion getUnityVersion(File path) { - if(unityVersion != null) { + if (unityVersion != null) { return unityVersion } String osName = System.getProperty("os.name").toLowerCase() - def versionString = "5.5.0" + def versionString = project.properties.get("defaultUnityTestVersion", "5.5.0") if (osName.contains("mac os x")) { File infoPlist = new File(path.parentFile.parentFile, "Info.plist") @@ -318,4 +320,11 @@ class Test extends AbstractUnityTask implements Reporting { unityVersion = new DefaultArtifactVersion(versionString.split(/f|p/).first()) unityVersion } + + + boolean getPlayModeTestsEnabled() { + def file = new File(projectPath, "ProjectSettings/ProjectSettings.asset") + def settings = new ProjectSettings(file) + return settings.playModeTestRunnerEnabled + } } diff --git a/src/main/groovy/wooga/gradle/unity/utils/ProjectSettings.groovy b/src/main/groovy/wooga/gradle/unity/utils/ProjectSettings.groovy new file mode 100644 index 00000000..28b94813 --- /dev/null +++ b/src/main/groovy/wooga/gradle/unity/utils/ProjectSettings.groovy @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Wooga GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + + +package wooga.gradle.unity.utils + +import org.yaml.snakeyaml.Yaml + +class ProjectSettings { + + private def content + + ProjectSettings(File projectSettingsFile) { + this(projectSettingsFile.text) + } + + ProjectSettings(String templateContent) { + + Yaml parser = new Yaml() + content = parser.load(templateContent) + } + + boolean getPlayModeTestRunnerEnabled() { + content['PlayerSettings'] && content['PlayerSettings']['playModeTestRunnerEnabled'] && content['PlayerSettings']['playModeTestRunnerEnabled'] == 1 + } +} diff --git a/src/test/groovy/wooga/gradle/unity/UnityPluginSpec.groovy b/src/test/groovy/wooga/gradle/unity/UnityPluginSpec.groovy index e97c3e77..7f0aa11c 100644 --- a/src/test/groovy/wooga/gradle/unity/UnityPluginSpec.groovy +++ b/src/test/groovy/wooga/gradle/unity/UnityPluginSpec.groovy @@ -20,7 +20,9 @@ package wooga.gradle.unity import nebula.test.PluginProjectSpec import nebula.test.ProjectSpec import org.gradle.api.DefaultTask +import org.gradle.language.base.plugins.LifecycleBasePlugin import spock.lang.Unroll +import wooga.gradle.unity.batchMode.TestPlatform import wooga.gradle.unity.tasks.Test import wooga.gradle.unity.tasks.UnityPackage @@ -60,12 +62,37 @@ class UnityPluginSpec extends ProjectSpec { where: taskName | taskType - UnityPlugin.TEST_TASK_NAME | Test + UnityPlugin.TEST_TASK_NAME | DefaultTask + UnityPlugin.TEST_EDITOMODE_TASK_NAME | Test + UnityPlugin.TEST_PLAYMODE_TASK_NAME | Test UnityPlugin.EXPORT_PACKAGE_TASK_NAME | UnityPackage UnityPlugin.ASSEMBLE_RESOURCES_TASK_NAME | DefaultTask UnityPlugin.SETUP_TASK_NAME | DefaultTask } + @Unroll("configure as test task #taskName #testPlatform") + def 'configures tasks for platform '(String taskName, TestPlatform testPlatform) { + given: + assert !project.plugins.hasPlugin(PLUGIN_NAME) + assert !project.tasks.findByName(taskName) + + when: + project.plugins.apply(PLUGIN_NAME) + + then: + def task = project.tasks.findByName(taskName) as Test + task.testPlatform == testPlatform + def testTask = project.tasks.findByName(UnityPlugin.TEST_TASK_NAME) + testTask.dependsOn.contains(task) + def checkTask = project.tasks.findByName(LifecycleBasePlugin.CHECK_TASK_NAME) + checkTask.dependsOn.contains(testTask) + + where: + taskName | testPlatform + UnityPlugin.TEST_EDITOMODE_TASK_NAME | TestPlatform.editmode + UnityPlugin.TEST_PLAYMODE_TASK_NAME | TestPlatform.playmode + } + @Unroll def 'adds pluginToAdd #pluginToAdd'(String pluginToAdd) { given: diff --git a/src/test/groovy/wooga/gradle/unity/utils/ProjectSettingsSpec.groovy b/src/test/groovy/wooga/gradle/unity/utils/ProjectSettingsSpec.groovy new file mode 100644 index 00000000..006f143d --- /dev/null +++ b/src/test/groovy/wooga/gradle/unity/utils/ProjectSettingsSpec.groovy @@ -0,0 +1,71 @@ +package wooga.gradle.unity.utils + +import spock.lang.Specification +import spock.lang.Shared +import spock.lang.Unroll + +class ProjectSettingsSpec extends Specification { + + static String TEMPLATE_CONTENT = """ + +PlayerSettings: + wiiUDrcBufferDisabled: 0 + wiiUProfilerLibPath: + playModeTestRunnerEnabled: 0 + actionOnDotNetUnhandledException: 1 + + """ + + static String TEMPLATE_CONTENT_ENABLED = """ + +PlayerSettings: + wiiUDrcBufferDisabled: 0 + wiiUProfilerLibPath: + playModeTestRunnerEnabled: 1 + actionOnDotNetUnhandledException: 1 + + """ + + @Shared + File templateFile = File.createTempFile("ProjectSettings", ".asset") + + @Unroll + def "initialize with #objectType"() { + expect: + new ProjectSettings(content) + + where: + objectType | content + "String" | TEMPLATE_CONTENT + "File" | templateFile << TEMPLATE_CONTENT + } + + @Unroll + def "parse playModeTestRunnerDisabled with #objectType"() { + when: + def settings =new ProjectSettings(content) + + then: + !settings.playModeTestRunnerEnabled + + where: + objectType | content + "String" | TEMPLATE_CONTENT + "File" | templateFile << TEMPLATE_CONTENT + } + + @Unroll + def "parse playModeTestRunnerEnabled with #objectType"() { + when: + def settings =new ProjectSettings(content) + + then: + settings.playModeTestRunnerEnabled + + where: + objectType | content + "String" | TEMPLATE_CONTENT_ENABLED + "File" | templateFile << TEMPLATE_CONTENT_ENABLED + } + +}