Grouping Tests with @Suite

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Organizing Your Test Suite

As your project grows, so will your number of tests. A flat list of hundreds of test functions quickly becomes unmanageable. To maintain clarity and efficiency, you need a robust way to organize them. Swift Testing provides two powerful and complementary organizational tools: @Suite for creating a structural hierarchy, and Tags for flexible, semantic categorization.

Grouping Tests with @Suite

In Swift Testing, a “suite” is simply a collection of related tests. The framework makes creating suites incredibly natural. Any Swift type—be it a struct, class, or actor—that contains one or more @Test functions is automatically considered a test suite, without any special declaration.  

struct UserManagerTests {
  @Test("Test successful user login")
  func testLoginSuccess() {
    //...
  }

  @Test("Test failed login with wrong password")
  func testLoginFailure() {
    //...
  }
}
@Suite("User Authentication Flow")
struct UserManagerTests {
  //... tests...
}
@Suite("Account Management")
struct AccountTests {
  @Suite("Authentication")
  struct AuthTests {
    @Test func testLogin() { /*... */ }
    @Test func testLogout() { /*... */ }
  }

  @Suite("Profile Editing")
  struct ProfileTests {
    @Test func testUpdateUsername() { /*... */ }
    @Test func testUpdateAvatar() { /*... */ }
  }
}

Setup and Teardown Logic

A common need in testing is to perform some setup work before each test runs (e.g., initializing a database, creating a mock object) and some cleanup work afterward (e.g., clearing the database, resetting state). In XCTest, this was handled by overriding the setUp() and tearDown() methods.

@Suite("Database Operations")
class DatabaseTests {
  var database: MockDatabase

  init() {
    // This runs BEFORE each test in this suite.
    self.database = MockDatabase()
    self.database.connect()
  }

  deinit {
    // This runs AFTER each test in this suite.
    self.database.disconnect()
  }

  @Test("Test adding a user")
  func testAddUser() {
    //... use self.database...
  }

  @Test("Test removing a user")
  func testRemoveUser() {
    //... use self.database...
  }
}

In-Depth Analysis: The Power of Value-Semantic Suite Structs

One of the most profound design decisions in Swift Testing is its strong recommendation to use value types, specifically structs, for test suites. To understand why this is so important, we must first revisit the fundamental difference between value types and reference types in Swift.

@Suite("Shopping Cart Tests")
struct ShoppingCartTests {
  var cart = ShoppingCart() // A struct to hold items

  @Test("Adding one item")
  mutating func testAddingFirstItem() {
    cart.add(item: "Apple")
    #expect(cart.items.count == 1)
  }

  @Test("Adding two items")
  mutating func testAddingSecondItem() {
    cart.add(item: "Banana")
    #expect(cart.items.count == 1) // This test will PASS
  }
}

Flexible Categorization with Tags

While suites provide a rigid, hierarchical structure, you often need a more flexible way to group tests that share a common characteristic, regardless of where they are in the source code. For example, you might want to run all “critical” tests, or all tests related to “networking,” or all tests that are known to be “slow.”

import Testing

extension Tag {
  @Tag static var networking: Self
  @Tag static var critical: Self
  @Tag static var slow: Self
}
@Suite("API Client",.tags(.networking))
struct APIClientTests {
  @Test("Fetch user profile",.tags(.critical))
  func testFetchUserProfile() {
    //...
  }
  
  @Test("Upload large file",.tags(.slow))
  func testFileUpload() {
    //...
  }
}
See forum comments
Download course materials from Github
Previous: Your First Test with @Test Next: Advanced Test Customization with Traits