@@ -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,38 +71,37 @@ 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
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") ` .
107105
108106Here are some concrete examples:
109107
@@ -122,7 +120,7 @@ We propose supporting the following Swift Testing APIs in XCTest:
122120-  ` withKnownIssue ` : marking an XCTest issue in this way will generate a runtime
123121  warning issue. In strict interop mode, this becomes a ` fatalError ` .
124122-  Attachments
125- -  [ Test cancellation] [ ]  (links to pitch )
123+ -  [ Test cancellation] [ ]  (currently pitched )
126124
127125We think developers will find utility in using Swift Testing APIs in XCTest. For
128126example, you can replace ` XCTAssert `  with ` #expect `  in your XCTest tests and
@@ -133,13 +131,13 @@ Testing at your own pace.
133131Present and future Swift Testing APIs will be supported in XCTest if the
134132XCTest API _ already_  provides similar functionality.
135133
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.
138137
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.
143141
144142Here are some concrete examples:
145143
@@ -151,8 +149,10 @@ Here are some concrete examples:
151149
152150### Interoperability Modes  
153151
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.
156156
157157-  ** Permissive** : This is the default interoperability mode, which surfaces test
158158  failures that were previously ignored. It also includes runtime warning issues
@@ -166,11 +166,11 @@ Here are some concrete examples:
166166Configure the interoperability mode when running tests using the
167167` SWIFT_TESTING_XCTEST_INTEROP_MODE `  environment variable:
168168
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 `                                        | 
174174
175175### Phased Rollout  
176176
@@ -185,9 +185,9 @@ lead to situations where previously "passing" test code now starts showing
185185failures. We believe this should be a net positive if it can highlight actual
186186bugs you would have missed previously.
187187
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 .
191191
192192## Integration with supporting tools  
193193
@@ -218,8 +218,7 @@ Testing:
218218  API within helper methods.
219219
220220-  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.
223222
224223## Alternatives considered  
225224
@@ -241,7 +240,7 @@ should make it clear that this is not intended to be a permanent measure.
241240
242241In a similar vein, we considered ` SWIFT_TESTING_XCTEST_INTEROP_MODE=off `  as a
243242way 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
245244warning-only mode could still cause test failures.
246245
247246However, 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
256255that we want users to migrate to Swift Testing.
257256
258257However, 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.
261264
262265### Alternative methods to control interop mode  
263266
@@ -271,7 +274,7 @@ good balance between notifying users yet not breaking existing test suites.
271274-  ** CLI option through SwiftPM:** 
272275
273276  ``` 
274-   swift test --interop-mode=warning 
277+   swift test --interop-mode=warning-only  
275278``` 
276279
277280  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.
282285Thanks to Stuart Montgomery, Jonathan Grynspan, and Brian Croom for feedback on
283286the proposal.
284287
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 
285290[ unconditional failure ] : https://developer.apple.com/documentation/xctest/unconditional-test-failures 
286291[ runtime warning issues ] : https://github.com/swiftlang/swift-evolution/blob/main/proposals/testing/0013-issue-severity-warning.md 
287292[ expected failures ] : https://developer.apple.com/documentation/xctest/expected-failures 
288293[ issue handling traits ] : https://developer.apple.com/documentation/testing/issuehandlingtrait 
289294[ test cancellation ] : https://forums.swift.org/t/pitch-test-cancellation/81847 
290295[ traits ] : https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/traits 
291- [ tags ] : https://swiftpackageindex.com/swiftlang/swift-testing/main/documentation/testing/addingtags 
292296[ exit testing ] : https://developer.apple.com/documentation/testing/exit-testing 
0 commit comments