Skip to content

Commit 5fa2aec

Browse files
authored
Able to continue tests if one fails (#641)
Add new property `CONTINUE_ON_FAIL_FOR_TESTS_ENABLED`. When set to `1`, if one test fails, the build script will continue running the next test and provide a final report when all tests are finished. This currently works for - Unity Integration tests - Python tests This does not work for - Gradle test, ex. `testDownloadArtifacts` - NUnit test
1 parent a9636f7 commit 5fa2aec

File tree

1 file changed

+116
-17
lines changed

1 file changed

+116
-17
lines changed

build.gradle

+116-17
Original file line numberDiff line numberDiff line change
@@ -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
*/
941955
Task 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,
10001016
Task 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
*/
12731304
Task 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

14241523
task 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

18581957
createUnityTestBatchAndNonBatch(

0 commit comments

Comments
 (0)