Skip to content

Commit dc24e27

Browse files
committed
Minor changes
1 parent 2afaf8e commit dc24e27

File tree

1 file changed

+67
-44
lines changed

1 file changed

+67
-44
lines changed

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

Lines changed: 67 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Interoperability between Swift Testing and XCTest
1+
# Targeted Interoperability between Swift Testing and XCTest
22

33
- Proposal: [ST-NNNN](NNNN-xctest-interoperability.md)
44
- Authors: [Jerry Chen](https://github.com/jerryjrchen)
@@ -51,18 +51,15 @@ Generally, we get into trouble today when ALL the following conditions are met:
5151
- You call XCTest API in a Swift Testing test, or call Swift Testing API in a
5252
XCTest test
5353
- The API doesn't function as expected in some or all cases, and
54-
- You get no notice at build or runtime about the malfunction
55-
56-
Example: calling `XCTAssertEqual(x, y)` in a Swift Testing test: if x does not
57-
equal y, it should report a failure but does nothing instead.
54+
- You get no notice at build time or runtime about the malfunction
5855

5956
For the remainder of this proposal, we’ll describe tests which exhibit this
6057
problem as **lossy without interop**.
6158

6259
If you've switched completely to Swift Testing and don't expect to use XCTest in
6360
the future, this proposal includes a mechanism to **prevent you from
64-
inadvertently introducing XCTest APIs to your project, including via a testing
65-
library.**
61+
inadvertently introducing XCTest APIs to your project**, including via a testing
62+
library.
6663

6764
## Proposed solution
6865

@@ -90,7 +87,7 @@ We propose supporting the following XCTest APIs in Swift Testing:
9087

9188
- Assertions: `XCTAssert*` and [unconditional failure][] `XCTFail`
9289
- [Expected failures][], such as `XCTExpectFailure`: marking a Swift Testing
93-
issue in this way will generate a runtime issue.
90+
issue in this way will generate a runtime warning issue.
9491
- `XCTAttachment`
9592
- [Issue handling traits][]: we will make our best effort to translate issues
9693
from XCTest to Swift Testing. Note that there are certain issue kinds that are
@@ -104,16 +101,18 @@ We also propose highlighting usage of above XCTest APIs in Swift Testing:
104101

105102
- **Report [runtime warning issues][]** for XCTest API usage in Swift Testing.
106103
This **applies to assertion successes AND failures**! We want to make sure you
107-
can identify opportunities to modernise even if your tests currently all pass.
104+
can identify opportunities to modernise even if your tests currently pass.
108105

109-
- Opt-in **strict interop mode**, which will trigger a crash instead.
106+
- Opt-in **strict interop mode**, where XCTest API usage will result in
107+
`fatalError("Usage of XCTest API in a Swift Testing context is not
108+
supported")`.
110109

111110
Here are some concrete examples:
112111

113112
| When running a Swift Testing test... | Current | Proposed (default) | Proposed (strict) |
114113
| ------------------------------------ | --------------- | -------------------------------------------- | ----------------- |
115-
| `XCTAssert` failure is a ... | ‼️ No-op | ❌ Test Failure and ⚠️ Runtime Warning Issue | 💥 Crash |
116-
| `XCTAssert` success is a ... | No-op | ⚠️ Runtime Warning Issue | 💥 Crash |
114+
| `XCTAssert` failure is a ... | ‼️ No-op | ❌ Test Failure and ⚠️ Runtime Warning Issue | 💥 `fatalError` |
115+
| `XCTAssert` success is a ... | No-op | ⚠️ Runtime Warning Issue | 💥 `fatalError` |
117116
| `throw XCTSkip` is a ... | ❌ Test Failure | ❌ Test Failure | ❌ Test Failure |
118117

119118
### Limited support for Swift Testing APIs in XCTest
@@ -122,8 +121,8 @@ We propose supporting the following Swift Testing APIs in XCTest:
122121

123122
- `#expect` and `#require`
124123
- Includes [exit testing][]
125-
- `withKnownIssue`: when this suppresses `XCTAssert` failures, it will still
126-
show a runtime warning issue.
124+
- `withKnownIssue`: marking an XCTest issue in this way will generate a runtime
125+
warning issue. In strict interop mode, this becomes a `fatalError`.
127126
- Attachments
128127
- [Test cancellation][] (links to pitch)
129128

@@ -136,12 +135,12 @@ Testing at your own pace.
136135
Present and future Swift Testing APIs will be supported in XCTest if the
137136
XCTest API _already_ provides similar functionality.
138137

139-
- For example, we plan on supporting the proposed Swift Testing [test
140-
cancellation][] feature in XCTest since it is analogous to `XCTSkip`
138+
- For example, we support the proposed Swift Testing [test cancellation][]
139+
feature in XCTest since it is analogous to `XCTSkip`.
141140

142141
- On the other hand, [Traits][] are a powerful Swift Testing feature, and
143142
include the ability to [add tags][tags] to organise tests. Even though XCTest
144-
does not interact with tags, this is beyond the scope of interoperability
143+
does not interact with tags, **this is beyond the scope of interoperability**
145144
because XCTest doesn't have existing “tag-like” behaviour to map onto.
146145

147146
Here are some concrete examples:
@@ -150,38 +149,33 @@ Here are some concrete examples:
150149
| -------------------------------------------- | --------------- | ------------------------ | ----------------- |
151150
| `#expect` failure is a ... | ‼️ No-op | ❌ Test Failure | ❌ Test Failure |
152151
| `#expect` success is a ... | No-op | No-op | No-op |
153-
| `withKnownIssue` wrapping `XCTFail` is a ... | ❌ Test Failure | ⚠️ Runtime Warning Issue | 💥 Crash |
152+
| `withKnownIssue` wrapping `XCTFail` is a ... | ❌ Test Failure | ⚠️ Runtime Warning Issue | 💥 `fatalError` |
154153

155154
### Interoperability Modes
156155

157-
The default interoperability surfaces test failures that were previously
158-
ignored. We include two more permissible interoperability modes to avoid
159-
breaking projects that are dependent on this pre-interop behaviour.
156+
The default interoperability mode surfaces test failures that were previously
157+
ignored. We also include two alternative interoperability modes:
160158

161159
- **Warning-only**: This is for projects which do not want to see new test
162160
failures surfaced due to interoperability.
163161

164-
- **None**: Some projects may additionally have issue handling trait that
165-
promote warnings to errors, which means that warning-only mode could still
166-
cause test failures.
167-
168-
For projects that want to bolster their Swift Testing adoption, there is also an
169-
opt-in strict interop mode.
170-
171162
- **Strict**: Warning issues included in the default mode can be easily
172163
overlooked, especially in CI. The strict mode guarantees that no XCTest API
173164
usage occurs when running Swift Testing tests by turning those warnings into a
174-
runtime crash.
165+
`fatalError`.
175166

176167
Configure the interoperability mode when running tests using the
177-
`SWT_XCTEST_INTEROP_MODE` environment variable:
168+
`SWIFT_TESTING_XCTEST_INTEROP_MODE` environment variable:
169+
170+
| Interop Mode | Issue behaviour across framework boundary | `SWIFT_TESTING_XCTEST_INTEROP_MODE` |
171+
| ------------ | ----------------------------------------------------------------- | ------------------------------------------- |
172+
| Warning-only | ⚠️ Runtime Warning Issue for XCTest API usage | `warning` |
173+
| Default | ❌ Test Failure and ⚠️ Runtime Warning Issue for XCTest API usage | `default`, or empty value, or invalid value |
174+
| Strict | 💥 `fatalError` for XCTest API usage | `strict` |
178175

179-
| Interop Mode | Issue behaviour across framework boundary | `SWT_XCTEST_INTEROP_MODE` |
180-
| ------------ | -------------------------------------------- | ------------------------------------------- |
181-
| Off | ‼️ No-op (status quo) | `off` |
182-
| Warning-only | ⚠️ Runtime Warning Issue | `warning` |
183-
| Default | ❌ Test Failure and ⚠️ Runtime Warning Issue | `default`, or empty value, or invalid value |
184-
| Strict | 💥 Crash | `strict` |
176+
<!-- TODO: alternative name besides strict. It should reflect that, it does
177+
still have interop for SWT API in XCTest, but a hard failure going the other way
178+
around-->
185179

186180
### Phased Rollout
187181

@@ -196,15 +190,15 @@ lead to situations where previously "passing" test code now starts showing
196190
failures. We believe this should be a net positive if it can highlight actual
197191
bugs you would have missed previously.
198192

199-
You can use `SWT_XCTEST_INTEROP_MODE=off` in the short-term to revert back to
193+
You can use `SWIFT_TESTING_XCTEST_INTEROP_MODE=off` in the short-term to revert back to
200194
the current behaviour. Refer to the "Interoperability Modes" section for a full list
201195
of options.
202196

203197
## Integration with supporting tools
204198

205199
Interoperability will be first available in future toolchain version,
206200
hypothetically named `6.X`, where default interop mode will be enabled for
207-
projects. After that, a `6.Y` release would make strict interop mode the
201+
projects. After that, a `7.Y` release would make strict interop mode the
208202
default.
209203

210204
- Swift Package Manager projects: `swift-tools-version` declared in
@@ -214,8 +208,8 @@ default.
214208
- Xcode projects: Installed toolchain version will be used to determine interop
215209
mode.
216210

217-
- Any project can use `SWT_XCTEST_INTEROP_MODE` to override interop mode at
218-
runtime, provided they are on toolchain version `6.X` or newer
211+
- Any project can use `SWIFT_TESTING_XCTEST_INTEROP_MODE` to override interop
212+
mode at runtime, provided they are on toolchain version `6.X` or newer
219213

220214
## Future directions
221215

@@ -228,10 +222,9 @@ Testing:
228222
API usage, which would be challenging to do completely and find usages of this
229223
API within helper methods.
230224

231-
- After new API added to SWT in future, will need to evaluate for
232-
interoperability with XCTest until strict mode is the default. "strict" is
233-
kind of saying "from this point forward, no new interop will be added" for new
234-
SWT features.
225+
- After new API is added to Swift Testing in future, will need to evaluate for
226+
interoperability with XCTest. Once strict mode is the default, we will no
227+
longer include interoperability for new Swift Testing features.
235228

236229
## Alternatives considered
237230

@@ -249,6 +242,18 @@ helping users catch more bugs are too important to pass up. We've also included
249242
a plan to increase the strictness of the interoperability mode over time, which
250243
should make it clear that this is not intended to be a permanent measure.
251244

245+
### Opt-out of interoperability
246+
247+
In a similar vein, we considered `SWIFT_TESTING_XCTEST_INTEROP_MODE=off` as a
248+
way to completely turn off interoperability. Some projects may additionally have
249+
issue handling trait that promote warnings to errors, which means that
250+
warning-only mode could still cause test failures.
251+
252+
However, in the scenario above, we think users who set up tests to elevate
253+
warnings as errors would be interested in increased visibility of testing issues
254+
surfaced by interop. We're open to feedback about other scenarios where a
255+
"interop off" mode would be preferred.
256+
252257
### Strict interop mode as the default
253258

254259
We believe that for projects using only Swift Testing, strict interop mode is
@@ -259,6 +264,24 @@ However, we are especially sensitive to use cases that depend upon the currently
259264
lossy without interop APIs, and decided to prioritise the current default as a
260265
good balance between notifying users yet not breaking existing test suites.
261266

267+
### Alternative methods to control interop mode
268+
269+
- **Build setting:** e.g. a new `SwiftSetting` that can be included in
270+
Package.swift or an Xcode project. A project could then configure their test
271+
targets to have a non-default interop mode.
272+
273+
However, interop is a runtime concept, and would be difficult or at least
274+
non-idiomatic to modify with a build setting.
275+
276+
- **CLI option through SwiftPM:**
277+
278+
```
279+
swift test --interop-mode=warning-only
280+
```
281+
282+
This could be offered in addition to the proposed environment variable option,
283+
although it would be unclear which one should take precedence.
284+
262285
## Acknowledgments
263286

264287
Thanks to Stuart Montgomery, Jonathan Grynspan, and Brian Croom for feedback on

0 commit comments

Comments
 (0)