@@ -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,34 +71,34 @@ 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
104
`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:
122
121
- ` withKnownIssue ` : marking an XCTest issue in this way will generate a runtime
123
122
warning issue. In strict interop mode, this becomes a ` fatalError ` .
124
123
- Attachments
125
- - [ Test cancellation] [ ] (links to pitch )
124
+ - [ Test cancellation] [ ] (currently pitched )
126
125
127
126
We think developers will find utility in using Swift Testing APIs in XCTest. For
128
127
example, you can replace ` XCTAssert ` with ` #expect ` in your XCTest tests and
@@ -133,13 +132,13 @@ Testing at your own pace.
133
132
Present and future Swift Testing APIs will be supported in XCTest if the
134
133
XCTest API _ already_ provides similar functionality.
135
134
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.
138
138
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.
143
142
144
143
Here are some concrete examples:
145
144
@@ -151,8 +150,10 @@ Here are some concrete examples:
151
150
152
151
### Interoperability Modes
153
152
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.
156
157
157
158
- ** Permissive** : This is the default interoperability mode, which surfaces test
158
159
failures that were previously ignored. It also includes runtime warning issues
@@ -166,11 +167,11 @@ Here are some concrete examples:
166
167
Configure the interoperability mode when running tests using the
167
168
` SWIFT_TESTING_XCTEST_INTEROP_MODE ` environment variable:
168
169
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 ` |
174
175
175
176
### Phased Rollout
176
177
@@ -185,9 +186,9 @@ lead to situations where previously "passing" test code now starts showing
185
186
failures. We believe this should be a net positive if it can highlight actual
186
187
bugs you would have missed previously.
187
188
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 .
191
192
192
193
## Integration with supporting tools
193
194
@@ -218,8 +219,7 @@ Testing:
218
219
API within helper methods.
219
220
220
221
- 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.
223
223
224
224
## Alternatives considered
225
225
@@ -241,7 +241,7 @@ should make it clear that this is not intended to be a permanent measure.
241
241
242
242
In a similar vein, we considered ` SWIFT_TESTING_XCTEST_INTEROP_MODE=off ` as a
243
243
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
245
245
warning-only mode could still cause test failures.
246
246
247
247
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
256
256
that we want users to migrate to Swift Testing.
257
257
258
258
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.
261
265
262
266
### Alternative methods to control interop mode
263
267
@@ -271,7 +275,7 @@ good balance between notifying users yet not breaking existing test suites.
271
275
- ** CLI option through SwiftPM:**
272
276
273
277
```
274
- swift test --interop-mode=warning
278
+ swift test --interop-mode=warning-only
275
279
```
276
280
277
281
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.
282
286
Thanks to Stuart Montgomery, Jonathan Grynspan, and Brian Croom for feedback on
283
287
the proposal.
284
288
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
285
291
[ unconditional failure ] : https://developer.apple.com/documentation/xctest/unconditional-test-failures
286
292
[ runtime warning issues ] : https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0013-issue-severity-warning.md
287
293
[ expected failures ] : https://developer.apple.com/documentation/xctest/expected-failures
288
294
[ issue handling traits ] : https://developer.apple.com/documentation/testing/issuehandlingtrait
289
295
[ test cancellation ] : https://forums.swift.org/t/pitch-test-cancellation/81847
290
296
[ traits ] : https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/traits
291
- [ tags ] : https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/addingtags
292
297
[ exit testing ] : https://developer.apple.com/documentation/testing/exit-testing
0 commit comments