Skip to content

Commit fb739f2

Browse files
authored
Fix assertSnapshot for Swift Testing tests. (#916)
* Fix assertSnapshot for Swift Testing tests. * wip * Update CI
1 parent 7b0bbba commit fb739f2

File tree

12 files changed

+75
-40
lines changed

12 files changed

+75
-40
lines changed

.github/workflows/ci.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ jobs:
1313
strategy:
1414
matrix:
1515
xcode:
16-
- "14.3.1"
16+
- 15.4
17+
- '16.0'
1718

18-
name: macOS 13 (Xcode ${{ matrix.xcode }})
19-
runs-on: macos-13
19+
name: macOS
20+
runs-on: macos-14
2021
steps:
2122
- uses: actions/checkout@v3
2223
- name: Select Xcode ${{ matrix.xcode }}

Sources/SnapshotTesting/AssertSnapshot.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import XCTest
22

33
#if canImport(Testing)
4-
// NB: We are importing only the implementation of Testing because that framework is not available
5-
// in Xcode UI test targets.
6-
@_implementationOnly import Testing
4+
import Testing
75
#endif
86

97
/// Enhances failure messages with a command line diff tool expression that can be copied and pasted
@@ -421,7 +419,10 @@ public func verifySnapshot<Value, Format>(
421419

422420
if !attachments.isEmpty {
423421
#if !os(Linux) && !os(Windows)
424-
if ProcessInfo.processInfo.environment.keys.contains("__XCODE_BUILT_PRODUCTS_DIR_PATHS") {
422+
if
423+
ProcessInfo.processInfo.environment.keys.contains("__XCODE_BUILT_PRODUCTS_DIR_PATHS"),
424+
!isSwiftTesting
425+
{
425426
XCTContext.runActivity(named: "Attached Failure Diff") { activity in
426427
attachments.forEach {
427428
activity.add($0)

Sources/SnapshotTesting/Documentation.docc/Articles/IntegratingWithTestFrameworks.md

+3-10
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,14 @@ class FeatureTests: XCTestCase {
6767

6868
This will override the `diffTool` and `record` properties for each test function.
6969

70-
Swift's new testing framework does not currently have a public API for this kind of customization.
71-
There is an experimental feature, called `CustomExecutionTrait`, that does gives us this ability,
72-
and the library provides such a trait called ``Testing/Trait/snapshots(diffTool:record:)``. It can
73-
be attached to any `@Test` or `@Suite` to configure snapshot testing:
70+
Swift's new testing framework also allows for this kind of configuration, both for a single test
71+
and an entire test suite. This is done via what are known as "test traits":
7472

7573
```swift
76-
@_spi(Experimental) import SnapshotTesting
74+
import SnapshotTesting
7775

7876
@Suite(.snapshots(record: .all, diffTool: .ksdiff))
7977
struct FeatureTests {
8078
8179
}
8280
```
83-
84-
> Important: You must import SnapshotTesting with the `@_spi(Experimental)` attribute to get access
85-
to this functionality because Swift Testing's own `CustomExecutionTrait` is hidden behind the same
86-
SPI flag. This means this API is subject to change in the future, but hopefully Apple will
87-
publicize this tool soon.

Sources/SnapshotTesting/Documentation.docc/Articles/MigrationGuides/MigratingTo1.17.md

+5-12
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,12 @@ in an XCTest context or a Swift Testing context, and will determine if it should
151151
`Issue.record` to trigger a test failure.
152152

153153
For the most part you can write tests for Swift Testing exactly as you would for XCTest. However,
154-
there is one major difference. Swift Testing does not (yet) have a substitute for `invokeTest`,
155-
which we used alongside `withSnapshotTesting` to customize snapshotting for a full test class.
156-
157-
There is an experimental version of this tool in Swift Testing, called `CustomExecutionTrait`, and
158-
this library provides such a trait called ``Testing/Trait/snapshots(diffTool:record:)``. It allows
159-
you to customize snapshots for a `@Test` or `@Suite`, but to get access to it you must perform an
160-
`@_spi(Experimental)` import of snapshot testing:
154+
there is one major difference. In order to override a snapshot's
155+
[configuration](<doc:SnapshotTestingConfiguration>) for a particular test or an entire suite you
156+
must use what are known as "test traits":
161157
162158
```swift
163-
@_spi(Experimental) import SnapshotTesting
159+
import SnapshotTesting
164160
165161
@Suite(.snapshots(record: .all, diffTool: .ksdiff))
166162
struct FeatureTests {
@@ -169,7 +165,4 @@ struct FeatureTests {
169165
```
170166
171167
That will override the `diffTool` and `record` options for the entire `FeatureTests` suite.
172-
173-
> Important: As evident by the usage of `@_spi(Experimental)` this API is subject to change. As
174-
soon as the Swift Testing library finalizes its API for `CustomExecutionTrait` we will update
175-
the library accordingly and remove the `@_spi` annotation.
168+
These traits can also be used on individual `@Test`s too.

Sources/SnapshotTesting/Internal/RecordIssue.swift

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import XCTest
22

33
#if canImport(Testing)
4-
// NB: We are importing only the implementation of Testing because that framework is not available
5-
// in Xcode UI test targets.
6-
@_implementationOnly import Testing
4+
import Testing
75
#endif
86

97
var isSwiftTesting: Bool {

Sources/SnapshotTesting/SnapshotsTestTrait.swift

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#if canImport(Testing)
2-
// NB: We are importing only the implementation of Testing because that framework is not available
3-
// in Xcode UI test targets.
4-
@_implementationOnly import Testing
2+
import Testing
53

6-
@_spi(Experimental)
74
extension Trait where Self == _SnapshotsTestTrait {
85
/// Configure snapshot testing in a suite or test.
96
///
@@ -33,7 +30,6 @@
3330
}
3431

3532
/// A type representing the configuration of snapshot testing.
36-
@_spi(Experimental)
3733
public struct _SnapshotsTestTrait: SuiteTrait, TestTrait {
3834
public let isRecursive = true
3935
let configuration: SnapshotTestingConfiguration

Tests/InlineSnapshotTestingTests/AssertInlineSnapshotSwiftTests.swift

+23-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import Testing
33
import Foundation
44
import InlineSnapshotTesting
5-
@_spi(Experimental) import SnapshotTesting
5+
import SnapshotTesting
66

77
@Suite(
88
.snapshots(
@@ -21,6 +21,28 @@
2121
}
2222
}
2323

24+
@Test func inlineSnapshotFailure() {
25+
withKnownIssue {
26+
assertInlineSnapshot(of: ["Hello", "World"], as: .dump) {
27+
"""
28+
▿ 2 elements
29+
- "Hello"
30+
31+
"""
32+
}
33+
} matching: { issue in
34+
issue.description == """
35+
Issue recorded: Snapshot did not match. Difference: …
36+
37+
@@ −1,3 +1,4 @@
38+
 ▿ 2 elements
39+
  - "Hello"
40+
+ - "World"
41+
42+
"""
43+
}
44+
}
45+
2446
@Test func inlineSnapshot_NamedTrailingClosure() {
2547
assertInlineSnapshot(
2648
of: ["Hello", "World"], as: .dump,

Tests/SnapshotTestingTests/AssertSnapshotSwiftTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#if canImport(Testing)
22
import Testing
33
import Foundation
4-
@_spi(Experimental) import SnapshotTesting
4+
import SnapshotTesting
55

66
@Suite(
77
.snapshots(

Tests/SnapshotTestingTests/SnapshotsTraitTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#if compiler(>=6) && canImport(Testing)
22
import Testing
3-
@_spi(Experimental) @_spi(Internals) import SnapshotTesting
3+
@_spi(Internals) import SnapshotTesting
44

55
struct SnapshotsTraitTests {
66
@Test(.snapshots(diffTool: "ksdiff"))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#if compiler(>=6) && canImport(Testing)
2+
import Testing
3+
import SnapshotTesting
4+
5+
@Suite(.snapshots(diffTool: "ksdiff"))
6+
struct SwiftTestingTests {
7+
@Test func testSnapshot() {
8+
assertSnapshot(of: ["Hello", "World"], as: .dump)
9+
}
10+
11+
@Test func testSnapshotFailure() {
12+
withKnownIssue {
13+
assertSnapshot(of: ["Goodbye", "World"], as: .dump)
14+
} matching: { issue in
15+
issue.description.hasSuffix("""
16+
@@ −1,4 +1,4 @@
17+
 ▿ 2 elements
18+
− - "Hello"
19+
+ - "Goodbye"
20+
  - "World"
21+
""")
22+
}
23+
}
24+
}
25+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
▿ 2 elements
2+
- "Hello"
3+
- "World"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
▿ 2 elements
2+
- "Hello"
3+
- "World"

0 commit comments

Comments
 (0)