ApprovalTests.Swift
ApprovalTests for Swift, a powerful alternative to assertions
Install / Use
/learn @approvals/ApprovalTests.SwiftREADME
<img src="https://avatars3.githubusercontent.com/u/36907" height="30px"> ApprovalTests
Approval Tests are an alternative to assertions. You’ll find them useful for testing objects with complex values (such as long strings), lots of properties, or collections of objects.
ApprovalTests.Swift is compatible with the XCTest testing framework.
<!-- toc -->Contents
- My First Approval Test
- Getting Started
- Predefined Verifiers
- How to Use with iOS
- Which File Artifacts to Exclude from Source Control
- Other Ways to Get It
- For More Information
- Questions?
- Documentation
- Video Tutorials
- Podcasts<!-- endToc -->
My First Approval Test
We'll start by writing a simple unit test to verify a list of names. But instead of using XCTest's XCTAssertEqual function, we'll use Approvals.verifyAll:
<a id='snippet-sample_test'></a>
class SampleArrayTests: XCTestCase {
func testList() throws {
var names = ["Llewellyn", "James", "Dan", "Jason", "Katrina"]
names.sort()
try Approvals.verifyAll(names, label: "")
}
<sup><a href='/ApprovalTests_SwiftTests/Demo/SampleArrayTests.swift#L8-L15' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_test' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->The verifyAll() function performs a test assertion for a list of items. Unlike a normal assertion, it doesn’t specify an expected list. Instead, this will produce a “received” file matching the name of your test suite and test case. In this example, it will write a file SampleArrayTests.testList.received.txt:
<a id='snippet-SampleArrayTests.testList.approved.txt'></a>
[0] = Dan
[1] = James
[2] = Jason
[3] = Katrina
[4] = Llewellyn
<sup><a href='/ApprovalTests_SwiftTests/Demo/SampleArrayTests.testList.approved.txt#L1-L5' title='Snippet source file'>snippet source</a> | <a href='#snippet-SampleArrayTests.testList.approved.txt' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->It also opens two files in a diff editor—the “received” file, and the “approved” file.

To approve the results, tell the diff editor to apply changes from the left side to the right side:

Most of the time, you’ll use one of the supported diff tools to examine and approve the result. If you don’t have any of these diff tools, you can rename the received file to SampleArrayTests.testList.approved.txt and the test will now pass.
Getting Started
The best way to get started is download and open one of the starter projects:
These are standard projects and can be imported into any editor or IDE.
They also all have CI with Github actions.
They come ready with:
- A Swift package definition adding ApprovalTests.Swift to the test target
- A suitable
.gitignoreto exclude approval artifacts - A GitHub action to build and run tests
- A GitHub build status badge
Predefined Verifiers
ApprovalTests.Swift comes with useful verifiers:
Approvals.verify— verify object or dictionaryApprovals.verifyAll— verify array of items (or use array as inputs)Approvals.verifyAsJSON— verify Encodable object converted to JSONApprovals.verifyQuery— verify query, also showing query results on failureApprovals.verifySequence— verify sequence of changing values
How to Use with iOS
ApprovalTests.Swift runs out-of-the-box for macOS tests. But for iOS tests, you need a separate process running on your Mac to watch for diffs. Run iOSApprovalsWatcher.py from your command line, giving it the path to your test directory.
Which File Artifacts to Exclude from Source Control
You must add any “approved” files to your source control system. But “received” files can change with any run and should be ignored. For Git, add this to your .gitignore:
*.received.*
If you have iOS tests, you should also add command.sh to your .gitignore. (They are scripts written by the iOS side for the file monitor to execute from the macOS side.) So for iOS testing, make sure to exclude:
*.received.*
command.sh
Other Ways to Get It
Swift Package Manager
See an example package manifest here
Get the following dependency:
<!-- snippet: package_include_approvals --><a id='snippet-https://raw.githubusercontent.com/approvals/ApprovalTests.Swift.StarterProject.MacOs/main/Package.swift%23package_include_approvals'></a>
dependencies: [
.package(
url: "https://github.com/approvals/ApprovalTests.Swift",
branch: "master"
),
],
<sup><a href='https://raw.githubusercontent.com/approvals/ApprovalTests.Swift.StarterProject.MacOs/main/Package.swift#package_include_approvals' title='Snippet source file'>anchor</a></sup>
<!-- endSnippet -->Then add it to your test target:
<!-- snippet: package_add_test_target --><a id='snippet-https://raw.githubusercontent.com/approvals/ApprovalTests.Swift.StarterProject.MacOs/main/Package.swift%23package_add_test_target'></a>
.testTarget(
name: "ApprovalTests.Swift.StarterProject.MacOSTests",
dependencies: [
"ApprovalTests.Swift.StarterProject.MacOS",
"ApprovalTests.Swift",
],
<sup><a href='https://raw.githubusercontent.com/approvals/ApprovalTests.Swift.StarterProject.MacOs/main/Package.swift#package_add_test_target' title='Snippet source file'>anchor</a></sup>
<!-- endSnippet -->Carthage
Add the following to your Cartfile:
github "approvals/ApprovalTests.Swift" ~> 2.0
Then drag the the built framework from the appropriate Carthage/Build directory into your project, but with “Copy items into destination group’s folder” disabled.
CocoaPods
If you want to add ApprovalTests.Swift using Cocoapods then add the following dependency to your Podfile. Most people will want ApprovalTests.Swift in their test targets, and not include any pods from their main targets:
target 'MyTests' do
inherit! :search_paths
use_frameworks!
pod 'ApprovalTests_Swift', '~> 2.0'
end
For More Information
Questions?
Ask Llewellyn Falco @LlewellynFalco on Twitter, or Jon Reid on BlueSky or Mastodon.
Documentation
Find some extra documentation here.
Video Tutorials
- Getting Started with ApprovalTests.Swift
- How to Verify Objects (and Simplify TDD)
- Verify Arrays and See Simple, Clear Diffs
- Write Parameterized Tests by Transforming Sequences
- Wrangle Legacy Code with Combination Approvals
You can also watch a series of short videos about using ApprovalTests in .Net on YouTube.
Podcasts
Prefer learning by listening? Then you might enjoy the following podcasts:
Related Skills
gh-issues
341.0kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
node-connect
341.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Writing Hookify Rules
84.4kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.

