Skip to content

Commit a8c3a7e

Browse files
committed
Respond to PR feedback
1 parent 3ecd884 commit a8c3a7e

File tree

1 file changed

+51
-46
lines changed

1 file changed

+51
-46
lines changed

proposals/testing/NNNN-targeted-interoperability-swift-testing-and-xctest.md

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ intermediate state where test helpers written using XCTest API are called from
1414
Swift Testing. Today, the Swift Testing and XCTest libraries stand mostly
1515
independently, which means an `XCTAssert` failure in a Swift Testing test is
1616
silently ignored. To address this, we formally declare a set of interoperability
17-
principles and propose updates to specific APIs that will enable users to
18-
migrate with confidence.
17+
principles and propose changes to the handling of specific APIs that will enable
18+
users to migrate with confidence.
1919

2020
## Motivation
2121

22-
Unfortunately, mixing an API call from one framework with a test from the other
23-
framework may not work as expected. As a more concrete example, if you take an
22+
Calling XCTest or Swift Testing API within a test from the opposite framework
23+
may not always work as expected. As a more concrete example, if you take an
2424
existing test helper function written for XCTest and call it in a Swift Testing
2525
test, it won't report the assertion failure:
2626

@@ -49,17 +49,16 @@ class FooTests: XCTestCase {
4949
Generally, we get into trouble today when ALL the following conditions are met:
5050

5151
- You call XCTest API in a Swift Testing test, or call Swift Testing API in a
52-
XCTest test
52+
XCTest test,
5353
- The API doesn't function as expected in some or all cases, and
5454
- You get no notice at build time or runtime about the malfunction
5555

56-
For the remainder of this proposal, we’ll describe tests which exhibit this
56+
For the remainder of this proposal, we’ll describe test APIs which exhibit this
5757
problem as **lossy without interop**.
5858

59-
If you've switched completely to Swift Testing and don't expect to use XCTest in
60-
the future, this proposal includes a mechanism to **prevent you from
61-
inadvertently introducing XCTest APIs to your project**, including via a testing
62-
library.
59+
This problem risks regressing test coverage for projects which migrate to Swift
60+
Testing. Furthermore, projects that have switched completely to Swift Testing
61+
may want to go and ensure they don't inadvertently add XCTest API.
6362

6463
## Proposed solution
6564

@@ -72,34 +71,34 @@ library.
7271
empowered to choose Swift Testing when writing new tests or test helpers, as
7372
it will work properly in both types of tests.
7473

75-
We don't propose supporting interoperability for APIs without risk of data loss,
76-
because they naturally have high visibility. For example, using `throw XCTSkip`
77-
in a Swift Testing test results in a test failure rather than a test skip,
78-
providing a clear indication that migration is needed.
74+
We don't propose supporting interoperability for APIs which are not lossy
75+
without interop, because they naturally have high visibility. For example, using
76+
`throw XCTSkip` in a Swift Testing test results in a test failure rather than a
77+
test skip, providing a clear indication that migration is needed.
7978

8079
## Detailed design
8180

8281
### Highlight and support XCTest APIs which are lossy without interop
8382

8483
We propose supporting the following XCTest APIs in Swift Testing:
8584

86-
- Assertions: `XCTAssert*` and [unconditional failure][] `XCTFail`
85+
- [Assertions][XCTest Assertions]: `XCTAssert*` and [unconditional failure][]
86+
`XCTFail`
8787
- [Expected failures][], such as `XCTExpectFailure`: marking a Swift Testing
8888
issue in this way will generate a runtime warning issue.
89-
- `XCTAttachment`
89+
- [`XCTAttachment`][XCTest attachments]
9090
- [Issue handling traits][]: we will make our best effort to translate issues
91-
from XCTest to Swift Testing. Note that there are certain issue kinds that are
92-
new to Swift Testing and not expressible from XCTest.
91+
from XCTest to Swift Testing. For issue details unique to XCTest, we will
92+
include them as a comment when constructing the Swift Testing issue.
9393

9494
Note that no changes are proposed for the `XCTSkip` API, because they already
95-
feature prominently as a test failure to be corrected when thrown in Swift
96-
Testing.
95+
feature prominently as a test failure when thrown in Swift Testing.
9796

9897
We also propose highlighting usage of above XCTest APIs in Swift Testing:
9998

10099
- **Report [runtime warning issues][]** for XCTest API usage in Swift Testing.
101-
This **applies to assertion successes AND failures**! We want to make sure you
102-
can identify opportunities to modernise even if your tests currently pass.
100+
This **applies to both assertion failures _and successes_**! This notifies you
101+
about opportunities to modernise even if your tests currently pass.
103102

104103
- Opt-in **strict interop mode**, where XCTest API usage will result in
105104
`fatalError("Usage of XCTest API in a Swift Testing context is not
@@ -122,7 +121,7 @@ We propose supporting the following Swift Testing APIs in XCTest:
122121
- `withKnownIssue`: marking an XCTest issue in this way will generate a runtime
123122
warning issue. In strict interop mode, this becomes a `fatalError`.
124123
- Attachments
125-
- [Test cancellation][] (links to pitch)
124+
- [Test cancellation][] (currently pitched)
126125

127126
We think developers will find utility in using Swift Testing APIs in XCTest. For
128127
example, you can replace `XCTAssert` with `#expect` in your XCTest tests and
@@ -133,13 +132,13 @@ Testing at your own pace.
133132
Present and future Swift Testing APIs will be supported in XCTest if the
134133
XCTest API _already_ provides similar functionality.
135134

136-
- For example, we support the proposed Swift Testing [test cancellation][]
137-
feature in XCTest since it is analogous to `XCTSkip`.
135+
For example, the recently-pitched [test cancellation][] feature in Swift Testing
136+
is analogous to `XCTSkip`. If that pitch were accepted, this proposal would
137+
support interop of the new API with XCTest.
138138

139-
- On the other hand, [Traits][] are a powerful Swift Testing feature, and
140-
include the ability to [add tags][tags] to organise tests. Even though XCTest
141-
does not interact with tags, **this is beyond the scope of interoperability**
142-
because XCTest doesn't have existing “tag-like” behaviour to map onto.
139+
On the other hand, [traits][] are a powerful Swift Testing feature which is not
140+
related to any functionality in XCTest. Therefore, there would be
141+
interoperability for traits under this proposal.
143142

144143
Here are some concrete examples:
145144

@@ -151,8 +150,10 @@ Here are some concrete examples:
151150

152151
### Interoperability Modes
153152

154-
- **Warning-only**: This is for projects which do not want to see new test
155-
failures surfaced due to interoperability.
153+
- **Warning-only**: Test failures that were previously ignored are reported as
154+
runtime warning issues. It also includes runtime warning issues for XCTest API
155+
usage in a Swift Testing context. This is for projects which do not want to
156+
see new test failures surfaced due to interoperability.
156157

157158
- **Permissive**: This is the default interoperability mode, which surfaces test
158159
failures that were previously ignored. It also includes runtime warning issues
@@ -166,11 +167,11 @@ Here are some concrete examples:
166167
Configure the interoperability mode when running tests using the
167168
`SWIFT_TESTING_XCTEST_INTEROP_MODE` environment variable:
168169

169-
| Interop Mode | Issue behaviour across framework boundary | `SWIFT_TESTING_XCTEST_INTEROP_MODE` |
170-
| ------------ | ----------------------------------------------------------------- | ---------------------------------------------- |
171-
| Warning-only | XCTest API: ⚠️ Runtime Warning Issue | `warning-only` |
172-
| Permissive | XCTest API: ⚠️ Runtime Warning Issue. All Issues: ❌ Test Failure | `permissive`, or empty value, or invalid value |
173-
| Strict | XCTest API: 💥 `fatalError`. Swift Testing API: ❌ Test Failure | `strict` |
170+
| Interop Mode | Issue behaviour across framework boundary | `SWIFT_TESTING_XCTEST_INTEROP_MODE` |
171+
| ------------ | -------------------------------------------------------------------------- | ---------------------------------------------- |
172+
| Warning-only | XCTest API: ⚠️ Runtime Warning Issue. All Issues: ⚠️ Runtime Warning Issue | `warning-only` |
173+
| Permissive | XCTest API: ⚠️ Runtime Warning Issue. All Issues: ❌ Test Failure | `permissive`, or empty value, or invalid value |
174+
| Strict | XCTest API: 💥 `fatalError`. Swift Testing API: ❌ Test Failure | `strict` |
174175

175176
### Phased Rollout
176177

@@ -185,9 +186,9 @@ lead to situations where previously "passing" test code now starts showing
185186
failures. We believe this should be a net positive if it can highlight actual
186187
bugs you would have missed previously.
187188

188-
You can use `SWIFT_TESTING_XCTEST_INTEROP_MODE=off` in the short-term to revert
189-
back to the current behaviour. Refer to the "Interoperability Modes" section for
190-
a full list of options.
189+
You can use `SWIFT_TESTING_XCTEST_INTEROP_MODE=warning-only` in the short-term
190+
to revert any changes to test pass/fail outcomes as a result of
191+
interoperability.
191192

192193
## Integration with supporting tools
193194

@@ -218,8 +219,7 @@ Testing:
218219
API within helper methods.
219220

220221
- After new API is added to Swift Testing in future, will need to evaluate for
221-
interoperability with XCTest. Once strict mode is the default, we will no
222-
longer include interoperability for new Swift Testing features.
222+
interoperability with XCTest.
223223

224224
## Alternatives considered
225225

@@ -241,7 +241,7 @@ should make it clear that this is not intended to be a permanent measure.
241241

242242
In a similar vein, we considered `SWIFT_TESTING_XCTEST_INTEROP_MODE=off` as a
243243
way to completely turn off interoperability. Some projects may additionally have
244-
issue handling trait that promote warnings to errors, which means that
244+
an issue handling trait that promotes warnings to errors, which means that
245245
warning-only mode could still cause test failures.
246246

247247
However, in the scenario above, we think users who set up tests to elevate
@@ -256,8 +256,12 @@ the best choice. Making this the default would also send the clearest signal
256256
that we want users to migrate to Swift Testing.
257257

258258
However, we are especially sensitive to use cases that depend upon the currently
259-
lossy without interop APIs, and decided to prioritise the current default as a
260-
good balance between notifying users yet not breaking existing test suites.
259+
lossy without interop APIs. With strict interop mode, the test process will
260+
crash on the first instance of XCTest API usage in Swift Testing, completely
261+
halting testing. In this same scenario, the default permissive interop mode
262+
would record a runtime warning issue and continue the remaining test, which we
263+
believe strikes a better balance between notifying users yet not being totally
264+
disruptive to the testing flow.
261265

262266
### Alternative methods to control interop mode
263267

@@ -271,7 +275,7 @@ good balance between notifying users yet not breaking existing test suites.
271275
- **CLI option through SwiftPM:**
272276

273277
```
274-
swift test --interop-mode=warning
278+
swift test --interop-mode=warning-only
275279
```
276280

277281
This could be offered in addition to the proposed environment variable option,
@@ -282,11 +286,12 @@ good balance between notifying users yet not breaking existing test suites.
282286
Thanks to Stuart Montgomery, Jonathan Grynspan, and Brian Croom for feedback on
283287
the proposal.
284288

289+
[XCTest assertions]: https://developer.apple.com/documentation/xctest/equality-and-inequality-assertions
290+
[XCTest attachments]: https://developer.apple.com/documentation/xctest/adding-attachments-to-tests-activities-and-issues
285291
[unconditional failure]: https://developer.apple.com/documentation/xctest/unconditional-test-failures
286292
[runtime warning issues]: https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0013-issue-severity-warning.md
287293
[expected failures]: https://developer.apple.com/documentation/xctest/expected-failures
288294
[issue handling traits]: https://developer.apple.com/documentation/testing/issuehandlingtrait
289295
[test cancellation]: https://forums.swift.org/t/pitch-test-cancellation/81847
290296
[traits]: https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/traits
291-
[tags]: https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/addingtags
292297
[exit testing]: https://developer.apple.com/documentation/testing/exit-testing

0 commit comments

Comments
 (0)