Reputation: 19858
I have recently converted my app, and unit tests over to Swift 2.0. I am using @testable import AppName
in my Tests.swift files.
Due to an issue with not being able to execute subclasses in multiple targets (see here for the issue), my class EntityName
can only be of Target Membership AppName
, and NOT AppNameTests
.
The problem is, once I switch over to the AppNameTests
schema to run unit tests, code in the module AppName
can't find the class EntityName
and I get
Use of undeclared type 'EntityName'
How do I get AppName
to compile when running tests from the AppNameTests
scheme without that entity class not a member of the scheme?
Upvotes: 19
Views: 13876
Reputation: 783
I had similar problem and the issue was that all of the application source files were linked to the unit test target, and so compiled twice!
Also, I installed Realm via Carthage and had to include both targets (main and test) for the frameworks "Realm.framework" and "RealmSwift.framework" because it wouldn't work otherwise.
Here is the issue link
https://github.com/realm/realm-cocoa/issues/3627
Upvotes: 0
Reputation: 1
First ensure that @testable import MyApp
is included in every test file. Then, in your Test Target Build Phases, remove all non-test files the Copy Bundle Resources sections. App files that are in your test target that point to app files that are not in your test target are breaking your unit tests. Remove all app files from your test target and add the @testable
flag and everything should work!
Upvotes: 0
Reputation: 6290
I also got this error recently and none of the above steps fixed the problem, what did fix it was removing non-swift file from the Compile sources build phase in the Target you want to run tests on. This was failing silently
Upvotes: 0
Reputation: 19858
I had to stop targeting my entire apps .swift files to be have membership of MyAppTests, and rely solely on @testable import MyApp
Upvotes: 10
Reputation: 14409
Due to an issue with not being able to execute subclasses in multiple targets
When compiling the same Swift code as part of different targets, the compiler actually generates different classes. So this behaves as designed, but is almost certainly not what you want when running an app's unit tests.
There are two ways I'd recommend you set up your models to allow testing:
In your app target:
import RealmSwift
public class MyModel: Object {}
This code should only be compiled as part of your application target, and your unit tests can be set up in the following way:
import MyApp
// should be able to access `MyModel`
Easy enough?
This approach relies on the @testable
keyword introduced in Swift 2.
In your app target:
import RealmSwift
internal class MyModel: Object {} // ACL cannot be `private`
Again, this code should only be compiled as part of your application target, and your unit tests can be set up in the following way:
@testable import MyApp
// should be able to access `MyModel`
Make sure MyApp's build settings have Enable Testability
set to YES
.
This approach may be preferred to public models if you're building a framework where some internal models shouldn't be accessible from users of that framework.
Realm has a dedicated section of their documentation detailing these common approaches to testing which you can read here: https://realm.io/docs/swift/latest/#avoid-linking-realm-and-tested-code-in-test-targets
Upvotes: 20