iOS UIコンポーネントのスナップショットテストを行うためのフレームワークであるiOSSnapshotTestCaseを活用して、より高度なカスタマイズを行い、プロジェクト固有のニーズに対応するテスト環境を構築する方法について解説します。
なぜカスタム拡張が必要なのか?
標準的な機能だけでは対応できないケースが多いため、以下のような理由でカスタム拡張が必要です:- 特殊なUIコンポーネントのテスト
- 特定のレンダリングモードへの対応
- 既存のテストフレームワークとの統合
- 追加の検証ロジックの導入
プロジェクト構造と主要コンポーネント
カスタム拡張を開発する前に、基本的なファイル構造を理解することが重要です。- FBImageTestController.h/m: イメージ比較処理を管理 - FBViewSnapshot.h/m: スナップショット生成の基盤 - Extensionsディレクトリ: UIImageに対する拡張機能群
UIImageカテゴリのカスタマイズ例
独自のフィルタリング処理を追加する場合、以下のコードを使用できます。// UIImage+CustomFilter.h @interface UIImage (CustomFilter) + (UIImage *)applyCustomBlurEffect:(UIImage *)img blurRadius:(CGFloat)radius; @end
FBSnapshotTestControllerの拡張
画像比較アルゴリズムやその他の検証ステップをカスタマイズすることで、より柔軟なテストが可能になります。// CustomTestController.h @interface CustomTestController : FBSnapshotTestController @property (nonatomic, assign) CGFloat maxRenderDuration; - (BOOL)customValidateWithTolerance:(CGFloat)tolerance error:(NSError **)error; @end
デバイス非依存のスナップショットテスト
異なる解像度を持つデバイスでのテストをサポートするために、次のように拡張できます。// MultiResolutionSnapshot.h @interface MultiResolutionSnapshot : FBSnapshotTestCase @property (nonatomic, strong) NSArray<NSString *> *deviceTypes; - (void)testViewOnAllDevices:(UIView *)view id:(NSString *)identifier; @end
CI/CDへの統合
自動化されたテストプロセスに組み込むために、以下のクラスを作成します。// CIIntegrationTest.h @interface CIIntegrationTest : FBSnapshotTestCase @property (nonatomic, assign) BOOL isCIMode; - (void)uploadToCI:(UIImage *)snap testName:(NSString *)name identifier:(NSString *)id; @end
実践例
アニメーション状態のテスト
- (void)testAnimationState {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
FBSnapshotVerifyView(btn, @"initial_state");
[btn setHighlighted:YES];
FBSnapshotVerifyView(btn, @"highlighted_state");
}
テーマ変更テスト
- (void)testThemeChange {
UIView *v = [[UIView alloc] initWithFrame:CGRectZero];
[ThemeManager applyLightTheme];
FBSnapshotVerifyView(v, @"light_theme");
[ThemeManager applyDarkTheme];
FBSnapshotVerifyView(v, @"dark_theme");
}