概要
Xcode 27 への移行(#48 )で CI を xcode-27 ランナーに移したところ、TortoiseUITests のプロセスが PNG ゴールデンの比較中にクラッシュしました。
#48 では、比較方法から perceptualPrecision を外してバイト単位の比較に切り替え、クラッシュを回避しています。ただ、再現した環境は macOS 27 も Xcode 27 もベータ版 でした。そのため、これが Apple 側のベータ版の不具合なのか、swift-snapshot-testing 側の問題なのかはまだ分かっていません。
この issue では、Xcode 27 / macOS 27 の正式版で再発するかを確認し、それに応じて回避策を外すか、上流に報告するかを決めます。
発生した環境
ローカル(macOS 26 + Xcode 27 RC)では再現しません。
症状
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[NSConcreteValue CGRectValue]: unrecognized selector sent to instance 0x75493f4000'
*** First throw call stack:
5 CoreImage -[CIReductionFilter offsetAndCrop] + 56
6 CoreImage -[CIAreaAverage outputImage] + 56
7 CoreImage -[CIImage imageByApplyingFilter:withInputParameters:] + 300
8 TortoiseUITests (extension in SnapshotTesting):CIImage.applyingAreaAverage()
9 TortoiseUITests SnapshotTesting.perceptuallyCompare(_:_:pixelPrecision:perceptualPrecision:)
10 TortoiseUITests SnapshotTesting.compare(_:_:precision:perceptualPrecision:) (NSImage)
テストが 1 件失敗するのではなく、テストプロセス全体が signal 6 で落ちます。
分かっていること
例外が起きている場所
swift-snapshot-testing の Sources/SnapshotTesting/Snapshotting/UIImage.swift で、CIAreaAverage の inputExtent に CGRect をそのまま渡しています。
func applyingAreaAverage( ) -> CIImage {
applyingFilter ( " CIAreaAverage " , parameters: [ kCIInputExtentKey: extent] )
}
CGRect は NSValue に変換されて渡ります。macOS 27 の Core Image はそれに CGRectValue を送りますが、macOS の NSValue には CGRectValue がありません(rectValue はある)。そのため例外になります。macOS 26 まではこの渡し方でも動いていました。
CIAreaAverage の inputExtent は、仕様上 CIVector を受け取るパラメータです。
macOS 26 で気づかなかった理由
compare はまずバイト列を比較し、一致しなかったときだけ perceptuallyCompare に進みます。ゴールデンを記録した macOS 26 では、描画結果がバイト単位で完全に一致するので、この処理まで進みません。macOS 27 では描画がわずかにずれるので、ここに進んで落ちます。
Tests/TortoiseUITests/CanvasGoldenSnapshotting.swift で .canvasGolden = .image(precision: 0.995) を定義し、Canvas の PNG ゴールデンはすべてこれで比較するようにしました。perceptualPrecision を指定しなければ、上流はバイト単位の比較だけを使うので、この処理を通りません。macOS 27 でのずれは許容誤差(バイトの 0.5%)に収まり、CI は通っています。
上流の状況(2026-09-14 時点)
同じクラッシュの issue や PR はありません。
pointfreeco/swift-snapshot-testing#673 :Xcode 27 と iOS 27 シミュレータで知覚差分の比較を使った報告があり、クラッシュせず 最後まで動いています。今回の問題は macOS 27 の Core Image に限ったもののようです。その報告者も回避策に perceptualPrecision: 1 を選んでいます。
PR #1119 と #1109 は知覚差分の比較まわりを変更しますが、kCIInputExtentKey の渡し方は変えていません。
検証すること
xcode-27 ランナーが macOS 27 と Xcode 27 の正式版になったら、次を確認します。
ランナーの OS と Xcode のビルド番号が正式版になっていることを確認する(ジョブログの「Operating System」と「Select Xcode」)。
ブランチで .canvasGolden を .image(precision: 0.995, perceptualPrecision: 0.98) に戻し、CI の Build & Test を回す。
クラッシュしない → 正式版で直った。回避策を残すか戻すかを決める(戻さなくても CI は通る)。
同じ例外で落ちる → 次の 3 に進む。
swift-snapshot-testing に issue を立てる。修正案は applyingAreaAverage() / applyingAreaMaximum() で CIVector(cgRect: extent) を渡すこと。
未確認のこと
修正案(CIVector(cgRect:) を渡す)で本当に直るかは、macOS 27 で動かしていないので確認できていません。
CIAreaMaximum(applyingAreaMaximum())も同じ渡し方をしているので同じく落ちる可能性がありますが、今回のスタックトレースに出たのは CIAreaAverage だけです。
概要
Xcode 27 への移行(#48)で CI を
xcode-27ランナーに移したところ、TortoiseUITestsのプロセスが PNG ゴールデンの比較中にクラッシュしました。#48 では、比較方法から
perceptualPrecisionを外してバイト単位の比較に切り替え、クラッシュを回避しています。ただ、再現した環境は macOS 27 も Xcode 27 もベータ版 でした。そのため、これが Apple 側のベータ版の不具合なのか、swift-snapshot-testing 側の問題なのかはまだ分かっていません。この issue では、Xcode 27 / macOS 27 の正式版で再発するかを確認し、それに応じて回避策を外すか、上流に報告するかを決めます。
発生した環境
xcode-27-arm6420260907.0173.1Xcode_27.0.0.app経由で選択)ローカル(macOS 26 + Xcode 27 RC)では再現しません。
症状
テストが 1 件失敗するのではなく、テストプロセス全体が signal 6 で落ちます。
分かっていること
例外が起きている場所
swift-snapshot-testing の
Sources/SnapshotTesting/Snapshotting/UIImage.swiftで、CIAreaAverageのinputExtentにCGRectをそのまま渡しています。CGRectはNSValueに変換されて渡ります。macOS 27 の Core Image はそれにCGRectValueを送りますが、macOS のNSValueにはCGRectValueがありません(rectValueはある)。そのため例外になります。macOS 26 まではこの渡し方でも動いていました。CIAreaAverageのinputExtentは、仕様上CIVectorを受け取るパラメータです。macOS 26 で気づかなかった理由
compareはまずバイト列を比較し、一致しなかったときだけperceptuallyCompareに進みます。ゴールデンを記録した macOS 26 では、描画結果がバイト単位で完全に一致するので、この処理まで進みません。macOS 27 では描画がわずかにずれるので、ここに進んで落ちます。回避策(#48)
Tests/TortoiseUITests/CanvasGoldenSnapshotting.swiftで.canvasGolden = .image(precision: 0.995)を定義し、Canvas の PNG ゴールデンはすべてこれで比較するようにしました。perceptualPrecisionを指定しなければ、上流はバイト単位の比較だけを使うので、この処理を通りません。macOS 27 でのずれは許容誤差(バイトの 0.5%)に収まり、CI は通っています。上流の状況(2026-09-14 時点)
perceptualPrecision: 1を選んでいます。kCIInputExtentKeyの渡し方は変えていません。検証すること
xcode-27ランナーが macOS 27 と Xcode 27 の正式版になったら、次を確認します。.canvasGoldenを.image(precision: 0.995, perceptualPrecision: 0.98)に戻し、CI の Build & Test を回す。applyingAreaAverage()/applyingAreaMaximum()でCIVector(cgRect: extent)を渡すこと。未確認のこと
CIVector(cgRect:)を渡す)で本当に直るかは、macOS 27 で動かしていないので確認できていません。CIAreaMaximum(applyingAreaMaximum())も同じ渡し方をしているので同じく落ちる可能性がありますが、今回のスタックトレースに出たのはCIAreaAverageだけです。