41

I've got a stock standard class call GeoRssParserDelegate which needs to be tested.

In my swift unit test I've got this:

func testParser()
{
    var bundle = NSBundle(forClass:GeoRssParserTest.classForKeyedArchiver())
    var path = bundle.pathForResource("test", ofType: "xml")
    let data = NSData.dataWithContentsOfFile(path, options: NSDataReadingOptions.DataReadingMapped, error: nil)
    let xmlParser = NSXMLParser(data:data)
    let delegate = GeoRssParserDelegate() <-- Compiler fails here
    var bStatus = xmlParser.parse()
    XCTAssertTrue(bStatus, "Parse failed", file: __FILE__, line: __LINE__)        
}

The compiler fails on the line highlighted above. The compiler error is Use of unresolved idenitifier GeorRssParserDelegate

This class does exist and builds with the product itself. Is anything special required?

dertkw
  • 7,798
  • 5
  • 37
  • 45
Lee
  • 3,996
  • 3
  • 33
  • 37
  • 3
    Maybe silly question: But are you sure it’s a class and not a protocol? Either way you probably need to post more of your code. – nschum Jun 13 '14 at 20:57

8 Answers8

59

You have to import your application's module into your unit test. This is usually your app name. For example, if your app name is GeoRssParser the import statement would be:

import GeoRssParser
Andriy
  • 2,767
  • 2
  • 21
  • 29
James Richard
  • 1,525
  • 12
  • 18
  • 1
    I want to give this answer 1000 up votes. THANK YOU. – Bill Jun 18 '14 at 02:31
  • 11
    Not sure if it's always the case, but this only worked for me when i prefixed the import statement with `@testable` – Chris Oct 07 '17 at 18:37
44

Solution for Xcode 8 and UP which works for me:

@testable import Product_Module_Name

note: not the target name but product's name.

Regarding answers above: making without @testable will require to make classes and methods public which changes the design of the app architecture. if you don't want to change it better to use this solution so you won't need to make changes to class being public or no.

Many thanks to this answer

Tung Fam
  • 7,899
  • 4
  • 56
  • 63
19

If the class you're testing is compiled into another target (such as your application, as opposed to the test bundle), make sure that the class or struct you're trying to use is marked public -- the default access visibility doesn't allow for cross-target testing.

Sophie Alpert
  • 139,698
  • 36
  • 220
  • 238
  • IMHO this should be the right answer in addition to James´s answer. Marking the tested Class or struct as public is necessary. Otherwise the Test-target will not find it. And for sure it has to be imported... – Tomte Feb 06 '15 at 07:15
  • 1
    In Xcode 6.3 beta 3, I not only had to mark each class to be tested as public, but each and every constituent class or instance function tested as well. Cumbersome. – ctpenrose Mar 24 '15 at 23:33
  • 4
    This is no longer the case as you can use @testable in Swift 2.0 – James Richard Aug 21 '15 at 04:22
15

If you're using brand new XCode 7 (as of Jul 21, 2015), simply write: @testable import GeoRssParserDelegate

Source: http://natashatherobot.com/swift-2-xcode-7-unit-testing-access/

Lukasz Czerwinski
  • 13,499
  • 10
  • 55
  • 65
11
@testable import MyApp

IMPORTANT! Note: MyApp must be the product module name in your project (Settings -> Target -> Build Setting -> Product Module Name)

atereshkov
  • 4,311
  • 1
  • 38
  • 49
2

Just add the class you are testing to Target -> Build Phases -> Compile Sources

It's how I fixed my problem.

Scott Zhu
  • 8,341
  • 6
  • 31
  • 38
  • 4
    this solution works well but it's not a good design for the app to include the classes of app target to tests target – Tung Fam Jan 13 '17 at 08:57
  • `@testable import` is the way to go, adding files to test target was how we used to do in Objective-C, but not swift. – Carlos Ricardo Jul 14 '17 at 12:16
0

Do the following 3 steps --> 1. Write @testable import Your_Project_name 2. Then save (CTRL+S) 3. Then build (CTRL+B)

tania_S
  • 1,350
  • 14
  • 23
0

For me the reference or value type that I wanted to test is not marked as public. That's why I've just used as copy-paste for the associated type.

alitosuner
  • 984
  • 1
  • 10
  • 15