📖 Scenario: You are building a simple Swift program that fetches a greeting message asynchronously, simulating a network call.
🎯 Goal: You will write code to test an asynchronous function that returns a greeting string after a short delay.
📋 What You'll Learn
Create an async function that returns a greeting string
Create a variable to hold the expected greeting
Write an async test function that calls the async greeting function
Print the result of the test to verify the greeting matches the expected value
💡 Why This Matters
🌍 Real World
Testing async code is important when working with network calls, file operations, or any tasks that take time to complete in real apps.
💼 Career
Many software jobs require writing and testing asynchronous code to ensure apps work smoothly without freezing or crashing.
Progress0 / 4 steps
1
Create the async greeting function
Create an async function called fetchGreeting() that returns a String. Inside, use try? await Task.sleep(nanoseconds: 1_000_000_000) to wait 1 second, then return the string "Hello, async world!".
Swift
Hint
Use func fetchGreeting() async -> String to define the async function. Use try? await Task.sleep(nanoseconds: 1_000_000_000) to pause for 1 second.
2
Create the expected greeting variable
Create a constant called expectedGreeting and set it to the string "Hello, async world!".
Swift
Hint
Use let expectedGreeting = "Hello, async world!" to create the constant.
3
Write the async test function
Write an async function called testFetchGreeting(). Inside, call fetchGreeting() with await and store the result in a variable called result. Then compare result with expectedGreeting using an if statement. If they match, print "Test passed", else print "Test failed".
Swift
Hint
Define func testFetchGreeting() async. Use let result = await fetchGreeting(). Use if result == expectedGreeting to check and print the test result.
4
Run the test and print the output
Call testFetchGreeting() inside a Task to run the async test. This will print either "Test passed" or "Test failed".
Swift
Hint
Use Task { await testFetchGreeting() } to run the async test and print the result.
Practice
(1/5)
1. What keyword must you add to a Swift test function to test asynchronous code?
easy
A. defer
B. await
C. async
D. try
Solution
Step 1: Understand async test function requirement
To test asynchronous code, the test function itself must be marked as asynchronous.
Step 2: Identify the correct keyword
The keyword to mark a function as asynchronous in Swift is async.
Final Answer:
async -> Option C
Quick Check:
async = async [OK]
Hint: Mark test functions with async to test async code [OK]
Common Mistakes:
Using await instead of async on test function
Forgetting to mark test function as async
Using try instead of async
Confusing defer with async
2. Which of the following is the correct syntax to wait for an async function fetchData() inside a test?
easy
A. let result = await fetchData()
B. let result = async fetchData()
C. await let result = fetchData()
D. fetchData().await()
Solution
Step 1: Recall await usage in Swift
In Swift, to wait for an async function, you use the await keyword before the function call.
Step 2: Check correct syntax
The correct syntax is let result = await fetchData(). The keyword await comes before the function call.
Final Answer:
let result = await fetchData() -> Option A
Quick Check:
await before function call = let result = await fetchData() [OK]
Hint: Put await before async function call to wait [OK]
Common Mistakes:
Placing await after let or variable
Using async instead of await before call
Calling await as a method
Omitting await keyword
3. Given this test code, what will be printed?
func testFetch() async {
let data = try? await fetchData()
print(data == nil ? "No Data" : "Got Data")
}
func fetchData() async throws -> String {
return "Hello"
}
medium
A. No Data
B. Compilation error
C. Runtime error
D. Got Data
Solution
Step 1: Analyze fetchData() behavior
The function fetchData() is async and throws but always returns "Hello" without throwing an error.
Step 2: Understand try? await usage
The try? await fetchData() will return the string "Hello" wrapped as optional, not nil, because no error is thrown.
Step 3: Evaluate print statement
Since data is not nil, the print outputs "Got Data".
Final Answer:
Got Data -> Option D
Quick Check:
try? await returns value = Got Data [OK]
Hint: try? returns nil only if error thrown, else returns value [OK]
Common Mistakes:
Assuming try? always returns nil
Confusing async throws with throwing error always
Ignoring optional unwrapping
Expecting compilation error due to async
4. Identify the error in this async test function:
func testDownload() async {
let result = fetchData()
XCTAssertEqual(result, "Success")
}
func fetchData() async -> String {
return "Success"
}
medium
A. XCTAssertEqual cannot compare strings
B. Missing await before fetchData() call
C. Test function should not be async
D. fetchData() must throw an error
Solution
Step 1: Check async function call
The function fetchData() is async, so calling it requires await to get the result.
Step 2: Identify missing await
In the test, fetchData() is called without await, causing a compile error.
Final Answer:
Missing await before fetchData() call -> Option B
Quick Check:
Async calls need await = Missing await before fetchData() call [OK]
5. You want to test an async function loadUser(id:) that throws an error if the user is not found. Which test code correctly checks that an error is thrown for an invalid id?
hard
A. func testLoadUserError() async throws {
do {
_ = try await loadUser(id: -1)
XCTFail("Expected error not thrown")
} catch {
XCTAssertTrue(true)
}
}
B. func testLoadUserError() async {
let user = try await loadUser(id: -1)
XCTAssertNil(user)
}
C. func testLoadUserError() async throws {
let user = await loadUser(id: -1)
XCTAssertNil(user)
}