ググっているとdocumentDirectoryを削除するとか色々出てくるのですが、ファイルまで消さなくてもオブジェクトだけ簡単に削除できたら良いやと思ったので、自前で実装してみました。
コードと解説
AppDelegateなどに、以下のコードを記述してください。
- 万が一のことがないようにCompilation Conditionsを利用してリリースビルドでクリーンアップ処理が混入しないようにしています。
- ProcessInfoを利用して注入された環境値を読み取って、UITestであればクリーンアップ処理を実行します
#if DEBUG
if ProcessInfo.processInfo.environment["UI_TEST"] == "1" {
CoreDataStack.shared.cleanUp()
}
#endif
CoreDataを管理しているクラスなどで以下のコードを記述してください。
- こちらも同様に#if DEBUGを利用してリリースへのデバッグコード混入を避けています。
- 全てのエンティティに対して全データのフェッチを要求してfor文を回して削除を実行しています
- コンテキストの保存を行なっています。
NSBatchDeleteRequestを利用しても良いのですが、UIテストの実行ではデータ件数がそれほど多くないはずなので安易にforを利用しています。
#if DEBUG
func cleanUp() {
let viewContext = persistentContainer.viewContext
for entity in persistentContainer.managedObjectModel.entities {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity.name!)
let results = try! viewContext.fetch(fetchRequest)
for result in results {
viewContext.delete(result)
}
}
if viewContext.hasChanges {
try! viewContext.save()
}
}
#endif
UITestのテストクラスで記述してください。
中段のlaunchEnvironment["UI_TEST"] = "1"
で環境変数を注入しています。
テストプランやスキームに記述したlaunchEnvironmentは、テストターゲット全体での実行時には環境変数を注入してくれますが、個別に実行した場合には影響しない(*筆者の環境が変なだけかもしれません。違ったら教えてください)ので、テストクラスごとに設定しています。
class YourUITest: XCTestCase {
private var app: XCUIApplication!
override func setUpWithError() throws {
continueAfterFailure = false
app = XCUIApplication()
app.launchEnvironment["UI_TEST"] = "1"
app.launch()
}
}