From 5867005be1c59e76b7173e9abc4ab0dbf630f6ed Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 13:05:16 +0900 Subject: [PATCH 01/17] Setup swift-testing --- Package.swift | 10 ++++++-- .../xcshareddata/swiftpm/Package.resolved | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 UhooiPicBook.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Package.swift b/Package.swift index 7d2d12e3..a71994cd 100644 --- a/Package.swift +++ b/Package.swift @@ -2,6 +2,10 @@ import PackageDescription +private extension PackageDescription.Target.Dependency { + static let testing: Self = .product(name: "Testing", package: "swift-testing") +} + let firebaseAnalyticsDependencies: [Target.Dependency] = [ "FBLPromises", "FirebaseAnalytics", @@ -63,8 +67,8 @@ let package = Package( name: "UhooiPicBookPackage", defaultLocalization: "ja", platforms: [ - .iOS(.v15), - .macOS(.v10_15), + .iOS(.v16), + .macOS(.v13), ], products: [ .library(name: "FirebaseSetup", targets: ["FirebaseSetup"]), @@ -75,6 +79,7 @@ let package = Package( .library(name: "ImageLoader", targets: ["ImageLoader"]), // TODO: Remove later ], dependencies: [ + .package(url: "https://github.com/apple/swift-testing.git", branch: "main"), ], targets: [ .target( @@ -103,6 +108,7 @@ let package = Package( name: "AppModuleTests", dependencies: [ "AppModule", + .testing, ] ), .target( diff --git a/UhooiPicBook.xcworkspace/xcshareddata/swiftpm/Package.resolved b/UhooiPicBook.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..0a685e54 --- /dev/null +++ b/UhooiPicBook.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,23 @@ +{ + "pins" : [ + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-syntax.git", + "state" : { + "revision" : "74203046135342e4a4a627476dd6caf8b28fe11b", + "version" : "509.0.0" + } + }, + { + "identity" : "swift-testing", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-testing.git", + "state" : { + "branch" : "main", + "revision" : "70f5963165929efa473522f8063e1590f85b3b9c" + } + } + ], + "version" : 2 +} From b7e200d74a6d2d9b9a05058ad0238a1b47fe0cf8 Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 13:05:24 +0900 Subject: [PATCH 02/17] Update MonsterListPresenterTests --- .../MonsterListPresenterTests.swift | 185 ++++++++---------- Tests/AppModuleTests/Scaffolding.swift | 15 ++ 2 files changed, 100 insertions(+), 100 deletions(-) create mode 100644 Tests/AppModuleTests/Scaffolding.swift diff --git a/Tests/AppModuleTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift b/Tests/AppModuleTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift index ffc5ca8d..8e674677 100644 --- a/Tests/AppModuleTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift +++ b/Tests/AppModuleTests/Modules/MonsterList/Presenters/MonsterListPresenterTests.swift @@ -7,33 +7,37 @@ // import XCTest +import Testing @testable import AppModule import MonstersRepository @MainActor -final class MonsterListPresenterTests: XCTestCase { +struct MonsterListPresenterTests { // MARK: Stored Instance Properties - private var viewMock: MonsterListUserInterfaceMock! - private var interactorMock: MonsterListInteractorInputMock! - private var routerMock: MonsterListRouterInputMock! + private let viewMock: MonsterListUserInterfaceMock + private let interactorMock: MonsterListInteractorInputMock + private let routerMock: MonsterListRouterInputMock - private var presenter: MonsterListPresenter< + private let presenter: MonsterListPresenter< MonsterListUserInterfaceMock, MonsterListInteractorInputMock, MonsterListRouterInputMock - >! + > // MARK: TestCase Life-Cycle Methods @MainActor - override func setUpWithError() throws { - reset() - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. + init() { + self.viewMock = MonsterListUserInterfaceMock() + self.interactorMock = MonsterListInteractorInputMock() + self.routerMock = MonsterListRouterInputMock() + self.presenter = MonsterListPresenter( + view: self.viewMock, + interactor: self.interactorMock, + router: self.routerMock + ) } // MARK: - Test Methods @@ -42,24 +46,26 @@ final class MonsterListPresenterTests: XCTestCase { // MARK: viewDidLoad() - func test_viewDidLoad_success_zero() async { + @Test + func viewDidLoad_success_zero() async { let monsterDTOs: [MonsterDTO] = [] interactorMock.monstersHandler = { monsterDTOs } viewMock.showMonstersHandler = { monsters in for _ in 0 ..< monsterDTOs.count { - XCTFail("There shouldn't be any monsters.") + Issue.record("There shouldn't be any monsters.") } } await presenter.viewDidLoad() - XCTAssertEqual(viewMock.startIndicatorCallCount, 1) - XCTAssertEqual(interactorMock.monstersCallCount, 1) - XCTAssertEqual(viewMock.showMonstersCallCount, 1) - XCTAssertEqual(viewMock.stopIndicatorCallCount, 1) + #expect(viewMock.startIndicatorCallCount == 1) + #expect(interactorMock.monstersCallCount == 1) + #expect(viewMock.showMonstersCallCount == 1) + #expect(viewMock.stopIndicatorCallCount == 1) } - func test_viewDidLoad_success_three() async { + @Test + func viewDidLoad_success_three() async { let uhooiDTO = MonsterDTO(name: "uhooi", description: "uhooi's description", baseColorCode: "#FFFFFF", iconURLString: "https://theuhooi.com/uhooi", dancingURLString: "https://theuhooi.com/uhooi-dancing", order: 1) let ayausaDTO = MonsterDTO(name: "ayausa", description: "ayausa's description", baseColorCode: "#000000", iconURLString: "https://theuhooi.com/ayausa", dancingURLString: "https://theuhooi.com/ayausa-dancing", order: 2) let chibirdDTO = MonsterDTO(name: "chibird", description: "chibird's description", baseColorCode: "#999999", iconURLString: "https://theuhooi.com/chibird", dancingURLString: "https://theuhooi.com/chibird-dancing", order: 3) @@ -69,144 +75,123 @@ final class MonsterListPresenterTests: XCTestCase { for index in 0 ..< monsterDTOs.count { let actual = MonsterItem(entity: MonsterEntity(dto: monsterDTOs[index])) let expected = monsterItems[index] - XCTAssertEqual(actual, expected) + #expect(actual == expected) } } await presenter.viewDidLoad() - XCTAssertEqual(viewMock.startIndicatorCallCount, 1) - XCTAssertEqual(interactorMock.monstersCallCount, 1) - XCTAssertEqual(viewMock.showMonstersCallCount, 1) - XCTAssertEqual(viewMock.stopIndicatorCallCount, 1) + #expect(viewMock.startIndicatorCallCount == 1) + #expect(interactorMock.monstersCallCount == 1) + #expect(viewMock.showMonstersCallCount == 1) + #expect(viewMock.stopIndicatorCallCount == 1) } - func test_viewDidLoad_newLine() async { - typealias TestCase = (description: String, expected: String, line: UInt) - let testCases: [TestCase] = [ - ("", "" , #line), - ("¥¥n", "¥¥n" , #line), - ("\n", "\n" , #line), - ("\\n", "\n" , #line), - // ("\\\n", "\\n" ,#line), - ("\\n\\n", "\n\n" , #line), - ("test\\nuhooi", "test\nuhooi" , #line), - ] - - for (description, expected, line) in testCases { - reset() - let monsterDTO = MonsterDTO( - name: "monster's name", - description: description, - baseColorCode: "#FFFFFF", - iconURLString: "https://theuhooi.com/monster", - dancingURLString: "https://theuhooi.com/monster-dancing", - order: 1 - ) - interactorMock.monstersHandler = { [monsterDTO] } - viewMock.showMonstersHandler = { monsters in - XCTAssertEqual(monsters[0].description, expected, line: line) - } - - await presenter.viewDidLoad() - - XCTAssertEqual(viewMock.startIndicatorCallCount, 1) - XCTAssertEqual(interactorMock.monstersCallCount, 1) - XCTAssertEqual(viewMock.showMonstersCallCount, 1) - XCTAssertEqual(viewMock.stopIndicatorCallCount, 1) + @Test(arguments: zip(["", "¥¥n", "\n", "\\n", "\\n\\n", "test\\nuhooi"], ["", "¥¥n", "\n", "\n", "\n\n", "test\nuhooi"])) + func viewDidLoad_newLine(description: String, expected: String) async { + let monsterDTO = MonsterDTO( + name: "monster's name", + description: description, + baseColorCode: "#FFFFFF", + iconURLString: "https://theuhooi.com/monster", + dancingURLString: "https://theuhooi.com/monster-dancing", + order: 1 + ) + interactorMock.monstersHandler = { [monsterDTO] } + viewMock.showMonstersHandler = { monsters in + #expect(monsters[0].description == expected) } + + await presenter.viewDidLoad() + + #expect(viewMock.startIndicatorCallCount == 1) + #expect(interactorMock.monstersCallCount == 1) + #expect(viewMock.showMonstersCallCount == 1) + #expect(viewMock.stopIndicatorCallCount == 1) } - func test_viewDidLoad_failure() async { + @Test + func viewDidLoad_failure() async { struct TestError: Error {} interactorMock.monstersHandler = { throw TestError() } await presenter.viewDidLoad() - XCTAssertEqual(viewMock.startIndicatorCallCount, 1) - XCTAssertEqual(interactorMock.monstersCallCount, 1) - XCTAssertEqual(viewMock.showMonstersCallCount, 0) - XCTAssertEqual(viewMock.stopIndicatorCallCount, 1) + #expect(viewMock.startIndicatorCallCount == 1) + #expect(interactorMock.monstersCallCount == 1) + #expect(viewMock.showMonstersCallCount == 0) + #expect(viewMock.stopIndicatorCallCount == 1) } // MARK: didTapContactUs() - func test_didTapContactUs() { + @Test + func didTapContactUs() { presenter.didTapContactUs() - XCTAssertEqual(routerMock.showContactUsCallCount, 1) - XCTAssertEqual(routerMock.showPrivacyPolicyCallCount, 0) - XCTAssertEqual(routerMock.showSettingsCallCount, 0) - XCTAssertEqual(routerMock.showAboutThisAppCallCount, 0) + #expect(routerMock.showContactUsCallCount == 1) + #expect(routerMock.showPrivacyPolicyCallCount == 0) + #expect(routerMock.showSettingsCallCount == 0) + #expect(routerMock.showAboutThisAppCallCount == 0) } // MARK: didTapPrivacyPolicy() - func test_didTapPrivacyPolicy() { + @Test + func didTapPrivacyPolicy() { presenter.didTapPrivacyPolicy() - XCTAssertEqual(routerMock.showContactUsCallCount, 0) - XCTAssertEqual(routerMock.showPrivacyPolicyCallCount, 1) - XCTAssertEqual(routerMock.showSettingsCallCount, 0) - XCTAssertEqual(routerMock.showAboutThisAppCallCount, 0) + #expect(routerMock.showContactUsCallCount == 0) + #expect(routerMock.showPrivacyPolicyCallCount == 1) + #expect(routerMock.showSettingsCallCount == 0) + #expect(routerMock.showAboutThisAppCallCount == 0) } // MARK: didTapLicenses() - func test_didTapLicenses() { + @Test + func didTapLicenses() { presenter.didTapLicenses() - XCTAssertEqual(routerMock.showContactUsCallCount, 0) - XCTAssertEqual(routerMock.showPrivacyPolicyCallCount, 0) - XCTAssertEqual(routerMock.showSettingsCallCount, 1) - XCTAssertEqual(routerMock.showAboutThisAppCallCount, 0) + #expect(routerMock.showContactUsCallCount == 0) + #expect(routerMock.showPrivacyPolicyCallCount == 0) + #expect(routerMock.showSettingsCallCount == 1) + #expect(routerMock.showAboutThisAppCallCount == 0) } // MARK: didTapAboutThisApp() - func test_didTapAboutThisApp() { + @Test + func didTapAboutThisApp() { presenter.didTapAboutThisApp() - XCTAssertEqual(routerMock.showContactUsCallCount, 0) - XCTAssertEqual(routerMock.showPrivacyPolicyCallCount, 0) - XCTAssertEqual(routerMock.showSettingsCallCount, 0) - XCTAssertEqual(routerMock.showAboutThisAppCallCount, 1) + #expect(routerMock.showContactUsCallCount == 0) + #expect(routerMock.showPrivacyPolicyCallCount == 0) + #expect(routerMock.showSettingsCallCount == 0) + #expect(routerMock.showAboutThisAppCallCount == 1) } // MARK: MonsterSectionEventHandler // MARK: didSelectMonster() - func test_didSelectMonster() async { + @Test + func didSelectMonster() async { let uhooiDTO = MonsterDTO(name: "uhooi", description: "uhooi's description", baseColorCode: "#FFFFFF", iconURLString: "https://theuhooi.com/uhooi", dancingURLString: "https://theuhooi.com/uhooi-dancing", order: 1) let monsterDTOs = [uhooiDTO] interactorMock.monstersHandler = { monsterDTOs } viewMock.showMonstersHandler = { monsters in for index in 0 ..< monsterDTOs.count { - XCTAssertEqual(monsters[index].name, monsterDTOs[index].name) + #expect(monsters[index].name == monsterDTOs[index].name) } } await presenter.viewDidLoad() await presenter.didSelectMonster(at: 0) - XCTAssertEqual(routerMock.showMonsterDetailCallCount, 1) - XCTAssertEqual(interactorMock.saveMonsterInSpotlightCallCount, 1) + #expect(routerMock.showMonsterDetailCallCount == 1) + #expect(interactorMock.saveMonsterInSpotlightCallCount == 1) } // MARK: MonsterListInteractorOutput - - // MARK: - Other Private Methods - - private func reset() { - self.viewMock = MonsterListUserInterfaceMock() - self.interactorMock = MonsterListInteractorInputMock() - self.routerMock = MonsterListRouterInputMock() - self.presenter = MonsterListPresenter( - view: self.viewMock, - interactor: self.interactorMock, - router: self.routerMock - ) - } - } diff --git a/Tests/AppModuleTests/Scaffolding.swift b/Tests/AppModuleTests/Scaffolding.swift new file mode 100644 index 00000000..e4cb370d --- /dev/null +++ b/Tests/AppModuleTests/Scaffolding.swift @@ -0,0 +1,15 @@ +// +// Scaffolding.swift +// +// +// Created by uhooi on 2023/10/01. +// + +import XCTest +import Testing + +final class AllTests: XCTestCase { + func testAll() async { + await XCTestScaffold.runAllTests(hostedBy: self) + } +} From d7c31ffef1e9dc13622aa0b680cf1280f03eb0cb Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 13:11:12 +0900 Subject: [PATCH 03/17] Update MonsterListInteractorTests --- .../MonsterListInteractorTests.swift | 74 +++++++++---------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/Tests/AppModuleTests/Modules/MonsterList/Interactors/MonsterListInteractorTests.swift b/Tests/AppModuleTests/Modules/MonsterList/Interactors/MonsterListInteractorTests.swift index d54e6d1a..37501d05 100644 --- a/Tests/AppModuleTests/Modules/MonsterList/Interactors/MonsterListInteractorTests.swift +++ b/Tests/AppModuleTests/Modules/MonsterList/Interactors/MonsterListInteractorTests.swift @@ -7,32 +7,38 @@ // import XCTest +import Testing @testable import AppModule import MonstersRepository -final class MonsterListInteractorTests: XCTestCase { +struct MonsterListInteractorTests { // MARK: Stored Instance Properties - private var presenterMock: MonsterListInteractorOutputMock! - private var monstersRepositoryMock: MonstersRepositoryMock! - private var monstersTempRepositoryMock: MonstersTempRepositoryMock! - private var spotlightRepositoryMock: SpotlightRepositoryMock! + private let presenterMock: MonsterListInteractorOutputMock + private let monstersRepositoryMock: MonstersRepositoryMock + private let monstersTempRepositoryMock: MonstersTempRepositoryMock + private let spotlightRepositoryMock: SpotlightRepositoryMock - private var interactor: MonsterListInteractor< + private let interactor: MonsterListInteractor< SpotlightRepositoryMock, MonstersRepositoryMock, MonstersTempRepositoryMock - >! + > // MARK: TestCase Life-Cycle Methods - override func setUpWithError() throws { - reset() - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. + init() { + self.presenterMock = MonsterListInteractorOutputMock() + self.monstersRepositoryMock = MonstersRepositoryMock() + self.monstersTempRepositoryMock = MonstersTempRepositoryMock() + self.spotlightRepositoryMock = SpotlightRepositoryMock() + self.interactor = MonsterListInteractor( + spotlightRepository: self.spotlightRepositoryMock, + monstersRepository: self.monstersRepositoryMock, + monstersTempRepository: self.monstersTempRepositoryMock + ) + self.interactor.inject(presenter: self.presenterMock) } // MARK: - Test Methods @@ -41,55 +47,43 @@ final class MonsterListInteractorTests: XCTestCase { // MARK: monsters() - func test_monsters_success() async { + @Test + func monsters_success() async { let monsterDTOs: [MonsterDTO] = [] monstersRepositoryMock.monstersHandler = { monsterDTOs } do { let monsters = try await interactor.monsters() - XCTAssertEqual(monsters, monsterDTOs) + #expect(monsters == monsterDTOs) } catch { - XCTFail("Error: \(error)") + Issue.record("Error: \(error)") } - XCTAssertEqual(monstersRepositoryMock.monstersCallCount, 1) + #expect(monstersRepositoryMock.monstersCallCount == 1) } - func test_monsters_failure() async { + @Test + func monsters_failure() async { struct TestError: Error {} monstersRepositoryMock.monstersHandler = { throw TestError() } do { let monsters = try await interactor.monsters() - XCTFail("Monsters: \(monsters)") + Issue.record("Monsters: \(monsters)") } catch { - XCTAssertTrue(error is TestError) + #expect(error is TestError) } - XCTAssertEqual(monstersRepositoryMock.monstersCallCount, 1) + #expect(monstersRepositoryMock.monstersCallCount == 1) } - // saveMonsterInSpotlight() + // MARK: saveMonsterInSpotlight() - func test_saveMonsterInSpotlight() async { + @Test + func saveMonsterInSpotlight() async { let uhooiEntity = MonsterEntity(name: "uhooi", description: "uhooi's description\nuhooi", baseColorCode: "#FFFFFF", iconURL: URL(string: "https://theuhooi.com/uhooi")!, dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")!) await interactor.saveMonsterInSpotlight(uhooiEntity) - XCTAssertEqual(monstersTempRepositoryMock.saveMonsterCallCount, 1) - XCTAssertEqual(spotlightRepositoryMock.saveMonsterCallCount, 1) - } - - // MARK: - Other Private Methods - - private func reset() { - self.presenterMock = MonsterListInteractorOutputMock() - self.monstersRepositoryMock = MonstersRepositoryMock() - self.monstersTempRepositoryMock = MonstersTempRepositoryMock() - self.spotlightRepositoryMock = SpotlightRepositoryMock() - self.interactor = MonsterListInteractor( - spotlightRepository: self.spotlightRepositoryMock, - monstersRepository: self.monstersRepositoryMock, - monstersTempRepository: self.monstersTempRepositoryMock - ) - self.interactor.inject(presenter: self.presenterMock) + #expect(monstersTempRepositoryMock.saveMonsterCallCount == 1) + #expect(spotlightRepositoryMock.saveMonsterCallCount == 1) } } From 398089eeed8aa67f113045a9a6179a80f4089e4a Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 14:22:45 +0900 Subject: [PATCH 04/17] Update MonsterDetailPresenterTests --- .../MonsterDetailPresenterTests.swift | 97 +++++++++---------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/Tests/AppModuleTests/Modules/MonsterDetail/Presenters/MonsterDetailPresenterTests.swift b/Tests/AppModuleTests/Modules/MonsterDetail/Presenters/MonsterDetailPresenterTests.swift index 2593c2a0..954ac560 100644 --- a/Tests/AppModuleTests/Modules/MonsterDetail/Presenters/MonsterDetailPresenterTests.swift +++ b/Tests/AppModuleTests/Modules/MonsterDetail/Presenters/MonsterDetailPresenterTests.swift @@ -7,32 +7,36 @@ // import XCTest +import Testing @testable import AppModule @MainActor -final class MonsterDetailPresenterTests: XCTestCase { +struct MonsterDetailPresenterTests { // MARK: Stored Instance Properties - private var viewMock: MonsterDetailUserInterfaceMock! - private var interactorMock: MonsterDetailInteractorInputMock! - private var routerMock: MonsterDetailRouterInputMock! + private let viewMock: MonsterDetailUserInterfaceMock + private let interactorMock: MonsterDetailInteractorInputMock + private let routerMock: MonsterDetailRouterInputMock - private var presenter: MonsterDetailPresenter< + private let presenter: MonsterDetailPresenter< MonsterDetailUserInterfaceMock, MonsterDetailInteractorInputMock, MonsterDetailRouterInputMock - >! + > // MARK: TestCase Life-Cycle Methods @MainActor - override func setUpWithError() throws { - reset() - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. + init() { + self.viewMock = MonsterDetailUserInterfaceMock() + self.interactorMock = MonsterDetailInteractorInputMock() + self.routerMock = MonsterDetailRouterInputMock() + self.presenter = MonsterDetailPresenter( + view: self.viewMock, + interactor: self.interactorMock, + router: self.routerMock + ) } // MARK: - Test Methods @@ -41,69 +45,64 @@ final class MonsterDetailPresenterTests: XCTestCase { // MARK: viewDidLoad() - func test_viewDidLoad() { + @Test + func viewDidLoad() { presenter.viewDidLoad() } // MARK: didTapDancingImageView() - func test_didTapDancingImageView_notNil() { + @Test + func didTapDancingImageView_notNil() { presenter.didTapDancingImageView(dancingImage: UIImage()) - XCTAssertEqual(routerMock.popupDancingImageCallCount, 1) + #expect(routerMock.popupDancingImageCallCount == 1) } - func test_didTapDancingImageView_nil() { + @Test + func didTapDancingImageView_nil() { presenter.didTapDancingImageView(dancingImage: nil) - XCTAssertEqual(routerMock.popupDancingImageCallCount, 0) + #expect(routerMock.popupDancingImageCallCount == 0) } // MARK: didTapShareButton() - func test_didTapShareButton_one_nil() { - typealias TestCase = (senderView: UIView?, name: String?, description: String?, icon: UIImage?, line: UInt) - let testCases: [TestCase] = [ - (nil, "name", "description", UIImage(), #line), - (UIView(), nil, "description", UIImage(), #line), - (UIView(), "name", nil, UIImage(), #line), - (UIView(), "name", "description", nil, #line) - ] - - for (senderView, name, description, icon, line) in testCases { - presenter.didTapShareButton(senderView, name: name, description: description, icon: icon) - XCTAssertEqual(routerMock.showActivityCallCount, 0, line: line) - } - } + // FIXME: A build error occurs. + // ref: https://github.com/apple/swift-testing/issues/41 +// struct DidTapShareButtonOneNilArgument { +// let senderView: UIView? +// let name: String? +// let description: String? +// let icon: UIImage? +// } +// @Test(arguments: [ +// DidTapShareButtonOneNilArgument(senderView: nil, name: "name", description: "description", icon: UIImage()), +// DidTapShareButtonOneNilArgument(senderView: UIView(), name: nil, description: "description", icon: UIImage()), +// DidTapShareButtonOneNilArgument(senderView: UIView(), name: "name", description: nil, icon: UIImage()), +// DidTapShareButtonOneNilArgument(senderView: UIView(), name: "name", description: "description", icon: nil), +// ]) +// func didTapShareButton_one_nil(_ argument: DidTapShareButtonOneNilArgument) { +// presenter.didTapShareButton(argument.senderView, name: argument.name, description: argument.description, icon: argument.icon) +// #expect(routerMock.showActivityCallCount == 0) +// } - func test_didTapShareButton_all_notNil() { + @Test + func didTapShareButton_all_notNil() { let senderView = UIView() let name = "name" let description = "description" let icon = UIImage() routerMock.showActivityHandler = { sourceView, text, image in - XCTAssertEqual(text, "\(name)\n\(description)\n#UhooiPicBook") - XCTAssertEqual(sourceView, senderView) - XCTAssertEqual(image, icon) + #expect(text == "\(name)\n\(description)\n#UhooiPicBook") + #expect(sourceView == senderView) + #expect(image == icon) } presenter.didTapShareButton(senderView, name: name, description: description, icon: icon) - XCTAssertEqual(routerMock.showActivityCallCount, 1) + #expect(routerMock.showActivityCallCount == 1) } // MARK: MonsterDetailInteractorOutput - - // MARK: - Other Private Methods - - private func reset() { - self.viewMock = MonsterDetailUserInterfaceMock() - self.interactorMock = MonsterDetailInteractorInputMock() - self.routerMock = MonsterDetailRouterInputMock() - self.presenter = MonsterDetailPresenter( - view: self.viewMock, - interactor: self.interactorMock, - router: self.routerMock - ) - } } From 774031a549ccf9a290f6052d9a708e65ba429bcd Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 14:24:06 +0900 Subject: [PATCH 05/17] Update MonsterDetailInteractorTests --- .../MonsterDetailInteractorTests.swift | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/Tests/AppModuleTests/Modules/MonsterDetail/Interactors/MonsterDetailInteractorTests.swift b/Tests/AppModuleTests/Modules/MonsterDetail/Interactors/MonsterDetailInteractorTests.swift index c9c57c90..ddfce3c7 100644 --- a/Tests/AppModuleTests/Modules/MonsterDetail/Interactors/MonsterDetailInteractorTests.swift +++ b/Tests/AppModuleTests/Modules/MonsterDetail/Interactors/MonsterDetailInteractorTests.swift @@ -7,35 +7,26 @@ // import XCTest +import Testing @testable import AppModule -final class MonsterDetailInteractorTests: XCTestCase { +struct MonsterDetailInteractorTests { // MARK: Stored Instance Properties - private var presenterMock: MonsterDetailInteractorOutputMock! + private let presenterMock: MonsterDetailInteractorOutputMock - private var interactor: MonsterDetailInteractor! + private let interactor: MonsterDetailInteractor // MARK: TestCase Life-Cycle Methods - override func setUpWithError() throws { - reset() - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. + init() { + self.presenterMock = MonsterDetailInteractorOutputMock() + self.interactor = MonsterDetailInteractor() + self.interactor.inject(presenter: self.presenterMock) } // MARK: - Test Methods // MARK: MonsterDetailInteractorInput - - // MARK: - Other Private Methods - - private func reset() { - self.presenterMock = MonsterDetailInteractorOutputMock() - self.interactor = MonsterDetailInteractor() - self.interactor.inject(presenter: self.presenterMock) - } } From e0cc80010ada4e621fc8c4cda139bb289ce50f9b Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 14:32:50 +0900 Subject: [PATCH 06/17] Update UserDefaultsClientTests --- .../Temp/UserDefaultsClientTests.swift | 43 +++++++------------ 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift b/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift index 512db4da..652d9f7a 100644 --- a/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift +++ b/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift @@ -6,9 +6,10 @@ // import XCTest +import Testing @testable import AppModule -final class UserDefaultsClientTests: XCTestCase { +struct UserDefaultsClientTests { // MARK: Stored Instance Properties @@ -16,43 +17,31 @@ final class UserDefaultsClientTests: XCTestCase { // MARK: TestCase Life-Cycle Methods - override func setUpWithError() throws { - reset() - } - - override func tearDownWithError() throws { + init() { + userDefaults.removeAll() } // MARK: - Test Methods - func test_monster() { + @Test + func monster() { var uhooiEntity = MonsterEntity(name: "uhooi", description: "uhooi's description\nuhooi", baseColorCode: "#FFFFFF", iconURL: URL(string: "https://theuhooi.com/uhooi")!, dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")!) let key = "spotlight_\(uhooiEntity.name)" - XCTContext.runActivity(named: "Unsaved") { _ in - XCTAssertNil(userDefaults.monster(key: key)) - } + // Unsaved + #expect(userDefaults.monster(key: key) == nil) - XCTContext.runActivity(named: "Add") { _ in - userDefaults.saveMonster(uhooiEntity, forKey: key) - XCTAssertEqual(uhooiEntity, userDefaults.monster(key: key)) - } + // Add + userDefaults.saveMonster(uhooiEntity, forKey: key) + #expect(uhooiEntity == userDefaults.monster(key: key)) + // Update uhooiEntity = MonsterEntity(name: "uhooi", description: "uhooi's description\nuhooi", baseColorCode: "#000000", iconURL: URL(string: "https://theuhooi.com/uhooi")!, dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")!) - XCTContext.runActivity(named: "Update") { _ in - userDefaults.saveMonster(uhooiEntity, forKey: key) - XCTAssertEqual(uhooiEntity, userDefaults.monster(key: key)) - } + userDefaults.saveMonster(uhooiEntity, forKey: key) + #expect(uhooiEntity == userDefaults.monster(key: key)) - XCTContext.runActivity(named: "Remove") { _ in - userDefaults.removeAll() - XCTAssertNil(userDefaults.monster(key: key)) - } - } - - // MARK: - Other Private Methods - - private func reset() { + // Remove userDefaults.removeAll() + #expect(userDefaults.monster(key: key) == nil) } } From 78010446da1c26907295cc4d76a1aeb828c87707 Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 14:40:02 +0900 Subject: [PATCH 07/17] Add comments --- Package.swift | 2 +- .../Repository/Temp/UserDefaultsClientTests.swift | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index a71994cd..9c97a02b 100644 --- a/Package.swift +++ b/Package.swift @@ -79,7 +79,7 @@ let package = Package( .library(name: "ImageLoader", targets: ["ImageLoader"]), // TODO: Remove later ], dependencies: [ - .package(url: "https://github.com/apple/swift-testing.git", branch: "main"), + .package(url: "https://github.com/apple/swift-testing.git", branch: "main"), // TODO: Use stable ], targets: [ .target( diff --git a/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift b/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift index 652d9f7a..57080a57 100644 --- a/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift +++ b/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift @@ -28,6 +28,8 @@ struct UserDefaultsClientTests { var uhooiEntity = MonsterEntity(name: "uhooi", description: "uhooi's description\nuhooi", baseColorCode: "#FFFFFF", iconURL: URL(string: "https://theuhooi.com/uhooi")!, dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")!) let key = "spotlight_\(uhooiEntity.name)" + // TODO: Use `XCTContext.runActivity(named:)` . + // ref: https://github.com/apple/swift-testing/issues/42 // Unsaved #expect(userDefaults.monster(key: key) == nil) From c7de993c7e5783b03f1f2a3bd4043ab29fc0724a Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 14:46:57 +0900 Subject: [PATCH 08/17] Remove tests from production --- .github/workflows/main.yml | 2 +- App/Production.xcodeproj/project.pbxproj | 255 ------------------ .../xcschemes/UhooiPicBook.xcscheme | 9 +- App/Production.xctestplan | 65 ----- Makefile | 4 - 5 files changed, 3 insertions(+), 332 deletions(-) delete mode 100644 App/Production.xctestplan diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7b051885..c4807401 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -64,7 +64,7 @@ jobs: strategy: fail-fast: false matrix: - name: ["develop", "production", "app-module"] + name: ["develop", "app-module"] steps: # チェックアウト diff --git a/App/Production.xcodeproj/project.pbxproj b/App/Production.xcodeproj/project.pbxproj index 897ffa95..8dc783d1 100644 --- a/App/Production.xcodeproj/project.pbxproj +++ b/App/Production.xcodeproj/project.pbxproj @@ -7,12 +7,8 @@ objects = { /* Begin PBXBuildFile section */ - 2AB9187FB6C6F195BDFA0AEA /* UhooiPicBookUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77956692405C61E8D8C04B5 /* UhooiPicBookUITests.swift */; }; 3784E43C6F9862BB2E871B15 /* UhooiPicBookWidgetsConfigurableIntent.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = D3A28FF132F9DB6448EAC23F /* UhooiPicBookWidgetsConfigurableIntent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3ED6158022DE90CA4AA73905 /* ImagePopupPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C5239C3163F47164ECE33E8 /* ImagePopupPage.swift */; }; - 478286982E492B33E65E682B /* ActivityPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC591FA4C18A058784472F /* ActivityPage.swift */; }; 5022F0F1F72B5341C9486B7A /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */; }; - 522896F9FC51ED2221060387 /* MonsterListPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21F0F147EB90FE7EAF86DB2 /* MonsterListPage.swift */; }; 745EB4E9574D57EB307F2AB9 /* UhooiPicBookStickers.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = D97430DE3B018D83FA30BA3F /* UhooiPicBookStickers.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 791904CC2793F9DA00416F7D /* ImageLoader in Frameworks */ = {isa = PBXBuildFile; productRef = 791904CB2793F9DA00416F7D /* ImageLoader */; }; 791904D22794084800416F7D /* MonstersRepository in Frameworks */ = {isa = PBXBuildFile; productRef = 791904D12794084800416F7D /* MonstersRepository */; }; @@ -41,29 +37,11 @@ 797ABFA9278A9BA5005B445B /* AppModule in Frameworks */ = {isa = PBXBuildFile; productRef = 797ABFA8278A9BA5005B445B /* AppModule */; }; 7995BD302786F36A00B553DC /* FirebaseMessagingBridge in Frameworks */ = {isa = PBXBuildFile; productRef = 7995BD2F2786F36A00B553DC /* FirebaseMessagingBridge */; }; 79C193AB2789CF5200E7A58E /* MonsterWidgets in Frameworks */ = {isa = PBXBuildFile; productRef = 79C193AA2789CF5200E7A58E /* MonsterWidgets */; }; - 7B7002A645C43EBB624D82D8 /* MonsterDetailPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B117974B5DFAEB1BA1DB35C /* MonsterDetailPage.swift */; }; - A1713DA74A4AE73B34351622 /* XCUIElement+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 541427EC2F900D49CD247CB2 /* XCUIElement+Ex.swift */; }; - A6BE80E8825B6DA6ACE56D06 /* BundleStringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4618659C63EB6D450468854 /* BundleStringTests.swift */; }; - ED23EF346F55E2E02F461F16 /* PageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B1D686A013EAD76B19604C9 /* PageProtocol.swift */; }; F84FC678215D503C49D26C58 /* UhooiPicBookWidgets.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = AE659249AE186390141063EE /* UhooiPicBookWidgets.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; F8BBF148F1591E57471509B2 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3678749154206AA2C7DE69F6 /* WidgetKit.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 46DB71745F7E01A515C0F13C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8F21FB9F02C54BE4076B12F8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F7174334A4963303CCEE4E61; - remoteInfo = UhooiPicBook; - }; - 73857B2E0E8A6F194DF299E9 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 8F21FB9F02C54BE4076B12F8 /* Project object */; - proxyType = 1; - remoteGlobalIDString = F7174334A4963303CCEE4E61; - remoteInfo = UhooiPicBook; - }; 8DABA011EEC5DA70896A6C44 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8F21FB9F02C54BE4076B12F8 /* Project object */; @@ -108,11 +86,9 @@ 10643B8C75A51C25725E377B /* FirebaseAnalytics.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseAnalytics.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/FirebaseAnalytics.xcframework; sourceTree = ""; }; 144AF202560DF7170CA1B88E /* FirebaseRemoteConfig.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseRemoteConfig.xcframework; path = Frameworks/Firebase/FirebasePerformance/FirebaseRemoteConfig.xcframework; sourceTree = ""; }; 18C42AC12CA0DA009E4241B5 /* leveldb-library.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "leveldb-library.xcframework"; path = "Frameworks/Firebase/FirebaseFirestore/leveldb-library.xcframework"; sourceTree = ""; }; - 1B117974B5DFAEB1BA1DB35C /* MonsterDetailPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterDetailPage.swift; sourceTree = ""; }; 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 3678749154206AA2C7DE69F6 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 39F4CD1686D945CFB87141CE /* GoogleUtilities.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleUtilities.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/GoogleUtilities.xcframework; sourceTree = ""; }; - 541427EC2F900D49CD247CB2 /* XCUIElement+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUIElement+Ex.swift"; sourceTree = ""; }; 5FC40872E7A32ADB0B8AE3D7 /* FirebaseFirestore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseFirestore.xcframework; path = Frameworks/Firebase/FirebaseFirestore/FirebaseFirestore.xcframework; sourceTree = ""; }; 64FA23DFA00E386CF2DBCE63 /* FirebaseCoreDiagnostics.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseCoreDiagnostics.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/FirebaseCoreDiagnostics.xcframework; sourceTree = ""; }; 792E8EE6278C430A000F3902 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/WidgetsConfiguration.intentdefinition; sourceTree = ""; }; @@ -137,35 +113,24 @@ 792E8F9B278C6933000F3902 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = UhooiPicBook/Production/Assets.xcassets; sourceTree = SOURCE_ROOT; }; 792E8FA1278C6A56000F3902 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Shared/Production/GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; }; 792E8FDA278C7B6F000F3902 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; - 7955D06327B94B730061AE99 /* Production.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Production.xctestplan; sourceTree = ""; }; - 7C5239C3163F47164ECE33E8 /* ImagePopupPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePopupPage.swift; sourceTree = ""; }; - 83C280827AC1AC8CDC771EC4 /* UhooiPicBookUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UhooiPicBookUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 84E4ADEF286CCE96A2942A1A /* FirebaseCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseCore.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/FirebaseCore.xcframework; sourceTree = ""; }; 8A43FC43A5F5F2869F78909D /* FirebasePerformance.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebasePerformance.xcframework; path = Frameworks/Firebase/FirebasePerformance/FirebasePerformance.xcframework; sourceTree = ""; }; - 8B1D686A013EAD76B19604C9 /* PageProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageProtocol.swift; sourceTree = ""; }; 8BA1D60203EDBC076FFF5642 /* FirebaseMessaging.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseMessaging.xcframework; path = Frameworks/Firebase/FirebaseMessaging/FirebaseMessaging.xcframework; sourceTree = ""; }; 8F94607B0325642C330CD793 /* nanopb.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = nanopb.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/nanopb.xcframework; sourceTree = ""; }; - 988A97043A06E226C6868588 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; AE659249AE186390141063EE /* UhooiPicBookWidgets.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = UhooiPicBookWidgets.appex; sourceTree = BUILT_PRODUCTS_DIR; }; AE841A10BB74D787FB068BD6 /* GoogleDataTransport.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleDataTransport.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/GoogleDataTransport.xcframework; sourceTree = ""; }; B121E1EC2442F244D11C5380 /* PromisesObjC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PromisesObjC.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/PromisesObjC.xcframework; sourceTree = ""; }; - B21F0F147EB90FE7EAF86DB2 /* MonsterListPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterListPage.swift; sourceTree = ""; }; B2A9349AFF95EFE00FCADA23 /* FirebaseCrashlytics.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseCrashlytics.xcframework; path = Frameworks/Firebase/FirebaseCrashlytics/FirebaseCrashlytics.xcframework; sourceTree = ""; }; B3034A14E3F41394DEB55A62 /* GoogleAppMeasurement.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleAppMeasurement.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/GoogleAppMeasurement.xcframework; sourceTree = ""; }; B3ACB3BE3E7ED3A4C84410CA /* BoringSSL-GRPC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "BoringSSL-GRPC.xcframework"; path = "Frameworks/Firebase/FirebaseFirestore/BoringSSL-GRPC.xcframework"; sourceTree = ""; }; - BA21C3023C46CC6151A43886 /* UhooiPicBookTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UhooiPicBookTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; BD6DB9EB8A33ED4D0822DB8F /* FirebaseABTesting.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseABTesting.xcframework; path = Frameworks/Firebase/FirebasePerformance/FirebaseABTesting.xcframework; sourceTree = ""; }; BF104BB707E325AC73440499 /* FirebaseInstallations.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseInstallations.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/FirebaseInstallations.xcframework; sourceTree = ""; }; - D1BC591FA4C18A058784472F /* ActivityPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityPage.swift; sourceTree = ""; }; D3A28FF132F9DB6448EAC23F /* UhooiPicBookWidgetsConfigurableIntent.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = UhooiPicBookWidgetsConfigurableIntent.appex; sourceTree = BUILT_PRODUCTS_DIR; }; D97430DE3B018D83FA30BA3F /* UhooiPicBookStickers.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = UhooiPicBookStickers.appex; sourceTree = BUILT_PRODUCTS_DIR; }; - E4618659C63EB6D450468854 /* BundleStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleStringTests.swift; sourceTree = ""; }; - E486EDFB4B99417855E33115 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; E4EA4C797239C728014E8BCC /* UhooiPicBook.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UhooiPicBook.app; sourceTree = BUILT_PRODUCTS_DIR; }; E8C25BE3139AF9A212CCC8F0 /* gRPC-C++.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "gRPC-C++.xcframework"; path = "Frameworks/Firebase/FirebaseFirestore/gRPC-C++.xcframework"; sourceTree = ""; }; E93FC0F13B863F9E5F5D500D /* abseil.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = abseil.xcframework; path = Frameworks/Firebase/FirebaseFirestore/abseil.xcframework; sourceTree = ""; }; F6868AB01C3AABA6F00D83C8 /* gRPC-Core.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "gRPC-Core.xcframework"; path = "Frameworks/Firebase/FirebaseFirestore/gRPC-Core.xcframework"; sourceTree = ""; }; - F77956692405C61E8D8C04B5 /* UhooiPicBookUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UhooiPicBookUITests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -203,23 +168,12 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 17E82F135C45DA22DAD85E72 /* Foundation */ = { - isa = PBXGroup; - children = ( - E4618659C63EB6D450468854 /* BundleStringTests.swift */, - ); - path = Foundation; - sourceTree = ""; - }; 47C552D3546C641AB89783C1 = { isa = PBXGroup; children = ( - 7955D06327B94B730061AE99 /* Production.xctestplan */, 781042549E5A01519EFED671 /* Shared */, 792E8F3A278C4B2D000F3902 /* UhooiPicBook */, 792E8F57278C4C8E000F3902 /* UhooiPicBookStickers */, - BAB84381A6737A2083BC961F /* UhooiPicBookTests */, - EB1BD4D1C82D8077591B0698 /* UhooiPicBookUITests */, 792E8F87278C6532000F3902 /* UhooiPicBookWidgets */, 792E8F94278C67F1000F3902 /* UhooiPicBookWidgetsConfigurableIntent */, 644BA30E73485BDC342F7204 /* Frameworks */, @@ -335,44 +289,17 @@ path = UhooiPicBookWidgetsConfigurableIntent; sourceTree = ""; }; - 9D14FEE7DAB67CCFD61B333D /* TestCases */ = { - isa = PBXGroup; - children = ( - F77956692405C61E8D8C04B5 /* UhooiPicBookUITests.swift */, - ); - path = TestCases; - sourceTree = ""; - }; - 9E07DDF4AF7D2B2926033FDC /* Extensions */ = { - isa = PBXGroup; - children = ( - 17E82F135C45DA22DAD85E72 /* Foundation */, - ); - path = Extensions; - sourceTree = ""; - }; B9F854ED00B8603447D5057B /* Products */ = { isa = PBXGroup; children = ( E4EA4C797239C728014E8BCC /* UhooiPicBook.app */, D97430DE3B018D83FA30BA3F /* UhooiPicBookStickers.appex */, - BA21C3023C46CC6151A43886 /* UhooiPicBookTests.xctest */, - 83C280827AC1AC8CDC771EC4 /* UhooiPicBookUITests.xctest */, AE659249AE186390141063EE /* UhooiPicBookWidgets.appex */, D3A28FF132F9DB6448EAC23F /* UhooiPicBookWidgetsConfigurableIntent.appex */, ); name = Products; sourceTree = ""; }; - BAB84381A6737A2083BC961F /* UhooiPicBookTests */ = { - isa = PBXGroup; - children = ( - 988A97043A06E226C6868588 /* Info.plist */, - 9E07DDF4AF7D2B2926033FDC /* Extensions */, - ); - path = UhooiPicBookTests; - sourceTree = ""; - }; C2B92E538C189F4941F7DAFE /* Resources */ = { isa = PBXGroup; children = ( @@ -381,29 +308,6 @@ path = Resources; sourceTree = ""; }; - EB1BD4D1C82D8077591B0698 /* UhooiPicBookUITests */ = { - isa = PBXGroup; - children = ( - E486EDFB4B99417855E33115 /* Info.plist */, - 8B1D686A013EAD76B19604C9 /* PageProtocol.swift */, - 541427EC2F900D49CD247CB2 /* XCUIElement+Ex.swift */, - EB9FF08BDED117C228729B0B /* Pages */, - 9D14FEE7DAB67CCFD61B333D /* TestCases */, - ); - path = UhooiPicBookUITests; - sourceTree = ""; - }; - EB9FF08BDED117C228729B0B /* Pages */ = { - isa = PBXGroup; - children = ( - D1BC591FA4C18A058784472F /* ActivityPage.swift */, - 7C5239C3163F47164ECE33E8 /* ImagePopupPage.swift */, - 1B117974B5DFAEB1BA1DB35C /* MonsterDetailPage.swift */, - B21F0F147EB90FE7EAF86DB2 /* MonsterListPage.swift */, - ); - path = Pages; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -445,38 +349,6 @@ productReference = AE659249AE186390141063EE /* UhooiPicBookWidgets.appex */; productType = "com.apple.product-type.app-extension"; }; - 4677FBF8E3C5D8691051D106 /* UhooiPicBookTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1FF40AA4CFE5087652123EAD /* Build configuration list for PBXNativeTarget "UhooiPicBookTests" */; - buildPhases = ( - 4FE41A7B35B5E5FAA407F3FA /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - 4DAF6BC74EE9AEF3E06A50D2 /* PBXTargetDependency */, - ); - name = UhooiPicBookTests; - productName = UhooiPicBookTests; - productReference = BA21C3023C46CC6151A43886 /* UhooiPicBookTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - AD5F2C9896C8C0CAC68E089A /* UhooiPicBookUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5336812240FABFFCD289F94B /* Build configuration list for PBXNativeTarget "UhooiPicBookUITests" */; - buildPhases = ( - 22070DEEFB8F99971EC40231 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - BB72275143FEBC036B69BC5C /* PBXTargetDependency */, - ); - name = UhooiPicBookUITests; - productName = UhooiPicBookUITests; - productReference = 83C280827AC1AC8CDC771EC4 /* UhooiPicBookUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; C2DB76B6BCC6E8EF34FA57BF /* UhooiPicBookWidgetsConfigurableIntent */ = { isa = PBXNativeTarget; buildConfigurationList = 0BE8F8DC9871C9E99D77E15E /* Build configuration list for PBXNativeTarget "UhooiPicBookWidgetsConfigurableIntent" */; @@ -544,13 +416,6 @@ DevelopmentTeam = 47E56DYP3N; ProvisioningStyle = Automatic; }; - 4677FBF8E3C5D8691051D106 = { - DevelopmentTeam = 47E56DYP3N; - }; - AD5F2C9896C8C0CAC68E089A = { - DevelopmentTeam = 47E56DYP3N; - TestTargetID = F7174334A4963303CCEE4E61; - }; C2DB76B6BCC6E8EF34FA57BF = { DevelopmentTeam = 47E56DYP3N; ProvisioningStyle = Automatic; @@ -577,8 +442,6 @@ targets = ( F7174334A4963303CCEE4E61 /* UhooiPicBook */, 0E1AD029696068D4B516B255 /* UhooiPicBookStickers */, - 4677FBF8E3C5D8691051D106 /* UhooiPicBookTests */, - AD5F2C9896C8C0CAC68E089A /* UhooiPicBookUITests */, 162395B56ED57E8800847617 /* UhooiPicBookWidgets */, C2DB76B6BCC6E8EF34FA57BF /* UhooiPicBookWidgetsConfigurableIntent */, ); @@ -736,20 +599,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 22070DEEFB8F99971EC40231 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 478286982E492B33E65E682B /* ActivityPage.swift in Sources */, - 3ED6158022DE90CA4AA73905 /* ImagePopupPage.swift in Sources */, - 7B7002A645C43EBB624D82D8 /* MonsterDetailPage.swift in Sources */, - 522896F9FC51ED2221060387 /* MonsterListPage.swift in Sources */, - ED23EF346F55E2E02F461F16 /* PageProtocol.swift in Sources */, - 2AB9187FB6C6F195BDFA0AEA /* UhooiPicBookUITests.swift in Sources */, - A1713DA74A4AE73B34351622 /* XCUIElement+Ex.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 4B799ED34E78C3F6214D145F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -760,14 +609,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4FE41A7B35B5E5FAA407F3FA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A6BE80E8825B6DA6ACE56D06 /* BundleStringTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; B1556D34667F4525E961FE38 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -782,21 +623,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 4DAF6BC74EE9AEF3E06A50D2 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F7174334A4963303CCEE4E61 /* UhooiPicBook */; - targetProxy = 46DB71745F7E01A515C0F13C /* PBXContainerItemProxy */; - }; 51B7EA9FEB54D0504D29FD8D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 0E1AD029696068D4B516B255 /* UhooiPicBookStickers */; targetProxy = F97CF2FC9CF60F60A337F2AA /* PBXContainerItemProxy */; }; - BB72275143FEBC036B69BC5C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F7174334A4963303CCEE4E61 /* UhooiPicBook */; - targetProxy = 73857B2E0E8A6F194DF299E9 /* PBXContainerItemProxy */; - }; CFF8820FAA1030EA6191F5CE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = C2DB76B6BCC6E8EF34FA57BF /* UhooiPicBookWidgetsConfigurableIntent */; @@ -841,40 +672,6 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 09D4296D6247B3DC0D1D51D7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - INFOPLIST_FILE = UhooiPicBookUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.theuhooi.UhooiPicBookUITests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = UhooiPicBook; - }; - name = Release; - }; - 0ED5B166D8E6F0C77AD417DD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - INFOPLIST_FILE = UhooiPicBookTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.theuhooi.UhooiPicBookTests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UhooiPicBook.app/UhooiPicBook"; - }; - name = Debug; - }; 1F66094B9A6482DB9583F607 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1001,23 +798,6 @@ }; name = Release; }; - 637D639F1590AE62D4CC5F5B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - INFOPLIST_FILE = UhooiPicBookUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.theuhooi.UhooiPicBookUITests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = UhooiPicBook; - }; - name = Debug; - }; 6F3C0123B6BDA1D471303B9B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1224,23 +1004,6 @@ }; name = Release; }; - C95A34D40744F3B1A485A39D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - INFOPLIST_FILE = UhooiPicBookTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.theuhooi.UhooiPicBookTests; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UhooiPicBook.app/UhooiPicBook"; - }; - name = Release; - }; CE81301A562141C55A4EA86A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1303,15 +1066,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - 1FF40AA4CFE5087652123EAD /* Build configuration list for PBXNativeTarget "UhooiPicBookTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0ED5B166D8E6F0C77AD417DD /* Debug */, - C95A34D40744F3B1A485A39D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; 3E50B2D32EEA9C3FA89AE8F6 /* Build configuration list for PBXNativeTarget "UhooiPicBookStickers" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1321,15 +1075,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - 5336812240FABFFCD289F94B /* Build configuration list for PBXNativeTarget "UhooiPicBookUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 637D639F1590AE62D4CC5F5B /* Debug */, - 09D4296D6247B3DC0D1D51D7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; BF5510DB2613969D49C12435 /* Build configuration list for PBXNativeTarget "UhooiPicBookWidgets" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/App/Production.xcodeproj/xcshareddata/xcschemes/UhooiPicBook.xcscheme b/App/Production.xcodeproj/xcshareddata/xcschemes/UhooiPicBook.xcscheme index 519df04a..ac6cfbb3 100644 --- a/App/Production.xcodeproj/xcshareddata/xcschemes/UhooiPicBook.xcscheme +++ b/App/Production.xcodeproj/xcshareddata/xcschemes/UhooiPicBook.xcscheme @@ -56,7 +56,8 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "YES"> + onlyGenerateCoverageForSpecifiedTargets = "YES" + shouldAutocreateTestPlan = "YES"> - - - - Date: Sun, 1 Oct 2023 15:12:51 +0900 Subject: [PATCH 09/17] Update UhooiPicBookTests --- App/Develop.xcodeproj/project.pbxproj | 32 +++++++++++++++---- App/Production.xcodeproj/project.pbxproj | 12 +++---- .../Foundation/BundleStringTests.swift | 27 ++++++++-------- App/UhooiPicBookTests/Scaffolding.swift | 15 +++++++++ 4 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 App/UhooiPicBookTests/Scaffolding.swift diff --git a/App/Develop.xcodeproj/project.pbxproj b/App/Develop.xcodeproj/project.pbxproj index 06a627cd..3442cde4 100644 --- a/App/Develop.xcodeproj/project.pbxproj +++ b/App/Develop.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 3784E43C6F9862BB2E871B15 /* UhooiPicBookWidgetsConfigurableIntent.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D3A28FF132F9DB6448EAC23F /* UhooiPicBookWidgetsConfigurableIntent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3ED6158022DE90CA4AA73905 /* ImagePopupPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C5239C3163F47164ECE33E8 /* ImagePopupPage.swift */; }; 478286982E492B33E65E682B /* ActivityPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC591FA4C18A058784472F /* ActivityPage.swift */; }; + 4BBA93DC2AC9440300C022FD /* Scaffolding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBA93DB2AC9440300C022FD /* Scaffolding.swift */; }; 5022F0F1F72B5341C9486B7A /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */; }; 522896F9FC51ED2221060387 /* MonsterListPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21F0F147EB90FE7EAF86DB2 /* MonsterListPage.swift */; }; 745EB4E9574D57EB307F2AB9 /* UhooiPicBookStickers.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D97430DE3B018D83FA30BA3F /* UhooiPicBookStickers.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -112,6 +113,7 @@ 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 3678749154206AA2C7DE69F6 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 39F4CD1686D945CFB87141CE /* GoogleUtilities.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleUtilities.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/GoogleUtilities.xcframework; sourceTree = ""; }; + 4BBA93DB2AC9440300C022FD /* Scaffolding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scaffolding.swift; sourceTree = ""; }; 541427EC2F900D49CD247CB2 /* XCUIElement+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUIElement+Ex.swift"; sourceTree = ""; }; 5FC40872E7A32ADB0B8AE3D7 /* FirebaseFirestore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseFirestore.xcframework; path = Frameworks/Firebase/FirebaseFirestore/FirebaseFirestore.xcframework; sourceTree = ""; }; 64FA23DFA00E386CF2DBCE63 /* FirebaseCoreDiagnostics.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseCoreDiagnostics.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/FirebaseCoreDiagnostics.xcframework; sourceTree = ""; }; @@ -369,6 +371,7 @@ children = ( 988A97043A06E226C6868588 /* Info.plist */, 9E07DDF4AF7D2B2926033FDC /* Extensions */, + 4BBA93DB2AC9440300C022FD /* Scaffolding.swift */, ); path = UhooiPicBookTests; sourceTree = ""; @@ -572,6 +575,7 @@ ); mainGroup = 47C552D3546C641AB89783C1; packageReferences = ( + 4BBA93DA2AC93FBC00C022FD /* XCRemoteSwiftPackageReference "swift-testing" */, ); projectDirPath = ""; projectRoot = ""; @@ -765,6 +769,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4BBA93DC2AC9440300C022FD /* Scaffolding.swift in Sources */, A6BE80E8825B6DA6ACE56D06 /* BundleStringTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -864,6 +869,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = UhooiPicBookTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -889,7 +895,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgets/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -919,7 +925,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgetsConfigurableIntent/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -975,7 +981,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgets/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1059,7 +1065,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.6.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -1154,7 +1160,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.6.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -1182,6 +1188,7 @@ DEVELOPMENT_LANGUAGE = jp; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBook/Resources/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1201,6 +1208,7 @@ DEVELOPMENT_LANGUAGE = jp; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBook/Resources/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1216,6 +1224,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; INFOPLIST_FILE = UhooiPicBookTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1239,7 +1248,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgetsConfigurableIntent/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1326,6 +1335,17 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + 4BBA93DA2AC93FBC00C022FD /* XCRemoteSwiftPackageReference "swift-testing" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-testing.git"; + requirement = { + branch = main; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + /* Begin XCSwiftPackageProductDependency section */ 791904C92793F9CB00416F7D /* ImageLoader */ = { isa = XCSwiftPackageProductDependency; diff --git a/App/Production.xcodeproj/project.pbxproj b/App/Production.xcodeproj/project.pbxproj index 8dc783d1..7f1b17d3 100644 --- a/App/Production.xcodeproj/project.pbxproj +++ b/App/Production.xcodeproj/project.pbxproj @@ -686,7 +686,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgets/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -718,7 +718,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgetsConfigurableIntent/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -778,7 +778,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgets/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -846,7 +846,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.6.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; @@ -943,7 +943,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; MARKETING_VERSION = 1.6.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; @@ -1016,7 +1016,7 @@ "$(inherited)", ); INFOPLIST_FILE = "$(SRCROOT)/UhooiPicBookWidgetsConfigurableIntent/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift b/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift index e6b6be98..c205a1d3 100644 --- a/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift +++ b/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift @@ -6,26 +6,23 @@ // import XCTest +import Testing @testable import AppModule -final class BundleStringTests: XCTestCase { +struct BundleStringTests { // MARK: TestCase Life-Cycle Methods - override func setUpWithError() throws { - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } + init() {} // MARK: - Test Methods // MARK: displayName - func test_bundle_displayName() { + @Test + func bundle_displayName() { guard let language = Locale.preferredLanguages.first else { - XCTFail("Fail to load user's preferred languages.") + Issue.record("Fail to load user's preferred languages.") return } @@ -33,18 +30,20 @@ final class BundleStringTests: XCTestCase { case "en": "UhooiPicBook" default: "ウホーイ図鑑" } - XCTAssertEqual(Bundle.main.displayName, expected) + #expect(Bundle.main.displayName == expected) } // MARK: version - func test_bundle_version() { - XCTAssertEqual(Bundle.main.version, "1.6.0") + @Test + func bundle_version() { + #expect(Bundle.main.version == "1.6.0") } // MARK: build - func test_bundle_build() { - XCTAssertEqual(Bundle.main.build, "17") + @Test + func bundle_build() { + #expect(Bundle.main.build == "17") } } diff --git a/App/UhooiPicBookTests/Scaffolding.swift b/App/UhooiPicBookTests/Scaffolding.swift new file mode 100644 index 00000000..085c88d7 --- /dev/null +++ b/App/UhooiPicBookTests/Scaffolding.swift @@ -0,0 +1,15 @@ +// +// Scaffolding.swift +// UhooiPicBookTests +// +// Created by uhooi on 2023/10/01. +// + +import XCTest +import Testing + +final class AllTests: XCTestCase { + func testAll() async { + await XCTestScaffold.runAllTests(hostedBy: self) + } +} From 791eec64df7d5250eb678d442fa787a4a894f69e Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 21:07:43 +0900 Subject: [PATCH 10/17] Fix comment --- .../Extensions/Foundation/BundleStringTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift b/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift index c205a1d3..0c813061 100644 --- a/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift +++ b/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift @@ -1,5 +1,5 @@ // -// BundleVersionTests.swift +// BundleStringTests.swift // UhooiPicBookTests // // Created by uhooi on 2021/02/25. From 11291552304be56f57cce8c3b612711261ead23e Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 21:08:30 +0900 Subject: [PATCH 11/17] Remove swift-testing from develop xcodeproj --- App/Develop.xcodeproj/project.pbxproj | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/App/Develop.xcodeproj/project.pbxproj b/App/Develop.xcodeproj/project.pbxproj index 3442cde4..f3796146 100644 --- a/App/Develop.xcodeproj/project.pbxproj +++ b/App/Develop.xcodeproj/project.pbxproj @@ -575,7 +575,6 @@ ); mainGroup = 47C552D3546C641AB89783C1; packageReferences = ( - 4BBA93DA2AC93FBC00C022FD /* XCRemoteSwiftPackageReference "swift-testing" */, ); projectDirPath = ""; projectRoot = ""; @@ -1335,17 +1334,6 @@ }; /* End XCConfigurationList section */ -/* Begin XCRemoteSwiftPackageReference section */ - 4BBA93DA2AC93FBC00C022FD /* XCRemoteSwiftPackageReference "swift-testing" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-testing.git"; - requirement = { - branch = main; - kind = branch; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - /* Begin XCSwiftPackageProductDependency section */ 791904C92793F9CB00416F7D /* ImageLoader */ = { isa = XCSwiftPackageProductDependency; From f2078bb75db5afcd24087235c9ec10cb3ad2c197 Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 21:59:51 +0900 Subject: [PATCH 12/17] Fix xcodeproj test build error --- App/Develop.xcodeproj/project.pbxproj | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/App/Develop.xcodeproj/project.pbxproj b/App/Develop.xcodeproj/project.pbxproj index f3796146..4abb1579 100644 --- a/App/Develop.xcodeproj/project.pbxproj +++ b/App/Develop.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 3ED6158022DE90CA4AA73905 /* ImagePopupPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C5239C3163F47164ECE33E8 /* ImagePopupPage.swift */; }; 478286982E492B33E65E682B /* ActivityPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC591FA4C18A058784472F /* ActivityPage.swift */; }; 4BBA93DC2AC9440300C022FD /* Scaffolding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBA93DB2AC9440300C022FD /* Scaffolding.swift */; }; + 4BBB00272AC9A1BA002C12E2 /* Testing in Frameworks */ = {isa = PBXBuildFile; productRef = 4BBB00262AC9A1BA002C12E2 /* Testing */; }; 5022F0F1F72B5341C9486B7A /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */; }; 522896F9FC51ED2221060387 /* MonsterListPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21F0F147EB90FE7EAF86DB2 /* MonsterListPage.swift */; }; 745EB4E9574D57EB307F2AB9 /* UhooiPicBookStickers.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D97430DE3B018D83FA30BA3F /* UhooiPicBookStickers.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -171,6 +172,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 4BBB00242AC9A172002C12E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BBB00272AC9A1BA002C12E2 /* Testing in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6986B5ACA2E569F81163AE24 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -453,6 +462,7 @@ buildConfigurationList = 1FF40AA4CFE5087652123EAD /* Build configuration list for PBXNativeTarget "UhooiPicBookTests" */; buildPhases = ( 4FE41A7B35B5E5FAA407F3FA /* Sources */, + 4BBB00242AC9A172002C12E2 /* Frameworks */, ); buildRules = ( ); @@ -460,6 +470,9 @@ 4DAF6BC74EE9AEF3E06A50D2 /* PBXTargetDependency */, ); name = UhooiPicBookTests; + packageProductDependencies = ( + 4BBB00262AC9A1BA002C12E2 /* Testing */, + ); productName = UhooiPicBookTests; productReference = BA21C3023C46CC6151A43886 /* UhooiPicBookTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -575,6 +588,7 @@ ); mainGroup = 47C552D3546C641AB89783C1; packageReferences = ( + 4BBB00252AC9A1A3002C12E2 /* XCRemoteSwiftPackageReference "swift-testing" */, ); projectDirPath = ""; projectRoot = ""; @@ -1334,7 +1348,23 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + 4BBB00252AC9A1A3002C12E2 /* XCRemoteSwiftPackageReference "swift-testing" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-testing"; + requirement = { + branch = main; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + /* Begin XCSwiftPackageProductDependency section */ + 4BBB00262AC9A1BA002C12E2 /* Testing */ = { + isa = XCSwiftPackageProductDependency; + package = 4BBB00252AC9A1A3002C12E2 /* XCRemoteSwiftPackageReference "swift-testing" */; + productName = Testing; + }; 791904C92793F9CB00416F7D /* ImageLoader */ = { isa = XCSwiftPackageProductDependency; productName = ImageLoader; From 2fe247778114ecc59775ddf0a44a6d90e674ebb7 Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 1 Oct 2023 22:11:05 +0900 Subject: [PATCH 13/17] Fix deprecated API --- .../Extensions/Foundation/BundleStringTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift b/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift index 0c813061..1abff890 100644 --- a/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift +++ b/App/UhooiPicBookTests/Extensions/Foundation/BundleStringTests.swift @@ -26,7 +26,7 @@ struct BundleStringTests { return } - let expected = switch Locale(identifier: language).languageCode { + let expected = switch Locale(identifier: language).language.languageCode?.identifier { case "en": "UhooiPicBook" default: "ウホーイ図鑑" } From 998f6d583090308effbb00b28f0986debc81d97a Mon Sep 17 00:00:00 2001 From: uhooi Date: Mon, 2 Oct 2023 00:16:00 +0900 Subject: [PATCH 14/17] Refactor UhooiPicBookUITests --- App/Develop.xcodeproj/project.pbxproj | 22 ++++++++++++++++++ .../Pages/ActivityPage.swift | 11 ++++----- .../Pages/ImagePopupPage.swift | 11 ++++----- .../Pages/MonsterDetailPage.swift | 23 +++++++++---------- .../Pages/MonsterListPage.swift | 18 ++++++--------- App/UhooiPicBookUITests/Scaffolding.swift | 15 ++++++++++++ .../TestCases/UhooiPicBookUITests.swift | 22 ++++-------------- 7 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 App/UhooiPicBookUITests/Scaffolding.swift diff --git a/App/Develop.xcodeproj/project.pbxproj b/App/Develop.xcodeproj/project.pbxproj index 4abb1579..c932d2ea 100644 --- a/App/Develop.xcodeproj/project.pbxproj +++ b/App/Develop.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 3784E43C6F9862BB2E871B15 /* UhooiPicBookWidgetsConfigurableIntent.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D3A28FF132F9DB6448EAC23F /* UhooiPicBookWidgetsConfigurableIntent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3ED6158022DE90CA4AA73905 /* ImagePopupPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C5239C3163F47164ECE33E8 /* ImagePopupPage.swift */; }; 478286982E492B33E65E682B /* ActivityPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1BC591FA4C18A058784472F /* ActivityPage.swift */; }; + 4B0CB3952AC9C2DC0025FA52 /* Testing in Frameworks */ = {isa = PBXBuildFile; productRef = 4B0CB3942AC9C2DC0025FA52 /* Testing */; }; + 4B0CB3972AC9C30E0025FA52 /* Scaffolding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CB3962AC9C30E0025FA52 /* Scaffolding.swift */; }; 4BBA93DC2AC9440300C022FD /* Scaffolding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBA93DB2AC9440300C022FD /* Scaffolding.swift */; }; 4BBB00272AC9A1BA002C12E2 /* Testing in Frameworks */ = {isa = PBXBuildFile; productRef = 4BBB00262AC9A1BA002C12E2 /* Testing */; }; 5022F0F1F72B5341C9486B7A /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */; }; @@ -114,6 +116,7 @@ 33B49E10FB3AFB3745B0AEF4 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 3678749154206AA2C7DE69F6 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 39F4CD1686D945CFB87141CE /* GoogleUtilities.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleUtilities.xcframework; path = Frameworks/Firebase/FirebaseAnalytics/GoogleUtilities.xcframework; sourceTree = ""; }; + 4B0CB3962AC9C30E0025FA52 /* Scaffolding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scaffolding.swift; sourceTree = ""; }; 4BBA93DB2AC9440300C022FD /* Scaffolding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scaffolding.swift; sourceTree = ""; }; 541427EC2F900D49CD247CB2 /* XCUIElement+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUIElement+Ex.swift"; sourceTree = ""; }; 5FC40872E7A32ADB0B8AE3D7 /* FirebaseFirestore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseFirestore.xcframework; path = Frameworks/Firebase/FirebaseFirestore/FirebaseFirestore.xcframework; sourceTree = ""; }; @@ -172,6 +175,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 4B0CB3932AC9C2D50025FA52 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B0CB3952AC9C2DC0025FA52 /* Testing in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BBB00242AC9A172002C12E2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -401,6 +412,7 @@ 541427EC2F900D49CD247CB2 /* XCUIElement+Ex.swift */, EB9FF08BDED117C228729B0B /* Pages */, 9D14FEE7DAB67CCFD61B333D /* TestCases */, + 4B0CB3962AC9C30E0025FA52 /* Scaffolding.swift */, ); path = UhooiPicBookUITests; sourceTree = ""; @@ -482,6 +494,7 @@ buildConfigurationList = 5336812240FABFFCD289F94B /* Build configuration list for PBXNativeTarget "UhooiPicBookUITests" */; buildPhases = ( 22070DEEFB8F99971EC40231 /* Sources */, + 4B0CB3932AC9C2D50025FA52 /* Frameworks */, ); buildRules = ( ); @@ -489,6 +502,9 @@ BB72275143FEBC036B69BC5C /* PBXTargetDependency */, ); name = UhooiPicBookUITests; + packageProductDependencies = ( + 4B0CB3942AC9C2DC0025FA52 /* Testing */, + ); productName = UhooiPicBookUITests; productReference = 83C280827AC1AC8CDC771EC4 /* UhooiPicBookUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -762,6 +778,7 @@ 3ED6158022DE90CA4AA73905 /* ImagePopupPage.swift in Sources */, 7B7002A645C43EBB624D82D8 /* MonsterDetailPage.swift in Sources */, 522896F9FC51ED2221060387 /* MonsterListPage.swift in Sources */, + 4B0CB3972AC9C30E0025FA52 /* Scaffolding.swift in Sources */, ED23EF346F55E2E02F461F16 /* PageProtocol.swift in Sources */, 2AB9187FB6C6F195BDFA0AEA /* UhooiPicBookUITests.swift in Sources */, A1713DA74A4AE73B34351622 /* XCUIElement+Ex.swift in Sources */, @@ -1360,6 +1377,11 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 4B0CB3942AC9C2DC0025FA52 /* Testing */ = { + isa = XCSwiftPackageProductDependency; + package = 4BBB00252AC9A1A3002C12E2 /* XCRemoteSwiftPackageReference "swift-testing" */; + productName = Testing; + }; 4BBB00262AC9A1BA002C12E2 /* Testing */ = { isa = XCSwiftPackageProductDependency; package = 4BBB00252AC9A1A3002C12E2 /* XCRemoteSwiftPackageReference "swift-testing" */; diff --git a/App/UhooiPicBookUITests/Pages/ActivityPage.swift b/App/UhooiPicBookUITests/Pages/ActivityPage.swift index 17ccd111..7c0dfb9e 100644 --- a/App/UhooiPicBookUITests/Pages/ActivityPage.swift +++ b/App/UhooiPicBookUITests/Pages/ActivityPage.swift @@ -15,14 +15,14 @@ final class ActivityPage: Page { // MARK: Computed Instance Properties - private var view: XCUIElement { self.app.navigationBars["UIActivityContentView"] } - private var closeButton: XCUIElement { self.view.buttons["Close"] } + private var view: XCUIElement { app.navigationBars["UIActivityContentView"] } + private var closeButton: XCUIElement { view.buttons["Close"] } // MARK: Initializers init(app: XCUIApplication, timeout: TimeInterval) { self.app = app - guard self.view.waitForExistence(timeout: timeout) else { + guard view.waitForExistence(timeout: timeout) else { fatalError("Fail to load ActivityPage.") } } @@ -30,8 +30,7 @@ final class ActivityPage: Page { // MARK: Other Internal Methods func tapCloseButton() -> MonsterDetailPage { - self.closeButton.tap() - return MonsterDetailPage(app: self.app, timeout: 1.0) + closeButton.tap() + return MonsterDetailPage(app: app, timeout: 1.0) } - } diff --git a/App/UhooiPicBookUITests/Pages/ImagePopupPage.swift b/App/UhooiPicBookUITests/Pages/ImagePopupPage.swift index e1fae831..a7329240 100644 --- a/App/UhooiPicBookUITests/Pages/ImagePopupPage.swift +++ b/App/UhooiPicBookUITests/Pages/ImagePopupPage.swift @@ -15,14 +15,14 @@ final class ImagePopupPage: Page { // MARK: Computed Instance Properties - private var view: XCUIElement { self.app.otherElements["imagePopup"] } - private var closeButton: XCUIElement { self.view.buttons["imagePopup_close_button"] } + private var view: XCUIElement { app.otherElements["imagePopup"] } + private var closeButton: XCUIElement { view.buttons["imagePopup_close_button"] } // MARK: Initializers init(app: XCUIApplication, timeout: TimeInterval) { self.app = app - guard self.view.waitForExistence(timeout: timeout) else { + guard view.waitForExistence(timeout: timeout) else { fatalError("Fail to load ImagePopupPage.") } } @@ -30,8 +30,7 @@ final class ImagePopupPage: Page { // MARK: Other Internal Methods func tapCloseButton() -> MonsterDetailPage { - self.closeButton.tap() - return MonsterDetailPage(app: self.app, timeout: 1.0) + closeButton.tap() + return MonsterDetailPage(app: app, timeout: 1.0) } - } diff --git a/App/UhooiPicBookUITests/Pages/MonsterDetailPage.swift b/App/UhooiPicBookUITests/Pages/MonsterDetailPage.swift index 3b10dd11..ad87908a 100644 --- a/App/UhooiPicBookUITests/Pages/MonsterDetailPage.swift +++ b/App/UhooiPicBookUITests/Pages/MonsterDetailPage.swift @@ -15,16 +15,16 @@ final class MonsterDetailPage: Page { // MARK: Computed Instance Properties - private var view: XCUIElement { self.app.otherElements["monsterDetail"] } - private var dancingImage: XCUIElement { self.view.images["monsterDetail_dancing_image"] } - private var backButton: XCUIElement { self.app.navigationBars["UhooiPicBook.MonsterDetailView"].buttons["Back"] } - private var shareButton: XCUIElement { self.app.navigationBars["UhooiPicBook.MonsterDetailView"].buttons["Share"] } + private var view: XCUIElement { app.otherElements["monsterDetail"] } + private var dancingImage: XCUIElement { view.images["monsterDetail_dancing_image"] } + private var backButton: XCUIElement { app.navigationBars["UhooiPicBook.MonsterDetailView"].buttons["Back"] } + private var shareButton: XCUIElement { app.navigationBars["UhooiPicBook.MonsterDetailView"].buttons["Share"] } // MARK: Initializers init(app: XCUIApplication, timeout: TimeInterval) { self.app = app - guard self.view.waitForExistence(timeout: timeout) else { + guard view.waitForExistence(timeout: timeout) else { fatalError("Fail to load MonsterDetailPage.") } } @@ -32,18 +32,17 @@ final class MonsterDetailPage: Page { // MARK: Other Internal Methods func tapDancingImage() -> ImagePopupPage { - self.dancingImage.tap() - return ImagePopupPage(app: self.app, timeout: 1.0) + dancingImage.tap() + return ImagePopupPage(app: app, timeout: 1.0) } func tapBackButton() -> MonsterListPage { - self.backButton.tap() - return MonsterListPage(app: self.app, timeout: 1.0) + backButton.tap() + return MonsterListPage(app: app, timeout: 1.0) } func tapShareButton() -> ActivityPage { - self.shareButton.tap() - return ActivityPage(app: self.app, timeout: 1.0) + shareButton.tap() + return ActivityPage(app: app, timeout: 1.0) } - } diff --git a/App/UhooiPicBookUITests/Pages/MonsterListPage.swift b/App/UhooiPicBookUITests/Pages/MonsterListPage.swift index b07d52b7..5d685c4f 100644 --- a/App/UhooiPicBookUITests/Pages/MonsterListPage.swift +++ b/App/UhooiPicBookUITests/Pages/MonsterListPage.swift @@ -15,14 +15,14 @@ final class MonsterListPage: Page { // MARK: Computed Instance Properties - private var view: XCUIElement { self.app.otherElements["monsterList"] } - private var monstersCollectionViewFirstCell: XCUIElement { self.view.collectionViews.cells.element(boundBy: 0) } + private var view: XCUIElement { app.otherElements["monsterList"] } + private var monstersCollectionViewFirstCell: XCUIElement { view.collectionViews.cells.element(boundBy: 0) } // MARK: Initializers init(app: XCUIApplication, timeout: TimeInterval) { self.app = app - guard self.view.waitForExistence(timeout: timeout) else { + guard view.waitForExistence(timeout: timeout) else { fatalError("Fail to load MonsterListPage.") } } @@ -30,21 +30,17 @@ final class MonsterListPage: Page { // MARK: Other Internal Methods func swipeUpMonstersCollectionViewFirstCell() -> MonsterListPage { - self.monstersCollectionViewFirstCell.swipeUp() + monstersCollectionViewFirstCell.swipeUp() return self } func swipeDownMonstersCollectionViewFirstCell() -> MonsterListPage { - self.monstersCollectionViewFirstCell.swipeDown() + monstersCollectionViewFirstCell.swipeDown() return self } func tapMonstersCollectionViewFirstCell() -> MonsterDetailPage { - self.monstersCollectionViewFirstCell.tap() - return MonsterDetailPage(app: self.app, timeout: 1.0) + monstersCollectionViewFirstCell.tap() + return MonsterDetailPage(app: app, timeout: 1.0) } - - // MARK: Other Private Methods - } - diff --git a/App/UhooiPicBookUITests/Scaffolding.swift b/App/UhooiPicBookUITests/Scaffolding.swift new file mode 100644 index 00000000..b0faa3c7 --- /dev/null +++ b/App/UhooiPicBookUITests/Scaffolding.swift @@ -0,0 +1,15 @@ +// +// Scaffolding.swift +// UhooiPicBookUITests +// +// Created by uhooi on 2023/10/02. +// + +import XCTest +import Testing + +final class AllTests: XCTestCase { + func testAll() async { + await XCTestScaffold.runAllTests(hostedBy: self) + } +} diff --git a/App/UhooiPicBookUITests/TestCases/UhooiPicBookUITests.swift b/App/UhooiPicBookUITests/TestCases/UhooiPicBookUITests.swift index 87880d57..31e6703e 100644 --- a/App/UhooiPicBookUITests/TestCases/UhooiPicBookUITests.swift +++ b/App/UhooiPicBookUITests/TestCases/UhooiPicBookUITests.swift @@ -7,27 +7,14 @@ // import XCTest +import Testing -final class UhooiPicBookUITests: XCTestCase { +struct UhooiPicBookUITests { - // MARK: TestCase Life-Cycle Methods - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - // MARK: - Test Methods - func test_normal() { + @Test + func normal() { let app = XCUIApplication() app.launch() @@ -54,5 +41,4 @@ final class UhooiPicBookUITests: XCTestCase { monsterListPage = monsterDetailPage .tapBackButton() } - } From ec71c58e965ce1efa95cdec3837d51c5b3d5521d Mon Sep 17 00:00:00 2001 From: uhooi Date: Mon, 2 Oct 2023 00:17:57 +0900 Subject: [PATCH 15/17] Add skipPackagePluginValidation flag to test-debug --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index c140244c..50cd9e5f 100644 --- a/Makefile +++ b/Makefile @@ -142,6 +142,7 @@ xcodebuild \ -testPlan '${TEST_PLAN_NAME}' \ -skip-testing:${UI_TESTS_TARGET_NAME} \ -clonedSourcePackagesDirPath './SourcePackages' \ +-skipPackagePluginValidation \ -resultBundlePath '${REPORTS_PATH}/${XCRESULT_NAME}.xcresult' \ clean test \ 2>&1 \ From 26af03600cdf21ec1f42d844e88dcb5693f88679 Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 21 Apr 2024 23:40:24 +0900 Subject: [PATCH 16/17] Use swift-testing 0.7.0 --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 9c97a02b..23b704c6 100644 --- a/Package.swift +++ b/Package.swift @@ -79,7 +79,7 @@ let package = Package( .library(name: "ImageLoader", targets: ["ImageLoader"]), // TODO: Remove later ], dependencies: [ - .package(url: "https://github.com/apple/swift-testing.git", branch: "main"), // TODO: Use stable + .package(url: "https://github.com/apple/swift-testing.git", from: "0.7.0"), ], targets: [ .target( From 922d4a68d4211848751268ab8971476ccec40091 Mon Sep 17 00:00:00 2001 From: uhooi Date: Sun, 21 Apr 2024 23:40:45 +0900 Subject: [PATCH 17/17] Format UserDefaultsClientTests --- .../Temp/UserDefaultsClientTests.swift | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift b/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift index 57080a57..a1f3122b 100644 --- a/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift +++ b/Tests/AppModuleTests/Repository/Temp/UserDefaultsClientTests.swift @@ -12,22 +12,28 @@ import Testing struct UserDefaultsClientTests { // MARK: Stored Instance Properties - + private let userDefaults = UserDefaultsClient.shared - + // MARK: TestCase Life-Cycle Methods - + init() { userDefaults.removeAll() } - + // MARK: - Test Methods - + @Test func monster() { - var uhooiEntity = MonsterEntity(name: "uhooi", description: "uhooi's description\nuhooi", baseColorCode: "#FFFFFF", iconURL: URL(string: "https://theuhooi.com/uhooi")!, dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")!) + var uhooiEntity = MonsterEntity( + name: "uhooi", + description: "uhooi's description\nuhooi", + baseColorCode: "#FFFFFF", + iconURL: URL(string: "https://theuhooi.com/uhooi")!, + dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")! + ) let key = "spotlight_\(uhooiEntity.name)" - + // TODO: Use `XCTContext.runActivity(named:)` . // ref: https://github.com/apple/swift-testing/issues/42 // Unsaved @@ -36,12 +42,18 @@ struct UserDefaultsClientTests { // Add userDefaults.saveMonster(uhooiEntity, forKey: key) #expect(uhooiEntity == userDefaults.monster(key: key)) - + // Update - uhooiEntity = MonsterEntity(name: "uhooi", description: "uhooi's description\nuhooi", baseColorCode: "#000000", iconURL: URL(string: "https://theuhooi.com/uhooi")!, dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")!) + uhooiEntity = MonsterEntity( + name: "uhooi", + description: "uhooi's description\nuhooi", + baseColorCode: "#000000", + iconURL: URL(string: "https://theuhooi.com/uhooi")!, + dancingURL: URL(string: "https://theuhooi.com/uhooi-dancing")! + ) userDefaults.saveMonster(uhooiEntity, forKey: key) #expect(uhooiEntity == userDefaults.monster(key: key)) - + // Remove userDefaults.removeAll() #expect(userDefaults.monster(key: key) == nil)