classSetUpAndTearDownExampleTestCase:XCTestCase {overrideclassfuncsetUp() { // 1.// This is the setUp() class method.// It is called before the first test method begins.// Set up any overall initial state here. }overridefuncsetUpWithError() throws { // 2.// This is the setUpWithError() instance method.// It is called before each test method begins.// Set up any per-test state here. }overridefuncsetUp() { // 3.// This is the setUp() instance method.// It is called before each test method begins.// Use setUpWithError() to set up any per-test state,// unless you have legacy tests using setUp(). }functestMethod1() throws { // 4.// This is the first test method.// Your testing code goes here.addTeardownBlock { // 5.// Called when testMethod1() ends. } }functestMethod2() throws { // 6.// This is the second test method.// Your testing code goes here.addTeardownBlock { // 7.// Called when testMethod2() ends. }addTeardownBlock { // 8.// Called when testMethod2() ends. } }overridefunctearDown() { // 9.// This is the tearDown() instance method.// It is called after each test method completes.// Use tearDownWithError() for any per-test cleanup,// unless you have legacy tests using tearDown(). }overridefunctearDownWithError() throws { // 10.// This is the tearDownWithError() instance method.// It is called after each test method completes.// Perform any per-test cleanup here. }overrideclassfunctearDown() { // 11.// This is the tearDown() class method.// It is called after all test methods complete.// Perform any overall cleanup here. }}
functestNasaData() throws {let rawResponse =""" { "description": "The past year was extraordinary for the discovery of extraterrestrial fountains and flows -- some offering new potential in the search for liquid water and the origin of life beyond planet Earth.. Increased evidence was uncovered that fountains spurt not only from Saturn's moon Enceladus, but from the dunes of Mars as well. Lakes were found on Saturn's moon Titan, and the residual of a flowing liquid was discovered on the walls of Martian craters. The diverse Solar System fluidity may involve forms of slushy water-ice, methane, or sublimating carbon dioxide. Pictured above, the light-colored path below the image center is hypothesized to have been created sometime in just the past few years by liquid water flowing across the surface of Mars.",
"copyright": "MGS, MSSS, JPL, NASA", "title": "A Year of Extraterrestrial Fountains and Flows", "url": "https://apod.nasa.gov/apod/image/0612/flow_mgs.jpg", "apod_site": "https://apod.nasa.gov/apod/ap061231.html", "date": "2006-12-31", "media_type": "image", "hdurl": "https://apod.nasa.gov/apod/image/0612/flow_mgs_big.jpg" } """// XCTUnwrap嘗試解開可選的內容,如果可選的內容為nil,則會拋出錯誤(並因此導致測試失敗)let data =tryXCTUnwrap(rawResponse.data(using: .utf8))let nasaData =tryXCTUnwrap(JSONDecoder().decode(NasaData.self, from: data))XCTAssertEqual(nasaData.date, "2006-12-31")XCTAssertEqual(nasaData.mediaType, "image")}
2. 對 API 做異步測試:使用 XCTestExpectation(這算是整合測試,不是單元測試)
functestDataManagerGetNasaData() {// 宣告expectationlet expect =expectation(description:"Get nasa data")let dataManager =DataManager()let urlString ="https://raw.githubusercontent.com/cmmobile/NasaDataSet/main/apod.json" dataManager.getNasaData(urlString: urlString) { result inswitch result {case .success(_):XCTAssert(true)case .failure(_):XCTAssert(false) }// 達成期望,讓test runner知道可以繼續 expect.fulfill() }// 等待期望被實現,或者10秒後超時wait(for: [expect], timeout:10.0)}
3. 對 ViewModel 或是 Manager 測試:當遇到 API 或資料庫,可用 Protocol 抽離實作並依賴注入(DI)
functestDataManagerWithDIGetNasaData() throws {let fakeDataProvider =FakeDataProvider()let dataManagerWithDI =DataManagerWithDI(dataProvider: fakeDataProvider) dataManagerWithDI.dataProvider = fakeDataProvider dataManagerWithDI.getNasaData { result inswitch result{case .success(_):XCTAssert(true)case .failure(_):XCTAssert(false) } }}classFakeDataProvider:DataProviderDelegate{funcgetData(url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) ->Void){let dataString =""" [{ "description": "The past year was extraordinary for the discovery of extraterrestrial fountains and flows -- some offering new potential in the search for liquid water and the origin of life beyond planet Earth.. Increased evidence was uncovered that fountains spurt not only from Saturn's moon Enceladus, but from the dunes of Mars as well. Lakes were found on Saturn's moon Titan, and the residual of a flowing liquid was discovered on the walls of Martian craters. The diverse Solar System fluidity may involve forms of slushy water-ice, methane, or sublimating carbon dioxide. Pictured above, the light-colored path below the image center is hypothesized to have been created sometime in just the past few years by liquid water flowing across the surface of Mars.",
"copyright": "MGS, MSSS, JPL, NASA", "title": "A Year of Extraterrestrial Fountains and Flows", "url": "https://apod.nasa.gov/apod/image/0612/flow_mgs.jpg", "apod_site": "https://apod.nasa.gov/apod/ap061231.html", "date": "2006-12-31", "media_type": "image", "hdurl": "https://apod.nasa.gov/apod/image/0612/flow_mgs_big.jpg" }] """let data =Data(dataString.utf8)completionHandler(data, nil ,nil) }}
4. 性能測試:使用Measure Block
classPerformanceTests:XCTestCase {lazyvar testData: [Int] = {return(0..<100000).map { Int($0) } }()functest_performance_getEvenNumbers_forEachLoop() {//這個區塊會運行10次,收集平均執行的時間和運行的標準偏差measure {var evenNumbers: [Int] = [] testData.filter { number in number %2==0}.forEach { number in evenNumbers.append(number) } } }functest_performance_getEvenNumbers_forLoop() {//這個區塊會運行10次,收集平均執行的時間和運行的標準偏差measure {var evenNumbers: [Int] = []for number in testData {if number %2==0 { evenNumbers.append(number) } } } }}
性能測試需要設置Baseline來驗證是否通過測試,沒有設置的會提示No baseline average for Time。