IOS Why Unit Test a class calls ViewController

Viewed 911

I wrote a unit test like below:

class Test445Tests: XCTestCase {
    func testPerformanceExample() {
        XCTAssert(true)
    }
}

When the test runs, something calls ViewController.viewDidLoad! Can someone explain why this happens?

class ViewController: UIViewController {

    static var s = false

    override func viewDidLoad() {
        super.viewDidLoad()
        ViewController.s = true // put the debugger here.
    }


}

If you write this code and put a debugger on ViewController, you can check that the debugger will stop on that line.

1 Answers

It's creating an instance of ViewController because your app creates a ViewController at launch, and your test bundle uses your app as its “Host Application”:

host application setting

When the setting is configured like shown above, it means Xcode runs the tests in your test bundle by launching the host application, then injecting the test bundle into it.

You can change the “Host Application” setting to “None”:

host application set to none

When the setting is configured as “None”, Xcode runs your test bundle using a non-GUI app called the XCTest agent, and doesn't launch your app, so your app doesn't get the chance to create a ViewController.

Note that when you set “Host Application” to “None”, your test bundle can no longer access any APIs defined in the application. Any APIs you want to test, you have to move into a framework, and link the test bundle with that framework (in the “Build Phases” tab for the test bundle).

Note also that even when you set “Host Application” to “None”, Xcode still launches a simulator. Your test cases are allowed to use iOS system services that are only available when a simulator is running, and Xcode doesn't know in advance whether your test cases need those services. So it has to launch the simulator first, just in case.

Related