'Module was not compiled for testing' when using @testable

I'm trying to use Swift 2's new @testable declaration to expose my classes to the test target. However I'm getting this compiler error:

Intervals is the module that contains the classes I'm trying to expose. How do I get rid of this error?

In your main target you need to set the Enable Testability build option to Yes.

As per the comment by @earnshavian below, this should only be used on debug builds as per apple release notes: "The Enable Testability build setting should be used only in your Debug configuration, because it prohibits optimizations that depend on not exporting internal symbols from the app or framework" https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html#//apple_ref/doc/uid/TP40001051-CH1-SW326

In my case I used a custom build configuration for testing (called Test) and also cocoapods as a dependency manager

I had to add the following lines to the end of my Podfile to enable testability

post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            if config.name == 'Test'
                config.build_settings['ENABLE_TESTABILITY'] = 'YES'
            end
        end
    end
end

By default cocoapods sets ENABLE_TESTABILITY to YES only for Debug builds

Make sure that you properly set your checkboxes under your app scheme. You SHOULD UNCHECK your test targets for Archive Build.

For those of you who are experiencing this only upon running Xcode Profiler: switch profile build configuration in your scheme management to the one that has testability enabled - and that would be debug in most cases:

This is probably because your main target Enable Testability is set to NO. You should set it to YES in the debug scheme (which is used for running your tests).

If you use Carthage, this problem can be caused by importing frameworks with @testable, because they are built with a release scheme.

Most of the times it's bad practice to import frameworks with that prefix, so you could avoid it. If you can't, you should Enable Testability in the frameworks' release scheme. https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html#//apple_ref/doc/uid/TP40001051-CH1-SW326

Comments
  • Hi, I'm getting the same error but not seeing the enable testability option and am using xcode 7. Any idea what I should do?
  • @user1601259 - You can find the option by selecting the top level project, going to Build Settings, and looking under the Build Options heading.
  • @hgwhittle - When i select the top level project, all I see in build options is "debug information format" and "validate build product." When I select the target in build options I see "embedded content contains swift code." That's it. When I search in build settings I cannot find it. Is this because of xcode 7?
  • It is possible that you have selected "Basic" in your "Build Settings". If you select "All" on the left side, you will see "Enable Testability"
  • How exactly should this work for release builds, where tests will run (so need @testable) but need to submit to the App Store? If Enable Testability is just for debug builds, what is the way around this? Do I have to pull out my test code for release?
  • For more information look here: developer.apple.com/library/mac/technotes/tn2215/_index.html
  • How can I avoid importing frameworks using @testable? What's the good practice here?
  • This worked for me.
  • If you don't need the tests, it might be better to remove the test targets from your project instead of removing them from all the builds.