@@ -221,6 +221,16 @@ project.ext {
221221 interactiveModeTestsEnabled =
222222 findProperty(" INTERACTIVE_MODE_TESTS_ENABLED" , " 1" ) == " 1"
223223
224+ // Whether to continue to the next test if one fails.
225+ continueOnFailForTestsEnabled =
226+ findProperty(" CONTINUE_ON_FAIL_FOR_TESTS_ENABLED" , " 0" ) == " 1"
227+
228+ // List of failed tests
229+ failedTests = []
230+
231+ // List of passed tests
232+ passedTests = []
233+
224234 // Directory for intermediate and final build outputs.
225235 buildDir = new File (scriptDirectory, " build" )
226236 // Directory for external tools.
@@ -922,6 +932,9 @@ Task createNUnitTask(String name, String description, File testDll,
922932 args ([sprintf (" -output:%s" , logFile. absolutePath),
923933 sprintf (" -xml:%s" , xmlLogFile. absolutePath),
924934 testDll. absolutePath])
935+ // TODO: Support continueOnFailForTestsEnabled
936+ // NUnit test is currently broken. Need to fix it before implementing
937+ // continueOnFailForTestsEnabled
925938 }
926939 }
927940 }
@@ -935,19 +948,21 @@ Task createNUnitTask(String name, String description, File testDll,
935948 * @param dependsOn Tasks this depends upon.
936949 * @param executable Executable to run.
937950 * @param arguments Arguments for the executable.
951+ * @param continueOnFail Whether to ignore non-zero return code and continue.
938952 *
939953 * @returns Task which runs the specified executable.
940954 */
941955Task createExecTask (String name , String description ,
942956 Iterable<Task > dependsOn , File executableToRun ,
943- Iterable<String > arguments ) {
957+ Iterable<String > arguments , Boolean continueOnFail = false ) {
944958 Task execTask = tasks. create(name : name,
945959 description : description,
946960 type : Exec ,
947961 dependsOn : dependsOn)
948962 execTask. with {
949963 executable executableToRun
950964 args arguments
965+ ignoreExitValue continueOnFail
951966 }
952967 return execTask
953968}
@@ -989,6 +1004,7 @@ Task createEmptyTask(String taskName, String summary,
9891004 * @param batchMode Whether to run Unity in batch mode.
9901005 * @param createTaskClosure Optional task used to start Unity, this must
9911006 * conform to createExecTask()
1007+ * @param continueOnFail Whether to ignore non-zero return code and continue.
9921008 *
9931009 * @returns Task which executes Unity.
9941010 * The following extended properties are set on the task:
@@ -1000,7 +1016,8 @@ Task createEmptyTask(String taskName, String summary,
10001016Task createUnityTask (String taskName , String summary ,
10011017 Iterable<Task > dependsOn , String projectName ,
10021018 File projectContainerDir , Iterable<String > arguments ,
1003- Boolean batchMode , createTaskClosure ) {
1019+ Boolean batchMode , createTaskClosure ,
1020+ Boolean continueOnFail = false ) {
10041021 Boolean createProject = summary == " create"
10051022 File logFile = new File (projectContainerDir,
10061023 sprintf (" %s_%s.log" , projectName, summary))
@@ -1021,8 +1038,13 @@ Task createUnityTask(String taskName, String summary,
10211038 if (! createTaskClosure) {
10221039 createTaskClosure = {
10231040 String name, String description, Iterable<Task > depends,
1024- File executable, Iterable<String > args ->
1025- return createExecTask(name, description, depends, executable, args)
1041+ File executable, Iterable<String > args, Boolean contOnFail->
1042+ return createExecTask(name,
1043+ description,
1044+ depends,
1045+ executable,
1046+ args,
1047+ contOnFail)
10261048 }
10271049 }
10281050
@@ -1036,7 +1058,8 @@ Task createUnityTask(String taskName, String summary,
10361058 summary, projectName),
10371059 dependsOn,
10381060 project. ext. unityExe,
1039- executeArguments)
1061+ executeArguments,
1062+ continueOnFail)
10401063 }
10411064 unityTask. with {
10421065 outputs. files files(logFile)
@@ -1173,8 +1196,15 @@ Task createUnityTestTask(String taskName, String description,
11731196 setupTestProject. ext. projectDir. name,
11741197 setupTestProject. ext. containerDir,
11751198 additionalArguments, batchMode,
1176- createTaskClosure)
1199+ createTaskClosure,
1200+ true )
11771201 testTask. description = description
1202+ testTask. with {
1203+ finalizedBy reportAllTestsResult
1204+ doLast {
1205+ EvaluateTestResult (testTask)
1206+ }
1207+ }
11781208
11791209 // Create a clean task
11801210 Task cleanTestTask = tasks. create(name : sprintf (" clean%s" , taskName),
@@ -1267,13 +1297,15 @@ Task createInstallPythonPackageTask(String taskName, String description,
12671297 * @param script Python script to run.
12681298 * @param arguments Command line arguments to pass to the Python script.
12691299 * @param packages Optional Python packages to install.
1300+ * @param continueOnFail Whether to ignore non-zero return code and continue.
12701301 *
12711302 * @returns Task which executes Python.
12721303 */
12731304Task createPythonTask (String taskName , String description ,
12741305 Iterable<Task > dependsOn ,
12751306 File script , Iterable<String > arguments ,
1276- Iterable<String > packages ) {
1307+ Iterable<String > packages ,
1308+ Boolean continueOnFail = false ) {
12771309 List<Task > installPackagesTask = []
12781310 if (packages) {
12791311 installPackagesTask = [
@@ -1289,6 +1321,7 @@ Task createPythonTask(String taskName, String description,
12891321 description : sprintf (" Run Python to %s" , description),
12901322 type : Exec ,
12911323 dependsOn : (dependsOn + installPackagesTask + [" build_envs" ])). with {
1324+ ignoreExitValue continueOnFail
12921325 executable project. ext. pythonExe
12931326 args ([script. absolutePath] + arguments)
12941327 }
@@ -1389,37 +1422,103 @@ task testDownloadArtifacts(type: GradleBuild) {
13891422 dir " source/AndroidResolver/scripts"
13901423}
13911424
1392- createPythonTask(
1425+ /*
1426+ * Evaluate previously-ran test result
1427+ *
1428+ * @param testTask Task for previously-ran test
1429+ */
1430+ void EvaluateTestResult (Task testTask ) {
1431+ if (testTask. class. simpleName. startsWith(" Exec" )) {
1432+ if (testTask. execResult. exitValue != 0 ) {
1433+ String errorMsg = sprintf (" Test %s FAILED" , testTask. name)
1434+ println sprintf (" ::error::%s" , errorMsg)
1435+ project. ext. failedTests. add(testTask. name)
1436+ if (! project. ext. continueOnFailForTestsEnabled) {
1437+ throw new GradleException (errorMsg)
1438+ }
1439+ } else {
1440+ println sprintf (" ::debug::Test %s PASSED" , testTask. name, testTask. execResult. exitValue)
1441+ project. ext. passedTests. add(testTask. name)
1442+ }
1443+ }
1444+ }
1445+
1446+ Task reportAllTestsResult = tasks. create (
1447+ name : " reportAllTestsResult" ,
1448+ description : " Report the result all every test that has been run" ,
1449+ type : Task
1450+ ). with {
1451+ doLast {
1452+ project. ext. passedTests. each {
1453+ println sprintf (" Test %s PASSED" , it)
1454+ }
1455+ project. ext. failedTests. each {
1456+ println sprintf (" Test %s FAILED" , it)
1457+ }
1458+ if (project. ext. failedTests. size > 0 ) {
1459+ throw new GradleException (
1460+ sprintf (" %d out of %d tests failed" ,
1461+ project. ext. failedTests. size,
1462+ project. ext. failedTests. size + project. ext. passedTests. size))
1463+ }
1464+ }
1465+ }
1466+
1467+ Task testPackageUploader = createPythonTask(
13931468 " testPackageUploader" ,
13941469 " Test the unity_asset_uploader.py application." ,
13951470 [],
13961471 new File (project. ext. unityAssetUploaderDir, " unity_asset_uploader_test.py" ),
13971472 [],
1398- [])
1473+ [],
1474+ true ). with {
1475+ finalizedBy reportAllTestsResult
1476+ doLast {
1477+ EvaluateTestResult (testPackageUploader)
1478+ }
1479+ }
13991480
1400- createPythonTask(
1481+ Task testExportUnityPackage = createPythonTask(
14011482 " testExportUnityPackage" ,
14021483 " Test the export_unity_package.py application" ,
14031484 [],
14041485 new File (project. ext. exportUnityPackageDir, " export_unity_package_test.py" ),
14051486 [],
1406- exportUnityPackageRequirements)
1487+ exportUnityPackageRequirements,
1488+ true ). with {
1489+ finalizedBy reportAllTestsResult
1490+ doLast {
1491+ EvaluateTestResult (testExportUnityPackage)
1492+ }
1493+ }
14071494
1408- createPythonTask(
1495+ Task testGenGuids = createPythonTask(
14091496 " testGenGuids" ,
14101497 " Test the gen_guids.py application" ,
14111498 [],
14121499 new File (project. ext. exportUnityPackageDir, " gen_guids_test.py" ),
14131500 [],
1414- [" absl-py" ])
1501+ [" absl-py" ],
1502+ true ). with {
1503+ finalizedBy reportAllTestsResult
1504+ doLast {
1505+ EvaluateTestResult (testGenGuids)
1506+ }
1507+ }
14151508
1416- createPythonTask(
1509+ Task testImportUnityPackage = createPythonTask(
14171510 " testImportUnityPackage" ,
14181511 " Test the import_unity_package.py application" ,
14191512 [],
14201513 new File (project. ext. importUnityPackageDir, " import_unity_package_test.py" ),
14211514 [],
1422- [" absl-py" ])
1515+ [" absl-py" ],
1516+ true ). with {
1517+ finalizedBy reportAllTestsResult
1518+ doLast {
1519+ EvaluateTestResult (testImportUnityPackage)
1520+ }
1521+ }
14231522
14241523task updateEmbeddedGradleWrapper (type : Zip ) {
14251524 description " Update the gradle wrapper in gradle-template.zip"
@@ -1841,7 +1940,7 @@ createUnityTestBatchAndNonBatch(
18411940 " source/VersionHandlerImpl/test/webrequest" ),
18421941 [], [],
18431942 { String name, String description, Iterable<Task > depends,
1844- File executable, Iterable<String > args ->
1943+ File executable, Iterable<String > args, Boolean continueOnFail ->
18451944 Iterable<String > runnerArgs = [executable. absolutePath] + args
18461945 return createPythonTask(
18471946 name, description, depends,
@@ -1852,7 +1951,7 @@ createUnityTestBatchAndNonBatch(
18521951 " test" ),
18531952 " webrequest_launcher.py" ),
18541953 runnerArgs,
1855- [])
1954+ [], continueOnFail )
18561955 })
18571956
18581957createUnityTestBatchAndNonBatch(
0 commit comments