$30 off During Our Annual Pro Sale. View Details »

LT: KaucheMockKit 導入した話

LT: KaucheMockKit 導入した話

Akifumi Fukaya

August 10, 2022
Tweet

More Decks by Akifumi Fukaya

Other Decks in Programming

Transcript

  1. © KAUCHE, Inc. LT: KaucheMockKit 導入した話

  2. © KAUCHE, Inc. 自己紹介 • 名前 ◦ 深谷 哲史 (ふかや

    あきふみ) • 会社 ◦ 株式会社カウシェ (2020/07 ~ 現在) • 役職 ◦ 取締役CPO • アカウント ◦ Twitter: @akifumifukaya ◦ Facebook: Akifumi Fukaya ◦ GitHub: akifumi
  3. © KAUCHE, Inc.

  4. © KAUCHE, Inc. アジェンダ • Multi Modules 導入状況 • Motivation

    • About KaucheMockKit • Dependency • Summary
  5. © KAUCHE, Inc. Multi Modules 導入状況

  6. © KAUCHE, Inc. Multi Modules 導入状況

  7. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit • KaucheAPIKit

    • KaucheShopifyKit • KaucheMockKit • KaucheDesignKit • Kauche
  8. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit ◦ 全モジュール/全レイヤーから参照され、基

    盤となるFramework ◦ 全モジュールの共通言語となるインターフ ェースやツールを搭載している ◦ インターフェース ▪ Models ▪ Protocols ◦ ツール ▪ Extensions ▪ Utilities • KaucheAPIKit • KaucheShopifyKit • KaucheMockKit • KaucheDesignKit • Kauche
  9. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit • KaucheAPIKit

    ◦ API通信を行うFramework ◦ カウシェサーバーとの通信を担っている ◦ 通信プロトコルの隠蔽 ◦ KaucheCoreKit.Models にマッピングし、 値を返す • KaucheShopifyKit • KaucheMockKit • KaucheDesignKit • Kauche
  10. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit • KaucheAPIKit

    • KaucheShopifyKit ◦ EC構築ツールShopifyとの通信を行う Framework ◦ Shopifyとの通信を隠蔽 ◦ KaucheCoreKit.Models にマッピングし、 値を返す • KaucheMockKit • KaucheDesignKit • Kauche
  11. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit • KaucheAPIKit

    • KaucheShopifyKit • KaucheMockKit ◦ カウシェのモックデータを定義する Framework ◦ Previews, Unit Tests などで使用 • KaucheDesignKit • Kauche
  12. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit • KaucheAPIKit

    • KaucheShopifyKit • KaucheMockKit • KaucheDesignKit ◦ カウシェのデザインコンポーネントを保持 ◦ Colors, Styles, UI Components を有する • Kauche
  13. © KAUCHE, Inc. Multi Modules 導入状況 • KaucheCoreKit • KaucheAPIKit

    • KaucheShopifyKit • KaucheDesignKit • KaucheMockKit • Kauche ◦ カウシェのアプリケーション ◦ 現在は、全Featureのコードが置いてある ◦ 将来的には、各Featureごとにモジュールを 分割し、 Kauche モジュールはアプリケー ションのみにできるように薄くしていきた い ◦ そうすることで、よりチーム開発がしやす い状態を目指す
  14. © KAUCHE, Inc. Motivation

  15. © KAUCHE, Inc. Motivation • Unit Tests / Xcode Previews

    で使用するモックデータの定義が重複していた • モックデータは開発用途であり、Production コードからは除外したい • 上記の課題から、モックデータの定義を切り出し KaucheMockKit としてまとめることに
  16. © KAUCHE, Inc. About KaucheMockKit

  17. © KAUCHE, Inc. About KaucheMockKit • 以下の役割を担っているFramework ◦ モックデータの格納 ◦

    モック用のインタフェース定義 • 対応しているModule ◦ KaucheCoreKit ◦ KaucheAPIKit
  18. © KAUCHE, Inc. Group.swift in KaucheCoreKit public struct Group {

    public let id: String public let ownerUserId: String public let productId: String public let groupRequirement: GroupRequirement public let expireDate: Date public let status: GroupStatus public let currentCompletedPurchaseCount: UInt32 public let productHandle: String public let url: String public let message: String public init(id: String, ownerUserId: String, productId: String, groupRequirement: GroupRequirement, expireDate: Date, status: GroupStatus, currentCompletedPurchaseCount: UInt32, productHandle: String, url: String, message: String) { self.id = id self.ownerUserId = ownerUserId self.productId = productId self.groupRequirement = groupRequirement self.expireDate = expireDate self.status = status self.currentCompletedPurchaseCount = currentCompletedPurchaseCount self.productHandle = productHandle self.url = url self.message = message } }
  19. © KAUCHE, Inc. Group+Extension.swift in KaucheMockKit (Mockable) import KaucheCoreKit public

    extension Group { static func mock( id: String = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ownerUserId: String = "user_id", productId: String = "1234567890", groupRequirement: GroupRequirement = .mock(), expireDate: Date = Date(), status: GroupStatus = .unspecified, currentCompletedPurchaseCount: UInt32 = 0, productHandle: String = "product_1", url: String = "https://kauche.dev/groups/group_id", message: String = "" ) -> Group { .init(id: id, ownerUserId: ownerUserId, productId: productId, groupRequirement: groupRequirement, expireDate: expireDate, status: status, currentCompletedPurchaseCount: currentCompletedPurchaseCount, productHandle: productHandle, url: url, message: message) } }
  20. © KAUCHE, Inc. Group+Extension.swift in KaucheMockKit (Active Group) import KaucheCoreKit

    public extension Group { static func active( id: String = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ownerUserId: String = "user_id", productId: String = "1234567890", groupRequirement: GroupRequirement = .init( lowerLimitUserCount: 2, expireDuration: 86400, upperLimitUserCount: 0, upperLimitUserCountSetting: .isNotActive ), expireDate: Date = Date(timeIntervalSinceNow: 100), status: GroupStatus = .inProgress, currentCompletedPurchaseCount: UInt32 = 1, productHandle: String = "product_1", url: String = "https://kauche.dev/groups/group_id", message: String = "" ) -> Group { .mock(id: id, ownerUserId: ownerUserId, productId: productId, groupRequirement: groupRequirement, expireDate: expireDate, status: status, currentCompletedPurchaseCount: currentCompletedPurchaseCount, productHandle: productHandle, url: url, message: message) } }
  21. © KAUCHE, Inc. Group+Extension.swift in KaucheMockKit (Expired Group) import KaucheCoreKit

    public extension Group { static func expired( id: String = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", ownerUserId: String = "user_id", productId: String = "1234567890", groupRequirement: GroupRequirement = .init( lowerLimitUserCount: 2, expireDuration: 86400, upperLimitUserCount: 0, upperLimitUserCountSetting: .isNotActive ), expireDate: Date = Date(timeIntervalSince1970: 1_596_683_282), status: GroupStatus = .expired, currentCompletedPurchaseCount: UInt32 = 1, productHandle: String = "product_1", url: String = "https://kauche.dev/groups/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", message: String = "" ) -> Group { .mock(id: id, ownerUserId: ownerUserId, productId: productId, groupRequirement: groupRequirement, expireDate: expireDate, status: status, currentCompletedPurchaseCount: currentCompletedPurchaseCount, productHandle: productHandle, url: url, message: message) } }
  22. © KAUCHE, Inc. How to use mock data #if DEBUG

    import KaucheCoreKit import KaucheMockKit struct GroupBuyingProgress_Previews: PreviewProvider { static var previews: some View { Group { GroupBuyingProgress(data: .init( remainingTimeData: .init( remainingTime: "23:59:59" ), groupProgressData: .init( group: .mock( groupRequirement: .mock( lowerLimitUserCount: 2 ), currentCompletedPurchaseCount: 1 ) ) )) .previewLayout(.sizeThatFits) GroupBuyingProgress(data: .init( remainingTimeData: .init( remainingTime: "23:59:59" ), groupProgressData: .init( group: .mock( groupRequirement: .mock( lowerLimitUserCount: 10 ), status: .completed, currentCompletedPurchaseCount: 10 ) ) )) .previewLayout(.sizeThatFits) } } } #endif @testable import Kauche import KaucheCoreKit import XCTest class GroupTests: XCTestCase { private var activeGroup: Group! private var expiredGroup: Group! override func setUp() { activeGroup = .active() expiredGroup = .expired() } func testActiveGroupIsExpired_false() { XCTAssertFalse(activeGroup.isExpired) } func testExpiredGroupIsExpired_true() { XCTAssertTrue(expiredGroup.isExpired) } } Previews UnitTests
  23. © KAUCHE, Inc. Dependency

  24. © KAUCHE, Inc. Dependency • モックデータは Unit Tests や Xcode

    Previews など開発用に定義し、使用する想定 • 開発アプリ Target のみにリンクさせる • 本番アプリ Target にはリンクしない
  25. © KAUCHE, Inc. Link KaucheMockKit

  26. © KAUCHE, Inc. まとめ

  27. © KAUCHE, Inc. まとめ • シェア買いアプリ「カウシェ」の Multi Modules 導入状況を共有しました •

    Unit Tests / Xcode Preview で使用しているモックデータ定義が重複してしまうという課題 に対して、KaucheMockKit を作成しモックデータを集約しました • KaucheMockKit の中身やリンクに関してお話しました
  28. © KAUCHE, Inc. #kauche_techtalk カウシェ、絶賛採用募集中です! 急成長中のECスタートアップで活躍したい仲間求む! エンジニア求人💁‍‍

  29. © KAUCHE, Inc. https://enjoy-working.kauche.com/product