늘 그렇듯 오랜만에 글을 쓰는듯 하네요
Xcode에서 신규 프로젝트 만들면 자동으로 Unit test도 추가할건지 물어봐서 추가하기도 쉽고,
추가하지 못했어도, 기존 프로젝트에 Unit test 추가하는것도 이전에 했었을때 쉬웠던 기억이 있다. ( 그냥 Target 하나더 추가하는거니까? )
새해 목표중 하나로.. 회사 프로젝트에 Unit Test 추가하여, 조금씩 테스트 코드 작성해보기로 다짐을 했었고, 추가하는 과정이 생각보다 쉽지 않았어가지고, 공유 하려고 글을 작성한다. ( 2-3일동안 붙잡은듯... ㅠ )
기존 프로젝트 상황
앱 말고도, extension으로 추가된 target이 있고, Build Phases에서 script를 사용하고있었음.
프로젝트의 Configurations가 다양하고, Product module name이 Configuration마다 다름.
Objective-c & Swift 혼재됨.
바쁜 분들을 위한 핵심 요약
Xcode 인터페이스에서 Command + U (테스트빌드) 했는데, Test Succeedded는 뜨는데, 실제로 테스트코드는 실행이안된다 ?
그렇다면 Command-Line으로 테스트빌드 해보길!
Build Settings가 잘 맞게 되어있는지 확인.
Add Target
Add a Target해서 Unit Testing Bundle을 추가하면 된다. 매우 쉽다.
Test Build
command + U 를 누르면 테스트 빌드를 하는데, 여기서 부터 문제..
XCode 화면에 Test Succeeded 로 나타나나, 실제 테스트코드가 실행되지 않음. 😡
요렇게 테스트 빌드는 성공했다고 뜨나,
좌측 Test 네비게이션바나, 테스트코드 작성화면에 초록색체크박스 또는 실패했다는 빨간색이 떠야하는데, 안뜸. 저 케이스 하나씩 클릭해도 테스트가 안됌. ( 아래 캡처화면이 정상. )
이때부터 멘붕.
다른 프로젝트 새로 생성해보고 하는데 이상한점이, Test Succeeded 알람뜬거보면 (null) 로 뜬다는점 확인.
빌드세팅도 크게 다를게 없어보였음.
삽질을 하다가... 어쩌다보니 Command-Line도 보게됌.
1. Command-Line 으로 테스트 빌드해보기.
커맨드라인으로도 빌드해볼수가 있는데,
아래 내용참고하여,
https://medium.com/tauk-blog/running-xctests-from-the-command-line-f2e5ce0b4bfd
터미널열어서 아래처럼 실행해보았다.
xcodebuild \
-workspace 프로젝트이름.xcworkspace \
-scheme 스킴이름 \
-destination 'platform=macos,arch=arm64' \
test
터미널에 로그가 쫘르르륵 찍히면서, 마지막에 빌드실패!! 라며 로그를 찍어주셨다. 😌
2. 로그 분석
첫번째 이슈로는, 프로젝트에 앱말고도 extension으로 추가된 target이 있는데, 해당 target을 찾을 수 없다라는 로그였다.
Test target 테스트타겟이름 encountered an error
(The bundle identifier for extension앱.app couldn’t be read. No such file or directory:
프로젝트의 Build phases에서 커스텀 Script를 실행하고있는데, 이 코드내용을 보면, 빌드를 할때, extension target도 빌드하여 바이너리로 생성되면서, 이 바이너리의 위치를 옮기도록 하는 내용이다.
그러므로, 빌드할때 저 스크립트가 실행되면서 바이너리 위치가 변경되니, 테스트빌드할때 필요한 바이너리가 안보이니, 실패라고 뜨는것.
( 도대체 테스트빌드할때 extension target이 왜필요한지는 아직까지 모르겠음. )
솔직히 이런 이슈들을 Xcode 인터페이스에서는 에러처리를 안해줄법하다고도 생각이 들었다. 완전 엣지케이스같으니까? ( 하지만 너무하다. )
암튼, 코드내용을 보나, 최근 os를 보나, 이 스크립트는 인스톨할때만 필요해보여, For install builds only 체크함.
그럼 빌드 행위자체에서는 저 스크립트가 실행이 안되므로, extension target 바이너리의 위치가 옮겨지지 않으니, 이슈가 사라짐.
이제다시 커맨드라인으로 다시 테스트 빌드해봤는데, 또 실패.
두번째 이슈. 이번엔 빌드 돌리는 환경의 아키텍쳐가 없다함.
보아하니, test target - Build settings - Architectures 가보니 excluded Architectures에 arm64가 있음. ( 나는 arm64 아키텍쳐인데 ) 그래서 요걸 없애줌.
세번째 이슈. test target - Build settings - Testing - Test Host 도 중요하다.
Host Application으로 설정한 앱의 바이너리를 사용해야하는데,
이 위치의 이름이 잘맞는지 체크해야한다.
해당 프로젝트는 Configurations가 많다. Alpha, beta, cbt, 등등.....
그래서 해당 Configuration마다 빌드하게끔 해야할테고,
빌드하고 생성된 바이너리의 이름도 다다르게 되어있었음.
이렇게 하나하나 해결해주니, 테스트 빌드 드디어성공!!! 😭
테스트 빌드 성공했으나, 테스트코드에서 프로젝트 import가 안됨. ㅎ 🤪
( 테스트코드를 왜 작성하나 ? 내 프로젝트에서 사용되는 모듈, 로직 등을 테스트하기위함인데, 그러려면 내 프로젝트내의 코드를 사용해야하는데, 그러려면 import를 해줘야하는데.....! )
@testable import 내프로젝트이름
암튼 이게 안된다.
테스트하는 Target ( 내프로젝트 앱) - Builds Settings - enable testability 에 YES로 수정한다.
추가적으로...
위의 Test Host와 비슷한 맥락으로, 해당 프로젝트는 Configurations가 많은데, 그에 따라 Product Module Name이 달랐다.
다르므로, import할때도 다르게 작성해야한다. ( 같으면 상관없었을텐데 ㅠㅠ )
즉 Configration마다 다르게 import해야하는데, 그건 전처리구문으로 가능하다.
아래처럼 전처리구문으로 작성하면된다. ( 프로젝트 코드에서도 동일한 전처리구문을 사용해서 동일하게 작성했다. )
import 성공!
import는 성공했으나... 외부 라이브러리를 찾을수없어서 테스트빌드 실패.😡
프로젝트에서 다양한 외부라이브러리를 사용하고 있다.
테스트코드에서 프로젝트에서 만든 클래스를 사용하려하니, 컴파일에러가 뜨는데, 보아하니, 해당 클래스에서 외부라이브러리를 쓰고있나보다.
하지만 test target에는 외부라이브러리 접근이 없으니, Podfile을 열어서 아래를 수정하여, Pod install 해주었다. ( Cocoapods으로 관리중 )
즉, 프로젝트가 가지는 모든 라이브러리들을 test target도 동일하게 상속받도록 하겠다는 뭐 그런뜻..
target 'TestTarget이름' do
inherit! :complete
end
이제 빌드 성공!!
테스트빌드 성공.. 했으나.. 전처리구문이 실행이안됌 🤬
요건 내가 바보같았다. 전처리구문은 해당 target에만 사용이 되어지는거므로.. 새로 만든 test target에도 Swift 전처리구문을 추가해줘야한다. ( 아니면 상위 PROJECT에 추가해서 앱 target, test target 둘다 동일하게 사용가능하게끔 해도됌 )
앱 target에 전처리구문 에러나는곳이 몇군대있어서, 모든 Configuration 케이스에 맞게 추가해줬다.
이제 테스트 빌드해보니! 정상적으로 됐다!!
아래 코드는 테스트목적으로, 빨간색X가 떠야하는 상황이고, 전처리구문에 맞게 잘 실행됐다. 👍
'Xcode' 카테고리의 다른 글
브렌치 변경시 tuist generate 자동화하기 (2) | 2024.10.20 |
---|---|
오픈소스 기여해보기 (feat Tuist) (2) | 2024.10.19 |
Tuist 마이그레이션 후기 (7) | 2024.10.17 |
Xcode 수동으로 사이닝하여 배포 및 디바이스에서 실행하기 (5) | 2024.10.03 |
static framework에 Assets.catalog - image 사용하기 ? (0) | 2024.09.15 |