Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions doc/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -726,10 +726,20 @@ root of your workspace (i.e. `$(SRCROOT)`).

### Test Filtering

A subset of tests for a given target can be executed via the `--test_filter` parameter:
`swift_test` supports Bazel's `--test_filter` flag on all platforms (i.e., Apple
and Linux), which can be used to run only a subset of tests. The expected filter
format is the same as Xcode's `xctest` tool:

```
bazel test //:Tests --test_filter=TestModuleName.TestClassName/testMethodName
* `ModuleName`: Run only the test classes/methods in module `ModuleName`.
* `ModuleName.ClassName`: Run only the test methods in class
`ModuleName.ClassName`.
* `ModuleName.ClassName/testMethodName`: Run only the method `testMethodName`
in class `ModuleName.ClassName`.

Multiple such filters can be separated by commas. For example:

```shell
bazel test --test_filter=AModule,BModule.SomeTests,BModule.OtherTests/testX //my/package/...
```

**ATTRIBUTES**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ swift_library(
"TestHelper.swift",
],
module_name = "test_filter",
target_compatible_with = ["@platforms//os:macos"],
)

# Verify that tests fail as expected without test filtering.
Expand All @@ -20,8 +19,7 @@ swift_test(
env = {
"EXPECT_FAILURE": "TRUE",
},
module_name = "test_filter",
target_compatible_with = ["@platforms//os:macos"],
module_name = "test_filter__baseline",
deps = [":test_filter_lib"],
)

Expand All @@ -31,8 +29,7 @@ swift_test(
env = {
"TESTBRIDGE_TEST_ONLY": "test_filter.PassTests",
},
module_name = "test_filter",
target_compatible_with = ["@platforms//os:macos"],
module_name = "test_filter__feature__target_class",
deps = [":test_filter_lib"],
)

Expand All @@ -42,7 +39,6 @@ swift_test(
env = {
"TESTBRIDGE_TEST_ONLY": "test_filter.PassFailTests/test_pass",
},
module_name = "test_filter",
target_compatible_with = ["@platforms//os:macos"],
module_name = "test_filter__feature__target_class_method",
deps = [":test_filter_lib"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ import XCTest
enum TestHelper {

static func ExpectFailureIfNeeded() {
#if canImport(Darwin)
let options: XCTExpectedFailure.Options = .init()
options.isEnabled = ProcessInfo.processInfo.environment["EXPECT_FAILURE"] == "TRUE"
XCTExpectFailure("Expected failure", options: options) {
Fail()
}
#else
// https://github.com/swiftlang/swift-corelibs-xctest/issues/348
if ProcessInfo.processInfo.environment["EXPECT_FAILURE"] != "TRUE" {
Fail()
}
#endif
}

static func Pass() {
Expand Down
16 changes: 13 additions & 3 deletions swift/swift_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,20 @@ root of your workspace (i.e. `$(SRCROOT)`).

### Test Filtering

A subset of tests for a given target can be executed via the `--test_filter` parameter:
`swift_test` supports Bazel's `--test_filter` flag on all platforms (i.e., Apple
and Linux), which can be used to run only a subset of tests. The expected filter
format is the same as Xcode's `xctest` tool:

```
bazel test //:Tests --test_filter=TestModuleName.TestClassName/testMethodName
* `ModuleName`: Run only the test classes/methods in module `ModuleName`.
* `ModuleName.ClassName`: Run only the test methods in class
`ModuleName.ClassName`.
* `ModuleName.ClassName/testMethodName`: Run only the method `testMethodName`
in class `ModuleName.ClassName`.

Multiple such filters can be separated by commas. For example:

```shell
bazel test --test_filter=AModule,BModule.SomeTests,BModule.OtherTests/testX //my/package/...
```
""",
executable = True,
Expand Down
18 changes: 17 additions & 1 deletion tools/test_discoverer/TestPrinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ struct TestPrinter {

var contents = """
import BazelTestObservation
import Foundation
import XCTest

@main
Expand All @@ -162,11 +163,26 @@ struct TestPrinter {
"""
}

// Bazel's `--test_filter` flag is passed to the test binary via the `TESTBRIDGE_TEST_ONLY`
// environment variable. Below, we read that value if it is present and pass it to `XCTMain`,
// where it behaves the same as the `-XCTest` flag value in Xcode's `xctest` tool.
//
// Note that `XCTMain` treats `arguments` as an actual command line, meaning that `arguments[0]`
// is expected to be the binary's path. So we only do the test filter logic if we've already
// been passed no other arguments. This lets the test binary still support other XCTest flags
// like `--list-tests` or `--dump-tests-json` if the user wishes to use those directly.
contents += """
if let xmlObserver = BazelXMLTestObserver.default {
XCTestObservationCenter.shared.addTestObserver(xmlObserver)
}
XCTMain(tests)

var arguments = CommandLine.arguments
if arguments.count == 1,
let testFilter = ProcessInfo.processInfo.environment["TESTBRIDGE_TEST_ONLY"]
{
arguments.append(testFilter)
}
XCTMain(tests, arguments: arguments)
}
}

Expand Down
2 changes: 1 addition & 1 deletion tools/xctest_runner/xctest_runner.sh.template
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
set -euo pipefail

# This test script is used as the executable output of a `swift_test` rule when
# building macOS targets (unless the "swift.bundled_tests" feature is disabled)
# building macOS targets (unless the target has `discover_tests = False`)
# because the test binary is an `MH_BUNDLE` that needs to be loaded dynamically
# and runtime reflection is used to locate the test methods.

Expand Down