개발/Swift

[Tuist] 모듈 생성 과 모듈 내 테스트 타겟 생성

덤벨로퍼 2025. 1. 14. 22:07

모듈을 생성해서 개발할 예정이다

(Tuist edit 한 후)

메인앱 타겟을 보면 여러 디펜던시들이 세팅되어있다

외부 라이브러리를 포함한다

dependencies: [TargetDependency] {
        return [            
            .external(name: "AdFitSDK"),
            .external(name: "AMPopTip"),
            .external(name: "ChannelIOSDK"),
            .external(name: "CocoaLumberjack"),
            .external(name: "CocoaLumberjackSwift"),
						....
						]

여기에 모듈을 만들 project 를 하나 넣어준다

Entity 모듈과 기능모듈을 넣어줬다

.project(target: "MyProfile", path: .relativeToRoot("Projects/MyProfile")),
.project(target: "Entity", path: .relativeToRoot("Projects/Entity")),

그러고 Project 폴더 내부에 위와 같은 폴더를 만들고 Project.swift 생성한다

세팅은 비교적 간단했다

//Entity Project 파일

import TemplatePlugin
import ProjectDescription
import TargetPlugin

let project = Project(
    name: "Entity",
    settings: .librarySettings,
    targets: [
        .target(
            name: "Entity",
            destinations: .iOS,
            product: .staticFramework,
            bundleId: "com.Entity.Entity",
            sources: [
                .glob(.path("Sources/**"))
            ],
            dependencies: [],
            settings: .settings(
                base: [
                    "DEFINES_MODULE": "NO",
                ]
            )
        )
    ]
)

//MyProfile Project 파일

let project = Project(
    name: "MyProfile",
    settings: .librarySettings,
    targets: [
        .target(
            name: "MyProfile",
            destinations: .iOS,
            product: .staticFramework,
            bundleId: "com.MyProfile.MyProfile",
            sources: [
                .glob(.path("Sources/**"))
            ],
            dependencies: [
                .project(target: "Entity", path: .relativeToRoot("Projects/Entity")),
                .external(name: "ComposableArchitecture"),
                .external(name: "RxSwift"),
            ],
       
            settings: .settings(
                base: [
                    "DEFINES_MODULE": "NO",
                ]
            )
        )
    ]
)

product 를 staticFramework로 지정했는데 framework로 하면 런타임에 EXC_BAD_ACCESS 에러가 났다.

원인은 좀 알아봐야겠다.

위에서 또 중요한건 Sources 폴더 만들고 경로 지정해주는것이다.

그리고 필요한 dependencies , 지금 만들 Entity를 의존해야하므로 추가했고

외부 라이브러리 추가했다.

settings는 configutation, info쪽에 들어가는 내용같은데

이미 있는게있어서 사용했다

static let librarySettings: Settings = .settings(
    base: [
        "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER": "NO",
        "DEVELOPMENT_TEAM": "39MSJ7FY3F",
        "EXCLUDED_ARCHS[sdk=iphonesimulator*]": ["x86_64"],
        "IPHONEOS_DEPLOYMENT_TARGET": "15.0",
        "ONLY_ACTIVE_ARCH": "YES",
        "TARGETED_DEVICE_FAMILY": "1",
    ],
    configurations: [
        .debug(name: "AppStore Debug"),
        .release(name: "AppStore Release"),
        .debug(name: "Development Debug"),
        .release(name: "Development Release"),
    ]
)

이러고 tuist generate 하면 모듈이 딱 들어와있었다.

모듈에서 테스트 환경 만들기

개발중에 테스트 코드를 짜려하는데 유닛테스트 코드에 지정할 타겟이 없었다

tuist edit → 아까 만든 Project 파일에 들어가서

let project = Project(
    name: "MyProfile",
    settings: .librarySettings,
    targets: [
        .target(
            name: "MyProfile",
            destinations: .iOS,
            product: .staticFramework,
            bundleId: "com.MyProfile.MyProfile",
            sources: [
                .glob(.path("Sources/**"))
            ],
            dependencies: [
                .project(target: "Entity", path: .relativeToRoot("Projects/Entity")),

                .external(name: "ComposableArchitecture"),
                .external(name: "RxSwift"),
            ],
       
            settings: .settings(
                base: [
                    "DEFINES_MODULE": "NO",
                ]
            )
        ),
        .target(
            name: "MyProfileTests",
            destinations: .iOS,
            product: .unitTests,
            bundleId: "com.MyProfile.MyProfileTests",
            sources: [
                .glob(.path("Tests/**"))
            ],
            dependencies: [
                .target(name: "MyProfile")
            ],
       
            settings: .settings(
                base: [
                    "DEFINES_MODULE": "NO",
                ]
            )
        )
    ]
)

target 하나 더 추가, unitTest 타입으로 만들고

source, dependencies 세팅했다.

그러고 프로젝트 내부에 Tests폴더 생성하고

generate 해보니 타겟이 생성되었다.

 

Tests 폴더 안에 테스트 코드 넣고 타겟 멤버쉽 을 test 로 설정


그리고 테스트 필요한 함수는 public 으로 지정되어야 사용 가능했다

같은 모듈이어도 타겟 다르니 internal 접근이 안되었다.