Adding Swift files to test target not fixing unit tests
After much headache and putting this on the back burner, I found that the main problem was when adding files to the test target membership, the Objective-C classes would still complain. I figured it was an old compatibility issue with the new way Swift does unit tests, but the solution was my test target didn't know there was a bridging header. Thus, I added a reference to it in my test target's build settings, like so:
It seems simple and obvious now, but the errors were unhelpful. No other solutions I saw for Swift unit tests suggested this could be an issue, but now I know.
Tl;dr
For unit tests to work in Swift, the test target must know everything the app target knows, so add a reference to your bridging header in your test target too (if applicable).
No such module when using @testable in Xcode Unit tests
The answer that worked for me
The answer was that I had some errors in my project that was making the build fail. (It was just your standard every day bug in the code.) After I fixed the errors and did another clean and build, it worked.
Note that these errors didn't show up at first. To get them to show up:
- Comment out your entire Test file that is giving you the "No such module" error.
- Try to run your project again.
If there are other errors, they should show up now. Fix them and then uncomment your Test file code. The "No such module" error was gone for me.
In case this doesn't solve the problem for other people, you can also try the following:
Clean the build folder
Open the Product menu, hold down Option, and click "Clean Build Folder..."
Make sure that Enable Testability is set to Yes
In the Project Navigator click your project name. Select Build Settings and scroll down to Build Options. Make sure that Enable Testability is Yes (for debug).
Delete and re-add your Tests target
If you have done the other things my guess is that you probably don't need to do this. But if you do, remember to save any Unit Tests that you have already written.
Click your project name in the Project Navigator. Then select your Tests target. Click the minus (-) button at the bottom to delete it.
Then click the plus (+) button and choose iOS Unit Testing Bundle to add it back again. As you can see, you can also add a UI Testing Bundle in the same way.
A few other ideas
- Make sure that all required classes are members of your test target.
- Make sure that you have added all the required libraries.
- Make sure that the module name is written correctly (see this answer).
Or...
Leave a comment or answer below if you found something else that worked.
Related
- How to do a Unit Test in Xcode
- Xcode UI Test example
How to let unit test to access app's target classes in swift
Just add @testable
before import in you Unit tests. Then you will have access to everything like you would in Objective-C.
Like this
@testable import MyModule
You can check out this tutorial on how to test in Swift 2 https://www.natashatherobot.com/swift-2-xcode-7-unit-testing-access/
Swift 3 Unit Testing - Linker fails when using import @testable
If your CocoaPods frameworks not included in the Test targets. It will throw this error.
I made sure running a pod install, but still it failed.
So 'pod deintegrate Yourproject.xcodeproj' and reinstall (pod install), clears the issue.
What's the difference between importing a target into unit testing and including that file among the target Membership?
From the Swift docs under the heading Access Levels for Unit Test Targets (emphasis added)
When you write an app with a unit test target, the code in your app needs to be made available to that module in order to be tested. By default, only entities marked as open or public are accessible to other modules. However, a unit test target can access any internal entity, if you mark the import declaration for a product module with the @testable attribute and compile that product module with testing enabled.
These docs say that the @testable attribute provides your Unit Test target access to all internals of the module marked as @testable. Thus letting you avoid having to manually add individual files in that module to the Unit Test target.
The @testable import is typically done on large codebases that did not
have any tests yet... because this approach is significantly slower
than adding the files you want to test to the test target.
Unit test class for Swift project
You should add the swift file you are testing to the testing target.
This can be done by clicking on the swift file, going to the Utilities panel (the one on the right) and checking the checkbox under "Target membership".
No need to change the access modifier to public, internal will do.
UPDATE
As of XCode 7 there is no need to make any file member of the testing target any more.
The recommended way is to use@testable import {Product Module Name}
. Just make sure to use the product module's and not the projects' folder name.
Adding Swift Unit Tests to a Mixed Language Xcode Project
Answer provided by https://twitter.com/UINT_MIN
In my case the both targets (the application and the tests) had the same module name in the build settings. Changing the module name of the test target resolved the issue.
Cannot load underlying module for XCTest
The main project does not link with the XCUnit framework. You should create a separate testing target for your project, if one does not already exist, and add your test source files to that target.
- Select your project in the Project Navigator. This will open the project's settings in the editor.
- Click the "+" button at the bottom of the column listing your Targets.
If you are working on an iOS project template, select
iOS > Test > iOS Unit Testing Bundle
.If you are working on an OS X project template, select
OS X > Test > OS X Unit Testing Bundle
.
Related Topics
How to Find the Kind of Errors a Method May Throw and Catch Them in Swift
Flutter: Disable Swipe to Navigate Back in iOS and Android
How to Ensure to Run Some Code on Same Background Thread
Share Datas Between Two Apps with iOS 8 App Groups (Using Nsuserdefaults)
Uipickerview as Inputview of Uitextfield
Generate Rsa Public Key from Modulus and Exponent
Cannot Invoke Initializer for Type 'Double' with an Argument List of Type '(String)'
How to Properly Structure Firebase Database to Allow Easy Reading and Removal
Simplest Algorithm of Measuring How Similar of Two Short Audio
Fairplay Streaming: Calling Copypixelbufferforitemtime on Avplayeritemvideooutput Returns Null
Firestore Paginating Data + Snapshot Listener
How to Draw on an Image in Swift
How to Use Multiple Segues with One Uitableviewdelegate
Cannot Show Modal Viewcontroller in iOS7
How to Remove All References for Outlet
React-Native Loading Image Over Https Works While Http Does Not Work
Arkit Session Paused and Not Resuming
Avassetwriter Avvideoexpectedsourceframeratekey (Frame Rate) Ignored