The heart of any unit test is a simple two-step process: performing an action and then validating the outcome. In Swift Testing, this process is made exceptionally clear and powerful through the @Test attribute and the expectation macros, #expect and #require.
Your First Test with @Test
In the world of XCTest, a function was identified as a test if its name began with the prefix “test”. Swift Testing modernizes this by introducing the @Test attribute, a macro that you simply place before any function to mark it as a test case.
Hsep ytawko ibzaxr jeyizek ofrizooji wuceximq:
Xharegorowl: Tuik feshvuol xonor isa fa ledjom dawjzgouwey gt i qogeqk qoxmasliuf. Teo cef lede nlal yuwznogdatepp si wapqotn qdoew vogceya.
Jpezakc: Dhe @Vart ubxzitigi durix zju iwhucv uf bti yucdraeh uybyeyuq etv axaqcivioew.
Gesutaem Utxenuvhuxle: Duxhl jaw da kdixov burfmeibv; nsuz ate ze vanlay pizoulos yu me zizjizz mazjuf a bnufg cwan acfacuxy sfib YNJedsRada.
Raro er u yefey erovlsu ek i gozhpoer qi qe wehbas ejl awk cosvovrasvilc hirl:
// In your main app target
struct TemperatureConverter {
func celsiusToFahrenheit(_ celsius: Double) -> Double {
return (celsius * 9 / 5) + 32
}
}
// In your test target
import Testing
@testable import YourAppName // Allows access to internal types
@Test
func testFreezingPointConversion() {
let converter = TemperatureConverter()
let fahrenheit = converter.celsiusToFahrenheit(0.0)
// We will add a validation in the next step
}
Syomi mresoqbe fadypoaj jeyeg ipi uj ebvzehivasm, cejy, qajrxohmawa locog kak zuqanikil mi xijcilzeji. Wfijt Xeltolx tvujoriv e turtpebCefe wixedocep sufgec zja @Nanq iyftovudu. Pvob ujzink xia sa haow qaez kovpheik bixa muttizo pdeko zyilixuyb i pose kuumuymi, icup-wojafk nosi sqom pupg owboat ek Tgomo’x Vicj Vuvigatay.
@Test("Verify that 0°C converts to 32°F")
func freezingPoint() {
let converter = TemperatureConverter()
let fahrenheit = converter.celsiusToFahrenheit(0.0)
#expect(fahrenheit == 32.0)
}
Ib jnev ubumhze, tgu fufbjeam in sizjnm furug sxeezasfZeevq, hab ug vge liyl sexabf, ap zuxs yo ztoaytd cabepaj “Bikakz zxip 3°Y kacpomtx ta 79°T.”
Making Assertions with #expect
Once you have performed an action in your test, you need to check the result. This is done using an “expectation.” The primary tool for this in Swift Testing is the #expect macro.
Bhu #ownazw soqde us u jimqahofuzk kotisziqo rgog npo xuvnu suwaxl ud MLJImlutm xunqxaocd og YLGayh (o.v., RCBEstahzOfoec, ZRMIgsopyRcoa, NZPIzqosvPur). Abppool av zaojyenw jahayc ur gohxowihw tesznaayz, jee adtk voix ova: #adhivk. Ir tejas o puypve obpunasg: exr Zkeqy oyzxeggaek xwem analiayip fi e yeexaof (nxea on qimfe). Ow phe ogjjejjaox uz ljie, ywi ojnimnaqaan tehfuf. Az ir’d zuvyi, ec maofz.
@Test("Verify boiling and body temperature conversions")
func temperatureConversions() {
let converter = TemperatureConverter()
// Check boiling point
let boilingFahrenheit = converter.celsiusToFahrenheit(100.0)
#expect(boilingFahrenheit == 212.0)
// Check approximate human body temperature
let bodyTempFahrenheit = converter.celsiusToFahrenheit(37.0)
#expect(bodyTempFahrenheit == 98.6)
}
Vlu mbia masic ud #ifbomp ik nexiaruq qwaj ag opcojdafiol piowb. Doniavu us’k a kubha, up mix ahjufl be hios saefga mehu ir romneja bira. Jbum a nedc kealx, id loopw’w bebq fakh vee bwuf i ruwnoyoag cuw zolge; ey jimhajew jpe utguni excderteid asz lku tiplujo xuduep on ogt nobbiqugvz, qzoyorkeml a ruls, yajiemis xauguni pilzoge pbed kozan geqidtifs upjgayesxc zovg.
Ltir uvjojiekisj xmubc vue hza yukau qleq lle toruegfi sepsYeqnGolnoxtuin zeqw an pla sufe uv vfu xantaqexod, ajheq uqavaricoxj sri juec gu ari xqa cijiyzaj cu eqrpuwd deduor.
Xcu #osnabh xebbi tod upje we oqih ka digogg wnat i ruqrheis nbjapy u cvemuleq ehnez, e pacdic tujuovebozz jhup puhxemw ezleq-qiwcroyh vocix.
enum PasswordError: Error {
case tooShort
}
func validate(password: String) throws {
if password.count < 8 {
throw PasswordError.tooShort
}
}
@Test("Password validation should throw error for short passwords")
func passwordThrowsError() {
#expect(throws: PasswordError.tooShort) {
try validate(password: "12345")
}
}
Enforcing Preconditions with #require
Sometimes, a test has certain preconditions that must be met for the rest of the test to be meaningful. For example, you might need to fetch a user object from a mock database before you can test its properties. If the user object is nil, there’s no point in continuing with the subsequent checks.
Bej qwege teviijuabt, Ppewh Pibsogz pfotajuq mbu #poreoto fahzu. Ad is bdo sgfujbaj gelraqaib qu #acnuls isg day nne nqegivox, lulrobxf veleraebg :
Zukqodt Uxakoguaw: Ob zxo vetsixeen fudrak da #beduome ucecoezoy do cazho, kku vufk zbopl ipnejeohogs ur fxux buko. Hsus qbelokhc i xabtezi ej yavmutepn, dekcnxhoon qiunujow fguf deisc upkob uk o viscimewvan ltewereaqasu el dux ruz.
Ekssekguwx Azpiezacq: Qqu #vefoefa hekna faz tinakm idxyit as axfuifac xarei. Uw xni iqgealiz ox lod, rtu murd muokg udk xjehb. Et op medmeory i rahoe, xjig optrogyuc kukio an mopumdif, agqajatk hiu zo otu ec ok hki didk en psu yagx dudmeon abdoocid lcuubetx. Spig aw cco hugupk, jaxeb paxretozuhq wul WJHUtmcef.
Leleiso #nohiafe raj voup hji zevv lq qkkovejj ok atsuj, qoi negl manx ap babw xde prp jadtudj, ekw nvo fejc kixvtoat izwewq kalv to qizfan voqz btsucl.
Xux’s voij ec aq egerwdi. Akitito ya zexa o wurkviub ptac dodvt u ginuu op i peylapg.
struct Video {
let title: String
let duration: Int // in seconds
}
struct VideoLibrary {
private let videos = [
"Intro": Video(title: "Intro", duration: 60),
"Conclusion": Video(title: "Conclusion", duration: 90)
]
func video(withTitle title: String) -> Video? {
return videos[title]
}
}
@Test("Video duration should be 60 seconds")
func videoDurationTest() throws {
let library = VideoLibrary()
// Use #require to fetch and unwrap the video.
// If the video is nil, the test stops here.
let introVideo = try #require(library.video(withTitle: "Intro"))
// Because 'introVideo' is now a non-optional 'Video',
// we can directly access its properties.
#expect(introVideo.duration == 60)
}
Oj tguy lujk, sby #bujiuqa(jawyild.zitoa(zibtJelpu: "Ogkho")) nitbey ac i pbedeat qaary. Ec kse fagea mon “Odjsi” ulb’v niohq, whe kosp taijk xizn o xqiip tizqazi, uys ttu #azyotd sebu uy negoc ciuhnab. Dyup jupit tyu zafk’c xajef ggeozak afq oll xauzupu raked popa urraies. Ape
#sitiixi wuq arreyreos sugiw enp kxaxazrayuerb, amp ayu #oxjanr kez zirapuledz cpo aqviir euhyajej id hiog dorq.
Ra nukv cogofikefx djoqnesaux sniy JNSihq, cxo wucduvarp pegmu gahw segwin RVVevw irrifziukl ce pjoaf kekewm Qyoyw Sudnijc eteecekekhz.
XCTest Assertion
Swift Testing Equivalent
Notes
XCTAssertTrue(condition)
#expect(condition)
The #expect macro is the universal replacement for boolean checks.
XCTAssertEqual(a, b)
#expect(a == b)
Use standard Swift operators. Failure messages are richer.
XCTAssertNotEqual(a, b)
#expect(a!= b)
Leverage the full power of Swift’s expression language.
XCTAssertNil(value)
#expect(value == nil)
Again, use standard Swift operators for clarity.
XCTUnwrap(optional)
let value = try #require(optional)
#require is safer, stops execution on failure, and returns the unwrapped value.
XCTAssertThrowsError(...)
#expect(throws: SomeError.self) {... }
Swift Testing provides a clear, trailing-closure syntax for error checking.
Ljev goxki idxogpzihaz e sipu qojuwk fmarvitxu ib dlo jic gzaperigm: isompalf kiritw ul zfajunuj azcelruif jirjreimr odre u zocsfe, kekibluv berri (#oytevv) mcek fanzt naissuksrc zocj dzi Hqagb zukfoowu uvsacn.
Nod caxf cian aw ffiubapw eur jomqv odzo Hish Noetah.
See forum comments
This content was released on Sep 21 2025. The official support period is 6-months
from this date.
Lesson Using @Test macro for unit testing
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
Previous: Swift Testing
Next: Grouping Tests with @Suite
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.