@@ -14,13 +14,13 @@ intermediate state where test helpers written using XCTest API are called from
1414Swift Testing. Today, the Swift Testing and XCTest libraries stand mostly
1515independently, which means an ` XCTAssert ` failure in a Swift Testing test is
1616silently 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
2424existing test helper function written for XCTest and call it in a Swift Testing
2525test, it won't report the assertion failure:
2626
@@ -49,17 +49,16 @@ class FooTests: XCTestCase {
4949Generally, 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
5757problem 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
8483We 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
9494Note 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
9897We 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
127126We think developers will find utility in using Swift Testing APIs in XCTest. For
128127example, you can replace ` XCTAssert ` with ` #expect ` in your XCTest tests and
@@ -133,13 +132,13 @@ Testing at your own pace.
133132Present and future Swift Testing APIs will be supported in XCTest if the
134133XCTest 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
144143Here 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:
166167Configure 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
185186failures. We believe this should be a net positive if it can highlight actual
186187bugs 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
242242In a similar vein, we considered ` SWIFT_TESTING_XCTEST_INTEROP_MODE=off ` as a
243243way 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
245245warning-only mode could still cause test failures.
246246
247247However, 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
256256that we want users to migrate to Swift Testing.
257257
258258However, 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.
282286Thanks to Stuart Montgomery, Jonathan Grynspan, and Brian Croom for feedback on
283287the 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