Posted by SarahM
November 14, 2023, 11:05 AM
Great question, Alex! For UI testing, we've found XCUITest to be powerful but sometimes brittle. Making sure your tests are atomic and don't rely on the state of previous tests is key. Also, using accessibility identifiers makes your selectors much more robust than relying on button titles or element types.
For unit testing, the built-in `XCTest` framework is excellent. I highly recommend looking into mocking libraries like `OHHTTPStubs` for network requests and `Cuckoo` or even manual protocol mocking for easier dependency injection.
Here's a simple example of mocking a network layer:
// Using OHHTTPStubs
@testable import MyApp
class NetworkServiceTests: XCTestCase {
func testFetchUserDataSuccess() {
stub(condition: isHost("api.example.com")) { _ in
let stubPath = OHPathForFile("success_user.json", self.classForCoder)
return fixture(filePath: stubPath!, status: 200, headers: ["Content-Type": "application/json"])
}
let networkService = NetworkService()
let expectation = self.expectation(description: "Fetch user data")
networkService.fetchUserData(userId: "123") { result in
switch result {
case .success(let user):
XCTAssertEqual(user.name, "Jane Doe")
expectation.fulfill()
case .failure(_):
XCTFail("Should have succeeded")
}
}
waitForExpectations(timeout: 5, handler: nil)
}
}