Changing The Core Data Test Store Location

A quick tip to change the default directory for your Core Data database files when unit testing.

Where’s My Core Data Store?

If you’re using NSPersistentContainer to setup your Core Data stack it provides a default, platform specific, location for the database files. For iOS applications this defaults to the “Application Support” directory of the application container.

If you’re running in the simulator you’ll find the files for each simulator buried deep in the Library folder under your Mac home directory:

// Simulator Device data location
cd ~/Library/Developer/CoreSimulator/Devices/<Device UDID>

// Application Container location
cd data/Containers/Data/Application/<App UDID>

// iOS Application Support Directory
cd Library/Application Support

Finder Application Support folder with Facts.sqlite, Facts.sqlite-shm and Facts.sqlite-wal files

Changing The Default For Unit Tests

When unit testing with Core Data I like using an in-memory store for speed and ease of clean up. But I also want, at least some of the time, to test with a disk-based store. Changing the location of the test database avoids overwriting or conflicting with any application database that I might already have installed on the simulator or device.

I’m using a launch argument to detect when I’m testing. See Faster App Setup For Unit Tests for details.

Test action scheme with launch argument -UNITTEST

To change the default directory I’m overriding the defaultDirectoryURL class method in a subclass of NSPersistentContainer and checking for the launch argument:

final class CoreDataContainer: NSPersistentContainer {
  override class func defaultDirectoryURL() -> URL {
    if ProcessInfo.processInfo.arguments.contains("-UNITTEST") {
      return super.defaultDirectoryURL()
        .appendingPathComponent("UNITTEST", isDirectory: true)
    }
    return super.defaultDirectoryURL()
  }
}

If we’re testing I append “UNITTEST” to the default directory path. My test database files are now kept in their own directory separate from any application files.

Swift Package Manager

One quick extra note. I’ve started moving my Core Data code and model to a Swift Package. That has an interesting implication when running unit tests for the package. There is no application so the data files end up in a common Application Support directory located at the device level:

// Swift Package Manager Application Support
<Device UDID>/data/Library/Application Support/

Learn More