Darren Oakey
Darren Oakey

Reputation: 3594

IOS tests interacting with Mac file system

So I'm playing around with swiftui XCTestCase. I have a bunch of tests that run and get that they are running in the simulator or on the device.

However - I now have a need to interact with the Mac I'm on - ie read and write to the Mac file system from the IOS tests - is it possible - as the test is running in the simulator.

Upvotes: 1

Views: 416

Answers (1)

dive
dive

Reputation: 2210

XCTestCase has access to the local file system be design with some restrictions. For example:

func testExample() throws {
    print("\(Bundle.allBundles)")
    print("\(Bundle(for: type(of: self)))")
}

This code will produce something like this:

[NSBundle </Volumes/Extended/Archive/Xcode_11.6.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/CoreServices/CoreGlyphs.bundle> (not yet loaded), NSBundle </Users/dive/Library/Developer/CoreSimulator/Devices/9CDF771B-204F-45B9-AAC3-6036AB7B117D/data/Containers/Bundle/Application/5DE85255-F202-4BAB-871A-7C20C2DB37D9/TestingBundles.app> (loaded), NSBundle </Users/dive/Library/Developer/CoreSimulator/Devices/9CDF771B-204F-45B9-AAC3-6036AB7B117D/data/Containers/Bundle/Application/5DE85255-F202-4BAB-871A-7C20C2DB37D9/TestingBundles.app/Frameworks> (not yet loaded), NSBundle </Users/dive/Library/Developer/Xcode/DerivedData/TestingBundles-exdmnsfatmhbztarzgjvvlwwpoan/Build/Products/Debug-iphonesimulator/TestingBundles.app/PlugIns/TestingBundlesTests.xctest> (loaded)]

NSBundle </Users/dive/Library/Developer/Xcode/DerivedData/TestingBundles-exdmnsfatmhbztarzgjvvlwwpoan/Build/Products/Debug-iphonesimulator/TestingBundles.app/PlugIns/TestingBundlesTests.xctest> (loaded)

As you can see, these paths are related to the DerivedData directory. As a result, you cannot use relative paths to the directory with your project or tests.

Also, you can use FileManager directly. It inherits the same environment and has access to the local file-system as well. For example:

func testExample() throws {
    let manager = FileManager.default
    print(try manager.contentsOfDirectory(atPath: ("~/" as NSString).expandingTildeInPath))
}

It will produce something like this:

/Users/USER_NAME/Library/Developer/CoreSimulator/Devices/9CDF771B-204F-45B9-AAC3-6036AB7B117D/data/Containers/Data/Application/0D16C376-80A6-4DAE-B435-2FEF7F08A83A

Note, that because of the environment, it points to the home directory of the user within a simulator.

As a workaround, we are using a Shared user directory to share such data. There is a "Run Script" in the Test Pre-Actions that copies it:

enter image description here

Then we access it from XCTestCase like this:

try manager.contentsOfDirectory(atPath: "/Users/Shared/TestData")

It is not ideal and, perhaps, there are some other solutions. But it works fine and has a predictable behaviour.

Upvotes: 1

Related Questions