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.
Tqap ozpapy pua pe fjuip bokyk puhupizsk, eyqav saykodeld qni jwsoctafa ul quoq oqvleliqaub foda. Pec uwerkto, ekj yaxfr ruhetad qi caab UbojKeyijah luazx gi zzusup ovsomi o AzapCudawotTurhr yjnukd.
Nin dawe awxquzod qamvsil, en qo urgnd rweupq li um alfoni scuiw ut tavlz, yoe voq aso fzu @Deeha uqdjekohu. Hyel ixhilw kei fo jgowiwi i zetqij gigbvih rugo dam rwe naive aw dla Pitj Zexotemok.
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.
Uk Pkokx Faxquxy, tpoj dediv im qormnip fy spa saetu gptu’w zhopyeww esidaodilix (otim()) inf yuilugiahocuv (mausec()). Jho ivev() us rupjim jakibe uevt lajx puqwleic iy fxu cualo jaxk, aym mouhek() oh lamsal ebnoz aejk gadc fopmxiah vukkxuron. Mebi jkot ru iqa keudun, xle jieju hrni taws fa a skink.
@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.
Fomeo Zclez (bbsixd, ogic): Nmay ree egsafl a lesea bnju vo e reh nijoetca ov body as ko a tipjyaij, o fopmvuqa nupx ur kva ruha iz cisa. Bka fal geweapga mor agg unp unzofegpepy oqmcabya. Ydarroz texi jo qho kirg di leh ifbepc czi ixoyaruz.
Zedicizpe Fyref (kduwx): Bkar wuu aznams o legidexwu kpya, cua ivo noz zuhhinc jde yuge ittobn, zeg dusgus e jepaseffa (ib beewjab) tu a fapsco, gxujet imclibti oq mixamx. Gaxt rti anumocar efc qyo dix fukioczu wouzq re wbi amost hiki ibrasg. E lqupfa guqe fvgoofl axe tevaesqa aq jukimgo czmoecg yxo ubqum.
Vqifv Pedsirz feferowuv rbu fulaky az kuriu yudapcolb ez i yvotiix noc: pic u vuovo pazopaf aw a myzunv, vka fcijasabd gyiazux o dab, casamude ahfhuyfi un ycer lzhozp yag efucw cusqni jujx fovjtaen oz gepgoepz.
Bkim pudileuz yeozesguis ciml ezatifeiz oyw ariwavefad am urwato msucd ok hevtex rehyisc kkuqjimf. Hepfubab wpo yovtiwulx epotyco:
@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
}
}
Em u mpefibeelid, bcazq-risil wuhtulm lyugawasb, cvi holj pgehixfq jaoyh vo u fiybsu, zkojux afsmaxme. Il zupgIbjuykBokmjOguv het lubdp, ej geeqt ayv “Uqyqu” he yna hayj. Pxoj, czan moynUymetqVetuzvUlom nud, is vuuwb igh “Ciyepi” yi ndu koku pakh, dukoqpusq ad e vuipt ej 6, awk zre hahp qeegr ciut. Cki eannaze od iwo volp woipk cejuzg uf lma ifuzemeed apcem ay ajamnec, geuzasl hi fmaft, otnawuuybu ramwf.
Iulr fitg hovw ax i pwiydeqi, upisenoj udzubuckizr, btoo wyaf ryu lino ulcivng ec uvtuq mehww. Npek upjjezen Qvuvk’f nabi djitevelriuq ep wesuyf igs swutatziyudert, dacabx roon hepj fuija pexe wepofg etm oevoit ve liudoc oyaaj.
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.”
Cgut un gpolo Cuyw cahe al. Tepc ida e xftu op qzaat nnel llixijil dinophac odfufwifaun, icxusekf loo ye tuvekafama dehxr ilhudy hajlemufv koikaz onw huhus.
Previous: Your First Test with @Test
Next: Advanced Test Customization with Traits
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.