I would like to have "access" to the reported measurements in XCTApplicationLaunchMetric
. To this effect, I created my own class that adopts XCTMetric
and uses, calls XCTApplicationLaunchMetric
under the hood like this:
class MyXCTApplicationLaunchMetric: NSObject, XCTMetric {
let myLaunchMetric: XCTApplicationLaunchMetric
init(waitUntilResponsive: Bool) {
print(#function)
myLaunchMetric = XCTApplicationLaunchMetric(waitUntilResponsive: waitUntilResponsive)
}
// XCTMetric conformance
func willBeginMeasuring() {
print(#function)
myLaunchMetric.willBeginMeasuring()
}
// XCTMetric conformance
func didStopMeasuring() {
print(#function)
myLaunchMetric.didStopMeasuring()
}
// XCTMetric conformance
func reportMeasurements(from startTime: XCTPerformanceMeasurementTimestamp, to endTime: XCTPerformanceMeasurementTimestamp) throws -> [XCTPerformanceMeasurement] {
let measurement = Measurement(value: 40, unit: .init(symbol: "M"))
let performanceMeasurement = XCTPerformanceMeasurement(identifier: "SomeIdentifier", displayName: "SomeDisplayName", value: measurement)
return [performanceMeasurement]
}
// NSObject conformance
func copy(with zone: NSZone? = nil) -> Any {
myLaunchMetric.copy(with: zone)
}
}
However, when I use it here, none of the XCTMetric
functions are called. The init
is called. I am not sure why.
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
let launchMetric = MyXCTApplicationLaunchMetric(waitUntilResponsive: true)
measure(metrics: [launchMetric],
options: options) {
XCUIApplication().launch()
}
}
}
}
The reason is because measure
calls copy(with:)
and you are not returning an instance of your custom type but myLaunchMetric
which is an instance of XCTApplicationLaunchMetric
.