Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Xcode PreviewsからSnapshotテストを自動生成する

kenmaz
December 18, 2020

Xcode PreviewsからSnapshotテストを自動生成する

2020/12/18に開催された「merpay Tech Talk ~for iOS Engineers~」というイベントでのスライドです。

https://mercari.connpass.com/event/197804/?utm_campaign=event_message_to_selected_participant&utm_source=notifications&utm_medium=email&utm_content=title_link

本発表の内容の詳細については下記のブログ記事を参照してください。
https://engineering.mercari.com/blog/entry/20201204-1f94b9dca2/

kenmaz

December 18, 2020
Tweet

More Decks by kenmaz

Other Decks in Programming

Transcript

  1. final class ConfirmationStateView: UIView, .. { struct Input { let

    screenName: String } private lazy var screenNameLabel: UILabel = { let label = UILabel(...) .... return label }() func apply(input: Input) { screenNameLabel.text = input.screenName ... } 7JFXίʔυ 6*7JFX
  2. struct Wrapper: UIViewRepresentable { let input: ConfirmationStateView.Input init(input: ConfirmationStateView.Input) {

    self.input = input } func makeUIView(...) -> ConfirmationStateView { let view = ConfirmationStateView() view.apply(input: input) return view } func updateUIView(...) { } } 7JFXίʔυΛ4XJGU6*ͷ7JFXͱͯ͠ϥοϓ
  3. struct ConfirmationStateViewPreview: PreviewProvider { static var previews: some View {

    Group { Wrapper( input: .init(screenName: "୹໊͍લ") ) Wrapper( input: .init(screenName: "গ͠௕໊͍લগ͠௕໊͍લ") ) Wrapper( input: .init(screenName: "௕໊͍લ௕໊͍લ௕໊͍લ௕໊͍લ௕໊͍લ") ) 1SFWJFXίʔυ 1SFWJFX1SPWJEFS
  4. import XCTest import SnapshotTesting class ConfirmationStateViewTests: XCTestCase { func testShortName()

    { let view = ConfirmationStateView() let input = ConfirmationStateView.Input( screenName: "୹໊͍લ" ) view.apply(input: input) assertSnapshot(matching: view, as: .image) } func testMiddleName() { ... screenName: "গ͠௕໊͍લগ͠௕໊͍લ" ... assertSnapshot(matching: view, as: .image) } func testLongName() { ... screenName: "௕໊͍લ௕໊͍લ௕໊͍લ௕໊͍લ௕໊͍લ" ... assertSnapshot(matching: view, as: .image) } 4OBQTIPUςετίʔυ 7JFXΛΩϟϓνϟͯ͠ ࢀরը૾ϑΝΠϧͱͯ͠ อଘ ൺֱ ࢀরը૾
  5. import XCTest import SnapshotTesting class ConfirmationStateViewTests: XCTestCase { func testShortName()

    { let view = ConfirmationStateView() let input = ConfirmationStateView.Input( screenName: "୹໊͍લ" ) view.apply(input: input) assertSnapshot(matching: view, as: .image) } func testMiddleName() { ... screenName: "গ͠௕໊͍લগ͠௕໊͍લ" ... assertSnapshot(matching: view, as: .image) } func testLongName() { ... screenName: "௕໊͍લ௕໊͍લ௕໊͍લ௕໊͍લ௕໊͍લ" ... assertSnapshot(matching: view, as: .image) } 1SFWJFXίʔυ 4OBQTIPUςετίʔυ ಉ͡Α͏ͳ͜ͱΛ΍͍ͬͯΔ
  6. 1SFWJFXίʔυʹର͢Δ4OBQTIPUςετ class PreviewSnapshotTests: XCTestCase { func testConfirmationStateViewPreview() { for preview

    in ConfirmationStateViewPreview._allPreviews { assertSnapshot(matching: preview.content, as: .image) } } } FYUFOTJPO@1SFWJFX1SPWJEFS\ QVCMJDTUBUJDWBS@BMM1SFWJFXT<4XJGU6*@1SFWJFX>\HFU^ QVCMJDTUSVDU@1SFWJFX\ QVCMJDWBSDPOUFOU4XJGU6*"OZ7JFX\HFU^ 1SFWJFXίʔυதʹఆٛ͞ΕͨશͯͷϓϨϏϡʔ ֤ϓϨϏϡʔͷදࣔ಺༰Λࣔ͢4XJGU6*ͷ7JFX
  7. class PreviewSnapshotTests: XCTestCase { func testConfirmationStateViewPreview() { for preview in

    ConfirmationStateViewPreview._allPreviews { assertSnapshot(matching: preview.content, as: .image) } } }
  8. 4PVSDFSZʹΑΔ4OBQTIPUςετίʔυͷࣗಈੜ੒ class PreviewSnapshotTests: XCTestCase { {% for type in types.based.PreviewProvider

    %} func test{{type.name}}() { for preview in T._allPreviews { assertSnapshot(matching: preview.content, as: .image) } } {% endfor %} } TUFODJMςϯϓϨʔτ IUUQTHJUIVCDPNLS[ZT[UPG[BCMPDLJ4PVSDFSZ UZQFTCBTFE1SFWJFX1SPWJEFS 1SFWJFX1SPWJEFSϓϩτίϧʹద߹ͨ͠શͯͷܕΛऔಘ