Adding Swift Files to Test Target Not Fixing Unit Tests

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:

test target bridging header

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..."

Sample Image

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).

Sample Image

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.

Sample Image

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".

add testing target to swift file

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.

  1. Select your project in the Project Navigator. This will open the project's settings in the editor.
  2. Click the "+" button at the bottom of the column listing your Targets.

Sample Image


  1. 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



Leave a reply



Submit