@@ -14,13 +14,13 @@ intermediate state where test helpers written using XCTest API are called from
14
14
Swift Testing. Today, the Swift Testing and XCTest libraries stand mostly
15
15
independently, which means an ` XCTAssert ` failure in a Swift Testing test is
16
16
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.
19
19
20
20
## Motivation
21
21
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
24
24
existing test helper function written for XCTest and call it in a Swift Testing
25
25
test, it won't report the assertion failure:
26
26
@@ -49,17 +49,16 @@ class FooTests: XCTestCase {
49
49
Generally, we get into trouble today when ALL the following conditions are met:
50
50
51
51
- You call XCTest API in a Swift Testing test, or call Swift Testing API in a
52
- XCTest test
52
+ XCTest test,
53
53
- The API doesn't function as expected in some or all cases, and
54
54
- You get no notice at build time or runtime about the malfunction
55
55
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
57
57
problem as ** lossy without interop** .
58
58
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.
63
62
64
63
## Proposed solution
65
64
@@ -72,38 +71,37 @@ library.
72
71
empowered to choose Swift Testing when writing new tests or test helpers, as
73
72
it will work properly in both types of tests.
74
73
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.
79
78
80
79
## Detailed design
81
80
82
81
### Highlight and support XCTest APIs which are lossy without interop
83
82
84
83
We propose supporting the following XCTest APIs in Swift Testing:
85
84
86
- - Assertions: ` XCTAssert* ` and [ unconditional failure] [ ] ` XCTFail `
85
+ - [ Assertions] [ XCTest Assertions ] : ` XCTAssert* ` and [ unconditional failure] [ ]
86
+ ` XCTFail `
87
87
- [ Expected failures] [ ] , such as ` XCTExpectFailure ` : marking a Swift Testing
88
88
issue in this way will generate a runtime warning issue.
89
- - ` XCTAttachment `
89
+ - [ ` XCTAttachment ` ] [ XCTest attachments ]
90
90
- [ 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 .
93
93
94
94
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.
97
96
98
97
We also propose highlighting usage of above XCTest APIs in Swift Testing:
99
98
100
99
- ** 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.
103
102
104
103
- Opt-in ** strict interop mode** , where XCTest API usage will result in
105
- `fatalError("Usage of XCTest API in a Swift Testing context is not
106
- supported")`.
104
+ ` fatalError("Usage of XCTest API in a Swift Testing context is unsupported") ` .
107
105
108
106
Here are some concrete examples:
109
107
@@ -122,7 +120,7 @@ We propose supporting the following Swift Testing APIs in XCTest:
122
120
- ` withKnownIssue ` : marking an XCTest issue in this way will generate a runtime
123
121
warning issue. In strict interop mode, this becomes a ` fatalError ` .
124
122
- Attachments
125
- - [ Test cancellation] [ ] (links to pitch )
123
+ - [ Test cancellation] [ ] (currently pitched )
126
124
127
125
We think developers will find utility in using Swift Testing APIs in XCTest. For
128
126
example, you can replace ` XCTAssert ` with ` #expect ` in your XCTest tests and
@@ -133,13 +131,13 @@ Testing at your own pace.
133
131
Present and future Swift Testing APIs will be supported in XCTest if the
134
132
XCTest API _ already_ provides similar functionality.
135
133
136
- - For example, we support the proposed Swift Testing [ test cancellation] [ ]
137
- feature in XCTest since it is analogous to ` XCTSkip ` .
134
+ For example, the recently-pitched [ test cancellation] [ ] feature in Swift Testing
135
+ is analogous to ` XCTSkip ` . If that pitch were accepted, this proposal would
136
+ support interop of the new API with XCTest.
138
137
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.
138
+ On the other hand, [ traits] [ ] are a powerful Swift Testing feature which is not
139
+ related to any functionality in XCTest. Therefore, there would be
140
+ interoperability for traits under this proposal.
143
141
144
142
Here are some concrete examples:
145
143
@@ -151,8 +149,10 @@ Here are some concrete examples:
151
149
152
150
### Interoperability Modes
153
151
154
- - ** Warning-only** : This is for projects which do not want to see new test
155
- failures surfaced due to interoperability.
152
+ - ** Warning-only** : Test failures that were previously ignored are reported as
153
+ runtime warning issues. It also includes runtime warning issues for XCTest API
154
+ usage in a Swift Testing context. This is for projects which do not want to
155
+ see new test failures surfaced due to interoperability.
156
156
157
157
- ** Permissive** : This is the default interoperability mode, which surfaces test
158
158
failures that were previously ignored. It also includes runtime warning issues
@@ -166,11 +166,11 @@ Here are some concrete examples:
166
166
Configure the interoperability mode when running tests using the
167
167
` SWIFT_TESTING_XCTEST_INTEROP_MODE ` environment variable:
168
168
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 ` |
169
+ | Interop Mode | Issue behaviour across framework boundary | ` SWIFT_TESTING_XCTEST_INTEROP_MODE ` |
170
+ | ------------ | -------------------------------------------------------------------------- | ---------------------------------------------- |
171
+ | Warning-only | XCTest API: ⚠️ Runtime Warning Issue. All Issues: ⚠️ 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 ` |
174
174
175
175
### Phased Rollout
176
176
@@ -185,9 +185,9 @@ lead to situations where previously "passing" test code now starts showing
185
185
failures. We believe this should be a net positive if it can highlight actual
186
186
bugs you would have missed previously.
187
187
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 .
188
+ You can use ` SWIFT_TESTING_XCTEST_INTEROP_MODE=warning-only ` in the short-term
189
+ to revert any changes to test pass/fail outcomes as a result of
190
+ interoperability .
191
191
192
192
## Integration with supporting tools
193
193
@@ -218,8 +218,7 @@ Testing:
218
218
API within helper methods.
219
219
220
220
- 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.
221
+ interoperability with XCTest.
223
222
224
223
## Alternatives considered
225
224
@@ -241,7 +240,7 @@ should make it clear that this is not intended to be a permanent measure.
241
240
242
241
In a similar vein, we considered ` SWIFT_TESTING_XCTEST_INTEROP_MODE=off ` as a
243
242
way to completely turn off interoperability. Some projects may additionally have
244
- issue handling trait that promote warnings to errors, which means that
243
+ an issue handling trait that promotes warnings to errors, which means that
245
244
warning-only mode could still cause test failures.
246
245
247
246
However, in the scenario above, we think users who set up tests to elevate
@@ -256,8 +255,12 @@ the best choice. Making this the default would also send the clearest signal
256
255
that we want users to migrate to Swift Testing.
257
256
258
257
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.
258
+ lossy without interop APIs. With strict interop mode, the test process will
259
+ crash on the first instance of XCTest API usage in Swift Testing, completely
260
+ halting testing. In this same scenario, the default permissive interop mode
261
+ would record a runtime warning issue and continue the remaining test, which we
262
+ believe strikes a better balance between notifying users yet not being totally
263
+ disruptive to the testing flow.
261
264
262
265
### Alternative methods to control interop mode
263
266
@@ -271,7 +274,7 @@ good balance between notifying users yet not breaking existing test suites.
271
274
- ** CLI option through SwiftPM:**
272
275
273
276
```
274
- swift test --interop-mode=warning
277
+ swift test --interop-mode=warning-only
275
278
```
276
279
277
280
This could be offered in addition to the proposed environment variable option,
@@ -282,11 +285,12 @@ good balance between notifying users yet not breaking existing test suites.
282
285
Thanks to Stuart Montgomery, Jonathan Grynspan, and Brian Croom for feedback on
283
286
the proposal.
284
287
288
+ [ XCTest assertions ] : https://developer.apple.com/documentation/xctest/equality-and-inequality-assertions
289
+ [ XCTest attachments ] : https://developer.apple.com/documentation/xctest/adding-attachments-to-tests-activities-and-issues
285
290
[ unconditional failure ] : https://developer.apple.com/documentation/xctest/unconditional-test-failures
286
291
[ runtime warning issues ] : https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0013-issue-severity-warning.md
287
292
[ expected failures ] : https://developer.apple.com/documentation/xctest/expected-failures
288
293
[ issue handling traits ] : https://developer.apple.com/documentation/testing/issuehandlingtrait
289
294
[ test cancellation ] : https://forums.swift.org/t/pitch-test-cancellation/81847
290
295
[ traits ] : https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/traits
291
- [ tags ] : https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/addingtags
292
296
[ exit testing ] : https://developer.apple.com/documentation/testing/exit-testing
0 commit comments