unit tests executing App's init() function?

I am adding unit tests to an existing SwiftUI project, and I've discovered the main 'App' struct's init() function is being called automatically before the individual test functions are run.

(1) Is this expected behavior?

(2) Is there a way to disable the App struct's init() from being called when running unit tests?

In my use case, the App struct's init() does some initialization, including network activity, that I would prefer not happen during unit tests.

Below is simplified version of what I am seeing beginning with the App struct:

import SwiftUI
import os.log

@main
struct MyTest2App: App {
    
    init() {
        os_log("===== In MyTest2App.init() =====")
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Here is an example of a struct that I want to exercise in a unit test:

import Foundation

struct Foo {
    var name: String
    var count: Int
    
    init(name: String, count: Int) {
        self.name = name
        self.count = count + 1
    }
}

Here is a unit test file:

import XCTest

final class MyTest2Tests: XCTestCase {

    override func setUpWithError() throws {
    }

    override func tearDownWithError() throws {
    }

    func testExample() throws {
        let foo = Foo(name: "Apple", count: 3)
        XCTAssertEqual(foo.count, 4)
    }
}

Here is part of the output console. The first line is the output from the App struct's init() function:

2023-09-27 10:41:26.798791-0700 MyTest2[66138:9429362] ===== In MyTest2App.init() =====
2023-09-27 10:41:26.869966-0700 MyTest2[66138:9429362] ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/yg/vfstql350kqgzp17lmh11jg80000gn/T/com.ennetix.MyTest2/com.ennetix.MyTest2.savedState
...
Answered by DTS Engineer in 766554022

(1) Is this expected behavior?

Yes. By default your unit test bundle is loaded into your app, and for that to happen the app must be initialised.

(2) Is there a way to disable the App struct's init() from being called when running unit tests?

You can change your unit test to not target your app. [Hmmm, I not entirely sure how to do that in this brave new world of test plans but it doesn’t really matter because I think the next option is better.]

A better option is to add arguments to your test plan, read those arguments in init(), and then customise your init() behaviour based on that. For example, I added the arguments -QQQ_TEST and YES to the test plan, and then added this code to init():

print("is testing:", UserDefaults.standard.bool(forKey: "QQQ_TEST"))

It prints true when testing and false when running.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

(1) Is this expected behavior?

Yes. By default your unit test bundle is loaded into your app, and for that to happen the app must be initialised.

(2) Is there a way to disable the App struct's init() from being called when running unit tests?

You can change your unit test to not target your app. [Hmmm, I not entirely sure how to do that in this brave new world of test plans but it doesn’t really matter because I think the next option is better.]

A better option is to add arguments to your test plan, read those arguments in init(), and then customise your init() behaviour based on that. For example, I added the arguments -QQQ_TEST and YES to the test plan, and then added this code to init():

print("is testing:", UserDefaults.standard.bool(forKey: "QQQ_TEST"))

It prints true when testing and false when running.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

unit tests executing App's init() function?
 
 
Q