Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XCTest: Load file from disk without Bundle on all platforms (Xcode, SPM Mac/Linux)

I am looking for a way to load files from disk within an XCTestCase that does not depend on Bundle.

Bundle works well when running the tests from Xcode (or with xcodebuild on the terminal), but bundles are part of the Xcode project and not available to Swift Package Manager (when running swift test), neither on the Mac nor in Linux.

Is there a way to specify the current directory where tests should be run that works in all platforms? Or maybe there is a way to determine where the tests are located that also works on all platforms?

FileManager.default.currentDirectoryPath only returns the current execution path (working directory).

like image 981
Eneko Alonso Avatar asked Jan 29 '23 12:01

Eneko Alonso


1 Answers

This method seems to work for me, and should work with both Xcode 11 and from the command line. Copy of the answer I just wrote here.

struct Resource {
  let name: String
  let type: String
  let url: URL

  init(name: String, type: String, sourceFile: StaticString = #file) throws {
    self.name = name
    self.type = type

    // The following assumes that your test source files are all in the same directory, and the resources are one directory down and over
    // <Some folder>
    //  - Resources
    //      - <resource files>
    //  - <Some test source folder>
    //      - <test case files>
    let testCaseURL = URL(fileURLWithPath: "\(sourceFile)", isDirectory: false)
    let testsFolderURL = testCaseURL.deletingLastPathComponent()
    let resourcesFolderURL = testsFolderURL.deletingLastPathComponent().appendingPathComponent("Resources", isDirectory: true)
    self.url = resourcesFolderURL.appendingPathComponent("\(name).\(type)", isDirectory: false)
  }
}

Usage:

final class SPMTestDataTests: XCTestCase {
  func testExample() throws {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct
    // results.
    XCTAssertEqual(SPMTestData().text, "Hello, World!")

    let file = try Resource(name: "image", type: "png")
    let image = UIImage(contentsOfFile: file.url.path)
    print(image)
  }
}

enter image description here

I found the key of using #file here

like image 70
jamone Avatar answered Feb 05 '23 19:02

jamone