The Swift Testing Framework
Apple's modern testing framework (Xcode 16) replaces XCTest's classes and assertions with macros. Learn import Testing , @Test functions, #expect and #require , parameterized tests with arguments: , @Suite , tags, and async tests.
Learn The Swift Testing Framework in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ @Test and #expect
Import Testing , mark a function @Test , and check results with #expect . No base class and no test prefix required.
2️⃣ #require and Expected Errors
#require throws to stop a test early — ideal for unwrapping. #expect(throws:) verifies that code throws the error you expect.
3️⃣ Parameterized Tests
Pass a collection to @Test(arguments:) and the function runs once per input, reporting each case independently — far cleaner than a hand-written loop.
Your turn. Fill in the import, the test attribute, and the assertion macro.
4️⃣ Suites, Tags, and Async
@Suite groups related tests; traits like .tags(...) add filterable metadata; and any @Test can be async to await directly.
📋 Quick Reference
Write a parameterized test plus a negative case for an age validator.
Practice quiz
Which module do you import to use the Swift Testing framework?
- Testing
- SwiftTest
- Foundation
- XCTest
Answer: Testing. Swift Testing is provided by the Testing module, so you write import Testing.
Which attribute marks a function as a test in Swift Testing?
- @TestCase
- @Check
- @Test
- @Spec
Answer: @Test. You annotate a function with the @Test macro to register it as a test.
Which macro replaces XCTAssert for ordinary checks?
- #check
- #expect
- #assert
- #verify
Answer: #expect. #expect(...) is the core assertion macro in Swift Testing.
What does #require do that #expect does not?
- Runs faster
- Logs only
- Skips the test
- Stops the test by throwing when the condition fails
Answer: Stops the test by throwing when the condition fails. #require throws and halts the test on failure, so you can safely unwrap or stop early.
How do you run the same test over many inputs?
- @Test with an arguments: parameter
- Copy the test
- @Repeat
- A for loop only
Answer: @Test with an arguments: parameter. Parameterized tests use @Test(arguments:) to run the function once per input value.
Which attribute groups related tests into a named collection?
- @Bundle
- @Suite
- @Set
- @Group
Answer: @Suite. @Suite marks a type as a test suite that organizes related @Test functions.
How do you write an asynchronous test in Swift Testing?
- Use waitForExpectations
- You cannot
- Wrap it in DispatchQueue
- Mark the @Test function async and use await
Answer: Mark the @Test function async and use await. A @Test function can be async, letting you await asynchronous code directly.
How do you express that a test should throw an error?
- @Throws
- try?
- #expect(throws:)
- XCTAssertThrows
Answer: #expect(throws:). #expect(throws:) verifies that the enclosed expression throws the expected error.
What are traits like .tags(...) used for?
- Speeding up tests
- Adding metadata to filter and organize tests
- Mocking
- Compiling
Answer: Adding metadata to filter and organize tests. Traits such as tags attach metadata so you can group, filter, and select tests to run.
How does Swift Testing relate to XCTest?
- It is a modern alternative that can coexist with XCTest
- It deletes XCTest
- It is identical to XCTest
- It only runs on Linux
Answer: It is a modern alternative that can coexist with XCTest. Swift Testing is a newer, macro-based framework that runs alongside existing XCTest tests.