XCTest checker

2020.06.16 更新:經測試第 1 個方法有可能判斷錯誤,已不推薦

  1. 在當下線程檢查是否在執行 XCTest(Unit Testing)
    extension Thread {
      var isRunningXCTest: Bool {
        for key in self.threadDictionary.allKeys {
          guard let keyAsString = key as? String else {
            continue
          }
        
          if keyAsString.split(separator: ".").contains("xctest") {
            return true
          }
        }
        return false
      }
    }

    使用方式

    if Thread.current.isRunningXCTest {
        // is running unit testing
    }
    
  2. 另一種方式
    if ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"] != nil {
        // Code only executes when tests are running
    }

UI Testing Checker

在 UITest 檔案裡設定 “–uitesting” flag

import XCTest

class OnboardingUITests: XCTestCase {
    var app: XCUIApplication!
    
    // MARK: - XCTestCase
    override func setUp() {
        super.setUp()
        
        // Since UI tests are more expensive to run, it's usually a good idea to exit if a failure was encountered
        continueAfterFailure = false
        
        app = XCUIApplication()
        
        // We send a command line argument to our app, to enable it to reset its state
        app.launchArguments.append("--uitesting")
    }
}

使用if CommandLine.arguments.contains("--uitesting") 來判斷是否正在執行 UI Testing

import UIKit

@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    
    func application(_ application: UIApplication,
                                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
        if CommandLine.arguments.contains("--uitesting") {
            resetState()
        }
        
        let mainVC = MainViewController()
        
        let window = UIWindow(frame: UIScreen.main.bounds)
        window.rootViewController = mainVC
        window.makeKeyAndVisible()
        self.window = window
        
        return true
    }
}

private extension AppDelegate {
    // Reset all userdefaults
    func resetState() {
        let defaultsName = Bundle.main.bundleIdentifier!
        UserDefaults.standard.removePersistentDomain(forName: defaultsName)
    }
}