From a2dc4546e8a2936d56cc4caa56b2fd8dc821206f Mon Sep 17 00:00:00 2001 From: Connor Date: Wed, 15 Feb 2023 19:11:18 -0500 Subject: [PATCH] Implement --test_filter support (#999) Implement `--test_filter` support, as detailed in https://github.com/bazelbuild/rules_swift/issues/997. This can be engaged via a `swift_test` target like so: ``` bazel test //:Tests --test_filter=TestModuleName.TestClassName/testMethodName ``` **Note:** If `--test_filter` is not passed into the test invocation, we fallback to the original behavior (pass `All` into the xctest invocation. --- doc/rules.md | 6 +++ examples/apple/test_filter/BUILD | 51 +++++++++++++++++++ examples/apple/test_filter/FailTests.swift | 8 +++ .../apple/test_filter/PassFailTests.swift | 12 +++++ examples/apple/test_filter/PassTests.swift | 8 +++ examples/apple/test_filter/TestHelper.swift | 20 ++++++++ swift/internal/swift_binary_test.bzl | 6 +++ tools/xctest_runner/xctest_runner.sh.template | 4 +- 8 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 examples/apple/test_filter/BUILD create mode 100644 examples/apple/test_filter/FailTests.swift create mode 100644 examples/apple/test_filter/PassFailTests.swift create mode 100644 examples/apple/test_filter/PassTests.swift create mode 100644 examples/apple/test_filter/TestHelper.swift diff --git a/doc/rules.md b/doc/rules.md index 83127405d..b90520d16 100644 --- a/doc/rules.md +++ b/doc/rules.md @@ -499,6 +499,12 @@ have the paths made absolute via swizzling by enabling the set the `BUILD_WORKSPACE_DIRECTORY` environment variable in your scheme to the root of your workspace (i.e. `$(SRCROOT)`). +A subset of tests for a given target can be executed via the `--test_filter` parameter: + +``` +bazel test //:Tests --test_filter=TestModuleName.TestClassName/testMethodName +``` + **ATTRIBUTES** diff --git a/examples/apple/test_filter/BUILD b/examples/apple/test_filter/BUILD new file mode 100644 index 000000000..b45876508 --- /dev/null +++ b/examples/apple/test_filter/BUILD @@ -0,0 +1,51 @@ +load( + "//swift:swift.bzl", + "swift_library", + "swift_test", +) + +swift_library( + name = "test_filter_lib", + testonly = True, + srcs = [ + "FailTests.swift", + "PassFailTests.swift", + "PassTests.swift", + "TestHelper.swift", + ], + module_name = "test_filter", + target_compatible_with = ["@platforms//os:macos"], +) + +# Verify that tests fail as expected without test filtering. +swift_test( + name = "test_filter__baseline", + env = { + "EXPECT_FAILURE": "TRUE", + }, + module_name = "test_filter", + target_compatible_with = ["@platforms//os:macos"], + deps = [":test_filter_lib"], +) + +# Verify that test scope is filtered by TARGET.TEST_CLASS as expected. +swift_test( + name = "test_filter__feature__target_class", + env = { + "TESTBRIDGE_TEST_ONLY": "test_filter.PassTests", + }, + module_name = "test_filter", + target_compatible_with = ["@platforms//os:macos"], + deps = [":test_filter_lib"], +) + +# Verify that test scope is filtered by TARGET.TEST_CLASS.TEST_METHOD as expected. +swift_test( + name = "test_filter__feature__target_class_method", + env = { + "TESTBRIDGE_TEST_ONLY": "test_filter.PassFailTests/test_pass", + }, + module_name = "test_filter", + target_compatible_with = ["@platforms//os:macos"], + deps = [":test_filter_lib"], +) diff --git a/examples/apple/test_filter/FailTests.swift b/examples/apple/test_filter/FailTests.swift new file mode 100644 index 000000000..f6ca990c9 --- /dev/null +++ b/examples/apple/test_filter/FailTests.swift @@ -0,0 +1,8 @@ +import XCTest + +class FailTests: XCTestCase { + + func test_fail() { + TestHelper.ExpectFailureIfNeeded() + } +} diff --git a/examples/apple/test_filter/PassFailTests.swift b/examples/apple/test_filter/PassFailTests.swift new file mode 100644 index 000000000..cbd2d9319 --- /dev/null +++ b/examples/apple/test_filter/PassFailTests.swift @@ -0,0 +1,12 @@ +import XCTest + +class PassFailTests: XCTestCase { + + func test_pass() { + TestHelper.Pass() + } + + func test_fail() { + TestHelper.ExpectFailureIfNeeded() + } +} diff --git a/examples/apple/test_filter/PassTests.swift b/examples/apple/test_filter/PassTests.swift new file mode 100644 index 000000000..47796d72b --- /dev/null +++ b/examples/apple/test_filter/PassTests.swift @@ -0,0 +1,8 @@ +import XCTest + +class PassTests: XCTestCase { + + func test_pass() { + TestHelper.Pass() + } +} diff --git a/examples/apple/test_filter/TestHelper.swift b/examples/apple/test_filter/TestHelper.swift new file mode 100644 index 000000000..3e7b9e9d6 --- /dev/null +++ b/examples/apple/test_filter/TestHelper.swift @@ -0,0 +1,20 @@ +import XCTest + +enum TestHelper { + + static func ExpectFailureIfNeeded() { + let options: XCTExpectedFailure.Options = .init() + options.isEnabled = ProcessInfo.processInfo.environment["EXPECT_FAILURE"] == "TRUE" + XCTExpectFailure("Expected failure", options: options) { + Fail() + } + } + + static func Pass() { + XCTAssertTrue(true) + } + + private static func Fail() { + XCTFail("Fail") + } +} diff --git a/swift/internal/swift_binary_test.bzl b/swift/internal/swift_binary_test.bzl index d8646d28e..7420cf87d 100644 --- a/swift/internal/swift_binary_test.bzl +++ b/swift/internal/swift_binary_test.bzl @@ -532,6 +532,12 @@ have the paths made absolute via swizzling by enabling the `"apple.swizzle_absolute_xcttestsourcelocation"` feature. You'll also need to set the `BUILD_WORKSPACE_DIRECTORY` environment variable in your scheme to the root of your workspace (i.e. `$(SRCROOT)`). + +A subset of tests for a given target can be executed via the `--test_filter` parameter: + +``` +bazel test //:Tests --test_filter=TestModuleName.TestClassName/testMethodName +``` """, executable = True, fragments = ["cpp"], diff --git a/tools/xctest_runner/xctest_runner.sh.template b/tools/xctest_runner/xctest_runner.sh.template index 11fd254c7..a760f5786 100644 --- a/tools/xctest_runner/xctest_runner.sh.template +++ b/tools/xctest_runner/xctest_runner.sh.template @@ -54,8 +54,8 @@ fi exit_status=0 xctest=$(xcrun -f xctest) -# TODO(allevato): Support Bazel's --test_filter. -DYLD_INSERT_LIBRARIES=$sanitizer_dyld_env LLVM_PROFILE_FILE="$profraw" $xctest -XCTest All "$bundle_path" || exit_status=$? +test_filter=${TESTBRIDGE_TEST_ONLY:-All} +DYLD_INSERT_LIBRARIES=$sanitizer_dyld_env LLVM_PROFILE_FILE="$profraw" $xctest -XCTest "$test_filter" "$bundle_path" || exit_status=$? if [[ "$exit_status" -ne 0 ]]; then exit "$exit_status"