0

MacOS 12.5, Xcode 13.4.1

I'm hoping to add swift-based unit tests to an existing project that is Mach-O type "Bundle" (com.apple.product-type.bundle) and acts as a plugin to a third project. Unfortunately I get linking errors when trying to run the unit test bundle such as below.

Underlying Error: The bundle “SOExample Unit Tests” couldn’t be loaded. The bundle couldn’t be loaded. Try reinstalling the bundle. dlopen(/Users/n8henrie/Library/Developer/Xcode/DerivedData/SOExample-fpwfambnggoejceucflywazoligm/Build/Products/Debug/SOExample Unit Tests.xctest/Contents/MacOS/SOExample Unit Tests, 0x0109): Symbol not found: (_$s9SOExample3FooCACycfC)
  Referenced from: '/Users/n8henrie/Library/Developer/Xcode/DerivedData/SOExample-fpwfambnggoejceucflywazoligm/Build/Products/Debug/SOExample Unit Tests.xctest/Contents/MacOS/SOExample Unit Tests'
  Expected in: '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Agents/xctest')

I'm using @testable import, have testability set to yes, and am setting the Bundle loader to the bundle's executable.

I've created an example project to demonstrate the issue at https://github.com/n8henrie/so-xcode-unittest-example.git. To create it, I just made a new Xcode project of type "Bundle", added File.swift with class Foo and method bar(), then added a new target -> unit test bundle, which basically tests that it can create a Foo and run bar(). I then add the main target as the Bundle loader and commit changes. One should be able to test as follows:

$ git clone https://github.com/n8henrie/so-xcode-unittest-example.git
$ cd so-xcode-unittest-example/
$ xcodebuild -scheme "SOExample Unit Tests" test

It currently fails with the above "couldn't be loaded" error. It looks like the symbols are there (I think -- I'm new to this):

$ nm -gU SOExample
0000000000003d78 T _$s9SOExample3FooC3barSSyF
0000000000003f34 S _$s9SOExample3FooC3barSSyFTq
0000000000003e14 T _$s9SOExample3FooCACycfC
0000000000003f3c S _$s9SOExample3FooCACycfCTq
0000000000003e4c T _$s9SOExample3FooCACycfc
0000000000003e70 T _$s9SOExample3FooCMa
0000000000008090 D _$s9SOExample3FooCMm
0000000000003f00 S _$s9SOExample3FooCMn
00000000000080c8 D _$s9SOExample3FooCN
0000000000003dd8 T _$s9SOExample3FooCfD
0000000000003db4 T _$s9SOExample3FooCfd

If I change the Mach-O type to Dynamic Library, Static Library, or Relocatable Object File, the linking succeeds and the example test passes.

NB: In this specific toy case I can also get the tests to pass while leaving the Mach-O type as bundle if I add SOExample Unit Tests to the target membership for File.swift; however this doesn't work for my real-world scenario (and I think employing @testable import should make this unnecessary, especially as it works with other Mach-O types).

Is there a way to run my unit tests:

  • leaving the Mach-O type as Bundle
  • without modifying "target membership"

?

Relevant links (without solutions that I've found)

n8henrie
  • 2,737
  • 3
  • 29
  • 45
  • Did you figure this out? I'm trying something related: I have code in a bundle that I want to test, but I get link errors in the test target where it can't find the symbols I'm referencing in the bundle. – Steve Madsen Feb 07 '23 at 15:57
  • I ended up adding a separate target for the tests I think, but eventually got something that works well enough. Relevant commits here: https://github.com/quicksilver/plugin_template/commits/main – n8henrie Feb 07 '23 at 16:24
  • Sort of similarly, I ended up extracting the code I wanted to test out of the bundle and into a local Swift package. That makes it its own module and can be easily referenced from the unit test bundle. – Steve Madsen Feb 08 '23 at 18:36
  • If your code is open source, would you mind sharing a link? – n8henrie Feb 09 '23 at 01:00
  • It isn't, otherwise I'd be happy to. – Steve Madsen Feb 10 '23 at 14:39

0 Answers0