How can I access a file inside of an XCTestCase?

I am trying to load a png file that is in the same folder as my test class. I use the code below but the call fails saying file does not exist.

try Data(contentsOf: URL(fileURLWithPath: "\(FileManager.default.currentDirectoryPath)media.png"))

I also tried creating an asset catalog into my test project and adding my file there, but no luck. This code fails as nil.

let mediaFile = NSDataAsset(name: "media")!.data

You shouldn't put resource files in the same directory as code. Are you using a swift package or an xcode project?

I have an xcode project that has a test project in it. Regardless I got it by doing this.

let fileImg = UIImage(named: "media", in: Bundle(for: ArweaveSvcMessageTests.self), compatibleWith: nil)
let mediaFileData = fileImg?.pngData()!

We've got the following helpers in a source file inside our Tests folder:

func fixtureData(for fixture: String) throws -> Data {
    try Data(contentsOf: fixtureUrl(for: fixture))
}


func fixtureUrl(for fixture: String) -> URL {
    fixturesDirectory().appendingPathComponent(fixture)
}


func fixturesDirectory(path: String = #file) -> URL {
    let url = URL(fileURLWithPath: path)
    let testsDir = url.deletingLastPathComponent()
    let res = testsDir.appendingPathComponent("Fixtures")
    return res
}

The #file default parameter resolves this to the source file's path. From there we resolve to the Fixtures directory inside Tests, which contains all manner of static data we want to load in for tests.

Hope that helps!

2 Likes

This seems to work well, but I'm curious about the potential differences between this approach, and the approach of:

It seems like the latter might be slightly more robust -- in that it's not reliant on placing the aforementioned utilities in a specific directory location.

My Helpers.swift inside the Unit Test target. The resources are added to the Unit Test target also.

func testURLForResource(_ resourceName: String) -> URL {
    return Bundle(for: Helpers.self)
        .url(forResource: resourceName, withExtension: nil)!
}

func dataFrom(resource: String) -> Data {
    let url = testURLForResource(resource)
    do {
        let data1 = try Data(contentsOf: url)
        return data1
    } catch { }

    return Data()   // should never happen
}

func imageFrom(resource: String) -> UIImage? {
    let url = testURLForResource(resource)
    let image = UIImage(contentsOfFile: url.path)
    return image
}

func stringFrom(resource: String) -> String? {
    let url = testURLForResource(resource)
    do {
        let value = try String(contentsOfFile: url.path, encoding: String.Encoding.utf8)
        return value
    } catch { }

    return nil
}

class Helpers {
}