ApprovalTests for Swift, a powerful alternative to assertions

What's New

Enhanced printing of approval files including markdown support


Breaking Changes:

  • Stop reporting the object type.
    For example,
try Approvals.verify(CGRect(x: 5, y: 10, width: 100, height: 200))

will produce these changes in your .approved. files

- CGRect: (5.0, 10.0, 100.0, 200.0)
+ (5.0, 10.0, 100.0, 200.0)


  • Works with Xcode 13.3. Changes in Xcode 13.3's call stack caused this issue.
  • Skip reporters that can't handle the file type. So if you have an image artifact, Approvals.Swift will use the first reporter that can show image differences.
  • Fix iOS results watcher to support project paths with spaces.


  • verifyAll improvements:
    • Now has an optional header to print above the array.
    • A new verifyAll takes a labeler closure to format each line.
      For example, here's a way to make lists without indices:
  try Approvals.verifyAll(header: "grocery list", groceries) { $0 }
  • For iOS tests, ApprovalTests will print a reminder to turn on the watcher.
  • SimpleLogger: an easy way to log and do performance profiling.
  • UIKitApprovals.verify for verifying UIViews and rendered UIViewControllers.
  • New reporters:
    • ReportMoveCommandToConsole
    • Make ReportByOpeningReceivedFile available on iOS, not just macOS


Approvals now offers a Verifiable interface that understands approvals.


Build Status Swift Package Index Swift Version Compatibility Swift Package Index Platform Compatibility Carthage compatible

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.


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:

class SampleArrayTests: XCTestCase {
    func testList() throws {
        var names = ["Llewellyn", "James", "Dan", "Jason", "Katrina"]
        try Approvals.verifyAll(names, label: "")

snippet source | anchor

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:

[0] = Dan
[1] = James
[2] = Jason
[3] = Katrina
[4] = Llewellyn

snippet source | anchor

It also opens two files in a diff editor—the “received” file, and the “approved” file.

Results shown in diff editor

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

Results copied from received to approved

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 .gitignore to 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 dictionary
  • Approvals.verifyAll — verify array of items (or use array as inputs)
  • Approvals.verifyAsJSON — verify Encodable object converted to JSON
  • Approvals.verifyQuery — verify query, also showing query results on failure
  • Approvals.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 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:


If you have iOS tests, you should also add 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:


Other Ways to Get It

Swift Package Manager

See an example package manifest here

Get the following dependency:

dependencies: [
        url: "",
        branch: "master"


Then add it to your test target:

    name: "ApprovalTests.Swift.StarterProject.MacOSTests",
    dependencies: [



Add the following to your Cartfile:

github "approvals/ApprovalTests.Swift" ~> 1.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.

For More Information


Ask Llewellyn Falco @LlewellynFalco or Jon Reid @qcoding on Twitter.


Find some extra documentation here.

Video Tutorials

You can also watch a series of short videos about using ApprovalTests in .Net on YouTube.


Prefer learning by listening? Then you might enjoy the following podcasts:


  • Swift Tools 5.3.0
View More Packages from this Author


  • None
Last updated: Fri Jul 12 2024 12:19:21 GMT-0900 (Hawaii-Aleutian Daylight Time)