diff --git a/.github/workflows/scripts/android/android-emulator-tests.sh b/.github/workflows/scripts/android/android-emulator-tests.sh index fc267f4f..974d5d11 100755 --- a/.github/workflows/scripts/android/android-emulator-tests.sh +++ b/.github/workflows/scripts/android/android-emulator-tests.sh @@ -160,19 +160,27 @@ 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 ]" + +# 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 || 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 ] || failed=1" +done +TEST_SHELL="${TEST_SHELL}; [ \$failed -eq 0 ]" log "Run Swift package tests" diff --git a/.github/workflows/swift_package_test.yml b/.github/workflows/swift_package_test.yml index ef199946..1fd06459 100644 --- a/.github/workflows/swift_package_test.yml +++ b/.github/workflows/swift_package_test.yml @@ -766,7 +766,8 @@ jobs: - name: Checkout swiftlang/github-workflows repository uses: actions/checkout@v7 with: - repository: swiftlang/github-workflows + repository: niktishakov/github-workflows + ref: fork-test-android-pass path: github-workflows - name: Determine script-root path id: script_path 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() +}