hgwhittle
hgwhittle

Reputation: 9426

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

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

enter image description here

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

Upvotes: 180

Views: 47548

Answers (14)

D. Rothschild
D. Rothschild

Reputation: 719

Here is an interesting possible solution. Apparently SPM doesn't build debug versions if your active configuration does not have the word debug, without spaces. Details here: https://forums.swift.org/t/update-swiftpm-to-support-custom-configuration-names/43075/12

I did the above and one more thing that finally fixed the error. My Product Name in Build Settings was the same as my Target name. When I change the Product Name to something different and imported the product name then the error went away.

Note that changing the product name changes the module name. The test target properly linked the app target with a different product name than the target name. So if you target name is Foo, your app and module name needs to be something different like BarCool. Then @testable import BarCool.

Xcode’s internal handling of module names can sometimes lead to residual mismatches when the product name is inconsistent or modified across configurations, especially with multiple schemes and environments.

Also now I am finding that as I add more files that have tests in my test target (using XCTest and Testing), the most recently added file has the error while the other files do not. So my most recent file is now just a mock/dummy test like this, to "hold" the error. The error doesn't seem to impact running the tests.

class MockTests: XCTestCase {

 func testPlaceholder() {
   XCTAssertTrue(true, "This is a placeholder test to ensure the test suite runs successfully.")
 }
}

Upvotes: 0

MMise
MMise

Reputation: 129

I had a problem where Xcode would show the Module 'Foo' was not compiled for testing, but I could still run the tests normally. The downside was that any code errors or warnings would not show up.

What solved this after trying everything else was to set Enable Testing Search Paths (ENABLE_TESTING_SEARCH_PATHS)to Yes.

Note that this was for my own dynamic framework's unit tests and that framework is used by an app

Upvotes: 0

Graham Perks
Graham Perks

Reputation: 23398

I got this when my new Tests.swift file belonged to the wrong Target.

Upvotes: 0

Cable W
Cable W

Reputation: 673

I'm a beginner and I just can't remember where all the settings and options are in Xcode. So I always feel frustrated when I see "you can set xxx to yyy ..." in answers to this kind of question. Where are those xxx in Xcode? and What are those yyy? We need a map showing how we get things done, but not another clue, like xxx. It seems we are Nicolas Cage in National Treasure!

Thanks for all the clues here, very much! You really help me. But I have a concrete answer here (which is actually from you):

  1. Select the main target of your project
  2. Go to the "Build Settings" tab
  3. Turn on the "All" option
  4. Search for the "Build Options" section
  5. Set "Enable Testability" to "Yes"
  6. Wait for a few minutes or restart Xcode (then the error disappeared)

Upvotes: 2

Nuno Gonçalves
Nuno Gonçalves

Reputation: 6805

If by any chance you have

install! 'cocoapods',
         generate_multiple_pod_projects: true,
         incremental_installation: true

Then, this is the way to do it.

    # generated_projects only returns results if the we run "pod install --clean-install"
    # or install a pod for the first time

    installer.generated_projects.each do |project|
        project.build_configurations.each do |configuration|
            configuration.build_settings["ENABLE_TESTABILITY"] = "YES" 
        end
    end

Upvotes: 2

Bartłomiej Semańczyk
Bartłomiej Semańczyk

Reputation: 61842

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

enter image description here

Upvotes: 20

rgkobashi
rgkobashi

Reputation: 2698

I started getting this error when running tests using Bitrise.

Unlike other users says, this is not per Target basis, or per Schema basis, it is per Configuration basis. Select Target -> Build Settings tab -> look for testability -> Enable it on the Configuration that you are using.

Please notice that Apple recommends to enable this on the configuration that you are using for debugging, not for AppStore.

Upvotes: 12

Zaporozhchenko Oleksandr
Zaporozhchenko Oleksandr

Reputation: 4928

If you trying to test framework:

Go to test target -> Build Phase -> Create new copy files phase -> Choose frameworks -> Add all recursively used frameworks

Upvotes: 0

Tim
Tim

Reputation: 1894

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

Upvotes: 22

nikBhosale
nikBhosale

Reputation: 541

Above solution is fine if you are using pods/Carthage. But if you are using frameworks from iOS itself 'e.g. Contacts', you need add path to these frameworks in 'Library Search Paths' of your main project's target. enter image description here

Upvotes: 0

Wladek Surala
Wladek Surala

Reputation: 2629

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:

enter image description here

Upvotes: 11

Samuel B.
Samuel B.

Reputation: 371

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

Upvotes: 7

sgaw
sgaw

Reputation: 3178

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

Upvotes: 294

Blaszard
Blaszard

Reputation: 31985

This didn't occur in my projects prior to Xcode 8, but after I upgraded to Xcode 8, it made me perplexed.

The answers posted here didn't get my problems resolved. For me, I just ditched these tests as it is not needed. So uncheck the test buttons:

enter image description here And now the error has gone out.

Upvotes: -5

Related Questions