10

My iOS app has multiple extensions:

  • today extension

  • siri extension

  • imessage extension

Also I created framework to share common code. My problem is that I want to have one unit test target which will test all extension. My Podfile looks like this:

 target 'MyApp' do
   pod 'MyFramework', :path => './MyFramework'
     target 'MyAppTests' do
       inherit! :search_paths
     end
 end

abstract_target 'Extensions' do
  pod 'MyFramework', :path => './MyFramework'
  target 'TodayExtension'
  target 'SiriExtension'
  target 'iMessageExtension'
  target 'ExtensionsTests'
end

As you see I created ExtensionsTests target but I don't know how I can inherit search path of all extensions. I also tried to use @testable import TodayExtension but I get linked error for undefined symbols for architecture x86_64.

Any ideas how I can fix this?

Complete error code:

Undefined symbols for architecture x86_64:
  "type metadata accessor for TodayExtension.LoadingView", referenced from:
      ExtensionTests.LoadingViewTests.setUp () -> () in LoadingViewTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

EDIT:

I think that problem is general: how I can test any extension code? I created single view project, added today extension and I'm not able to extension code.

In apple docs there is only this information:

To test an app extension using the Xcode testing framework (that is, the XCTest APIs), write tests that exercise the extension code using your containing app as the host environment. To learn more about testing, see Testing with Xcode.

which is not very helpful

MichalMoskala
  • 887
  • 1
  • 12
  • 25

3 Answers3

2

I ran into the same issue. According to this answer, unit testing extensions in this way is unsupported. As a workaround, you can factor out the code you’d like to test into a framework and include it in both your extension target and in your extension test target.

Community
  • 1
  • 1
paulrehkugler
  • 3,241
  • 24
  • 45
2

The quote from Apple documentation is exactly right.

To test an app extension using the Xcode testing framework (that is, the XCTest APIs), write tests that exercise the extension code using your containing app as the host environment. To learn more about testing, see Testing with Xcode.

You may be falling into a pitfall that I find myself falling into a lot: Unit test are supposed to test the "unit" for functionality. Don't test every little helper function you have in the the "unit" but test the public functions. The same goes for frameworks. Write tests only for the public functionality. If you are testing more you are spending too much time writing tests.

You can create a Unit Test target and select you main app as the "Target to be Tested" Then in the test files just load the extension like a host app would and test that the interactions that the host app would use are returning correctly.

Lucas Goossen
  • 527
  • 7
  • 15
1

undefined symbols for architecture x86_64

The error tells you that TodayExtension(or parts of it) can not be found (does/do not exist) for architecture x86_64. Architecture x86_64 is your simulators architecture.

I suspect you build TodayExtension with target set to a real device (architecture arm x) and TodayExtension build setting Build Active Architecture Only is set to YES, which means it builds for your target devices architecture (arm x) and not for the simulator (x86_64).

Fix

In TodayExtensions build settings (and in all its dependencies, if any):

  • Set Build Active Architecture Only to NO

  • Set Valid Architectures to arm64, armv7, armv7s, i386, x86_64 (if not set already

Rebuild TodayExtension

If your problem persists, double check the artefacts slice(s). In Terminal:

file /path/to/TodayExtension.apex/TodayExtension

It should output:

/path/to/TodayExtension.appex/TodayExtension: Mach-O 64-bit executable x86_64

and for your framework:

file /path/to/MyFramework.framework/MyFramework

should output:

path/to//MyFramework.framework/MyFramework: Mach-O universal binary with 5 architectures
path/to//MyFramework.framework/MyFramework (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64
path/to//MyFramework.framework/MyFramework (for architecture i386): Mach-O dynamically linked shared library i386
path/to//MyFramework.framework/MyFramework (for architecture armv7):    Mach-O dynamically linked shared library arm
path/to//MyFramework.framework/MyFramework (for architecture armv7s):   Mach-O dynamically linked shared library arm
path/to//MyFramework.framework/MyFramework (for architecture arm64):    Mach-O 64-bit dynamically linked shared library
shallowThought
  • 19,212
  • 9
  • 65
  • 112
  • I needed to set Build Active Architecture Only also to all dependencies of TodayExtension to make it work. But when I try to test ExtensionTests target i still get that error. I think problem is connected with other thing. – MichalMoskala Nov 14 '16 at 12:09
  • Please add the complete error `linked error for undefined symbols for architecture x86_64` to the question. – shallowThought Nov 14 '16 at 12:17
  • Is your test target a`UITest` target? `type metadata accessor` is suspicious. – shallowThought Nov 14 '16 at 18:03