Unrecognized selector in XCTest test

70 Views Asked by At

In this code

class MyXCTApplicationLaunchMetric: NSObject, XCTMetric {
    let myLaunchMetric: XCTApplicationLaunchMetric

    override init() {
        myLaunchMetric = XCTApplicationLaunchMetric(waitUntilResponsive: true)
        super.init()
    }

    // XCTMetric conformance
    func willBeginMeasuring() {
        myLaunchMetric.willBeginMeasuring()
    }

    // XCTMetric conformance
    func didStopMeasuring() {
        myLaunchMetric.didStopMeasuring()
    }

    // XCTMetric conformance
    func reportMeasurements(from startTime: XCTPerformanceMeasurementTimestamp, to endTime: XCTPerformanceMeasurementTimestamp) throws -> [XCTPerformanceMeasurement] {
        try myLaunchMetric.reportMeasurements(from: startTime, to: endTime)
    }

    // NSObject conformance
    func copy(with zone: NSZone? = nil) -> Any {
        self
    // have also tried returning MyXCTApplicationLaunchMetric()
    // and MyXCTApplicationLaunchMetric(myLaunchMetric) when provided    
    // an init that accepts that param. 
    }
}

When is called in

final class PerformanceUITests: XCTestCase {
    func testLaunchPerformance() throws {
        if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
            let options = XCTMeasureOptions()
            options.iterationCount = 1

            measure(metrics: [MyXCTApplicationLaunchMetric()],
                    options: options) {
                XCUIApplication().launch()
            }
        }
    }
}

It crashes on line myLaunchMetric.willBeginMeasuring() with

Thread 2: "-[XCTApplicationLaunchMetric willBeginMeasuring]: unrecognized selector sent to instance 0x60000026c620"


I found that the selector error is typically caused because the instance does not have willBeginMeasuring() method. I also found that MyXCTApplicationLaunchMetric's init is called once and then the copy(with:), which is not clear why it would need a copy.

0

There are 0 best solutions below