Accessing Resources from Test Cases in Swift

This is just a reminder from me to me. I constantly find myself searching through my previous projects trying to remember how to do this. Putting it in my blog might make it easier to find it in future.

Quite often, when writing test cases, I want to access resources that are not Swift code. For example, my 6502 project has a 6502 program that exercises every single 6502 instruction. At first, I was effectively hand compiling the program and embedding it into the Swift test cases. After a while I thought, wouldn’t it be better to properly write a 6502 program and use a real assembler to make a binary and then load it into the memory of the 6502? Well I could create the binary and then put it on disk and use Swift’s IO to load it into the CPU’s memory, but that required putting a file path into the test case code. It’s much better to include it as a bundle resource and then access the resource from the test case.

How to do that from Swift. Well adding the resource to the test bundle is easy. Add the resource to the target and then make sure it is copied during the “copy bundle resources” phase of the build.

Screenshot 2019-09-19 at 18.51.53

The code needed to access that is quite simple, but if you don’t know how to do it needs at least five minutes of Googling. So here it is.

class SomeTest: XCTestCase
{
// Some stuff

    override func setUp()
    {
        super.setUp()
        let myBundle = Bundle(for: type(of: self))
        let binaryFileUrl = myBundle.url(forResource: "coveragetest", withExtension: "bin")
        guard let binaryFileUrl = binaryFileUrl else { fatalError("Could not locate coverage test binary") }

        do 
        {
            let program = try Data(contentsOf: binaryFileUrl)
            // Do something with the data
        }
        catch 
        {
            fatalError("Could not read test coverage program")
        }
    }
    // All the test cases
}

The only slightly non obvious line is the one that says

let myBundle = Bundle(for: type(of: self))

This line is the easiest way to locate the bundle of the test suite without specifying its name or location. It just gives you the bundle containing the test case class.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.