From 72c002c5497194cd21ae3f961dd80978778b8cf4 Mon Sep 17 00:00:00 2001 From: Nik <31962595+niktishakov@users.noreply.github.com> Date: Sat, 17 Oct 2026 18:48:50 +0700 Subject: [PATCH 1/2] Run every test runner in the Android emulator tests With Swift Build, each test target has its own test runner. The script ran them with the glob ./*-test-runner, so the shell passed the other runners as arguments to the first one and only the first test target ran. In swift-foundation, FoundationInternationalizationTests and FoundationMacrosTests didn't run on the emulator. Run the test runners one at a time, and add a second test target to TestPackage so that the emulator tests cover more than one runner. Fixes #277. --- .../scripts/android/android-emulator-tests.sh | 28 +++++++++++-------- tests/TestPackage/Package.swift | 4 +++ tests/TestPackage/Package@swift-5.10.swift | 4 +++ tests/TestPackage/Package@swift-5.9.swift | 4 +++ tests/TestPackage/Package@swift-6.0.swift | 4 +++ .../Tests/Target2Tests/Target2Tests.swift | 18 ++++++++++++ 6 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 tests/TestPackage/Tests/Target2Tests/Target2Tests.swift diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index fc267f4f..b4a01170 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -160,19 +160,25 @@ log "Copy Swift test package to emulator" ANDROID_TMP_FOLDER="/data/local/tmp/${STAGING_DIR}" adb push "${STAGING_DIR}" "${ANDROID_TMP_FOLDER}" -TEST_CMD="./*-test-runner" -if ! find "${STAGING_DIR}" -name '*-test-runner' -maxdepth 1 | grep -q .; then - TEST_CMD="./*.xctest" +# Each test target has its own test runner, so run them one at a time: +# with a glob, the shell would pass the other runners as arguments to the first one. +TEST_RUNNERS=$(cd "${STAGING_DIR}" && find . -maxdepth 1 -name '*-test-runner' | sort) +if [[ -z "${TEST_RUNNERS}" ]]; then + TEST_RUNNERS=$(cd "${STAGING_DIR}" && find . -maxdepth 1 -name '*.xctest' | sort) fi + TEST_SHELL="cd ${ANDROID_TMP_FOLDER}" -TEST_SHELL="${TEST_SHELL} && ${TEST_CMD} --testing-library xctest" - -# Run test cases a second time with the Swift Testing library -# We additionally need to handle the special exit code -# EXIT_NO_TESTS_FOUND (69 on Android), which can happen -# when the tests link to Testing, but no tests are executed -# see: https://github.com/swiftlang/swift-package-manager/blob/main/Sources/Commands/SwiftTestCommand.swift#L1571 -TEST_SHELL="${TEST_SHELL} && ${TEST_CMD} --testing-library swift-testing && [ \$? -eq 0 ] || [ \$? -eq 69 ]" +for TEST_RUNNER in ${TEST_RUNNERS}; do + TEST_SHELL="${TEST_SHELL} && echo 'Running ${TEST_RUNNER}'" + TEST_SHELL="${TEST_SHELL} && ${TEST_RUNNER} --testing-library xctest" + + # Run test cases a second time with the Swift Testing library + # We additionally need to handle the special exit code + # EXIT_NO_TESTS_FOUND (69 on Android), which can happen + # when the tests link to Testing, but no tests are executed + # see: https://github.com/swiftlang/swift-package-manager/blob/main/Sources/Commands/SwiftTestCommand.swift#L1571 + TEST_SHELL="${TEST_SHELL} && { ${TEST_RUNNER} --testing-library swift-testing; status=\$?; [ \$status -eq 0 ] || [ \$status -eq 69 ]; }" +done log "Run Swift package tests" diff --git a/tests/TestPackage/Package.swift b/tests/TestPackage/Package.swift index 079bbb33..8459a54c 100644 --- a/tests/TestPackage/Package.swift +++ b/tests/TestPackage/Package.swift @@ -18,6 +18,10 @@ let package = Package( name: "Target1Tests", dependencies: ["Target1"] ), + .testTarget( + name: "Target2Tests", + dependencies: ["Target2"] + ), .target(name: "theDocs"), ] ) diff --git a/tests/TestPackage/Package@swift-5.10.swift b/tests/TestPackage/Package@swift-5.10.swift index d3951721..7bf0dc68 100644 --- a/tests/TestPackage/Package@swift-5.10.swift +++ b/tests/TestPackage/Package@swift-5.10.swift @@ -18,5 +18,9 @@ let package = Package( name: "Target1Tests", dependencies: ["Target1"] ), + .testTarget( + name: "Target2Tests", + dependencies: ["Target2"] + ), ] ) diff --git a/tests/TestPackage/Package@swift-5.9.swift b/tests/TestPackage/Package@swift-5.9.swift index 46e43c6a..470e00fb 100644 --- a/tests/TestPackage/Package@swift-5.9.swift +++ b/tests/TestPackage/Package@swift-5.9.swift @@ -18,5 +18,9 @@ let package = Package( name: "Target1Tests", dependencies: ["Target1"] ), + .testTarget( + name: "Target2Tests", + dependencies: ["Target2"] + ), ] ) diff --git a/tests/TestPackage/Package@swift-6.0.swift b/tests/TestPackage/Package@swift-6.0.swift index 3c244dc3..fdf4f160 100644 --- a/tests/TestPackage/Package@swift-6.0.swift +++ b/tests/TestPackage/Package@swift-6.0.swift @@ -18,5 +18,9 @@ let package = Package( name: "Target1Tests", dependencies: ["Target1"] ), + .testTarget( + name: "Target2Tests", + dependencies: ["Target2"] + ), ] ) diff --git a/tests/TestPackage/Tests/Target2Tests/Target2Tests.swift b/tests/TestPackage/Tests/Target2Tests/Target2Tests.swift new file mode 100644 index 00000000..34d54b7d --- /dev/null +++ b/tests/TestPackage/Tests/Target2Tests/Target2Tests.swift @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import Target2 +import Testing + +@Test func example() async throws { + bar() +} From 2daea042a4fbad82b8aae2586f9cb478f44ab85d Mon Sep 17 00:00:00 2001 From: Nik <31962595+niktishakov@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:47:26 +0700 Subject: [PATCH 2/2] Keep running Android test runners after a failure Separate the commands with `;` so that a failing runner doesn't stop the others, and keep a `failed` flag so the job still fails if any runner failed. --- .../scripts/android/android-emulator-tests.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index b4a01170..974d5d11 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -167,18 +167,20 @@ if [[ -z "${TEST_RUNNERS}" ]]; then TEST_RUNNERS=$(cd "${STAGING_DIR}" && find . -maxdepth 1 -name '*.xctest' | sort) fi -TEST_SHELL="cd ${ANDROID_TMP_FOLDER}" +# Run every runner even if an earlier one fails, and fail at the end if any of them failed. +TEST_SHELL="cd ${ANDROID_TMP_FOLDER} || exit 1; failed=0" for TEST_RUNNER in ${TEST_RUNNERS}; do - TEST_SHELL="${TEST_SHELL} && echo 'Running ${TEST_RUNNER}'" - TEST_SHELL="${TEST_SHELL} && ${TEST_RUNNER} --testing-library xctest" + TEST_SHELL="${TEST_SHELL}; echo 'Running ${TEST_RUNNER}'" + TEST_SHELL="${TEST_SHELL}; ${TEST_RUNNER} --testing-library xctest || failed=1" # Run test cases a second time with the Swift Testing library # We additionally need to handle the special exit code # EXIT_NO_TESTS_FOUND (69 on Android), which can happen # when the tests link to Testing, but no tests are executed # see: https://github.com/swiftlang/swift-package-manager/blob/main/Sources/Commands/SwiftTestCommand.swift#L1571 - TEST_SHELL="${TEST_SHELL} && { ${TEST_RUNNER} --testing-library swift-testing; status=\$?; [ \$status -eq 0 ] || [ \$status -eq 69 ]; }" + TEST_SHELL="${TEST_SHELL}; ${TEST_RUNNER} --testing-library swift-testing; status=\$?; [ \$status -eq 0 ] || [ \$status -eq 69 ] || failed=1" done +TEST_SHELL="${TEST_SHELL}; [ \$failed -eq 0 ]" log "Run Swift package tests"