본문 바로가기
Xcode

기존 프로젝트에 Unit Test 추가하기

by vapor3965 2024. 2. 8.

목차

     

    늘 그렇듯 오랜만에 글을 쓰는듯 하네요 

     

    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

     

    Running XCTests from the Command Line

    Update: We’ve created a Discord server for discussing all things related to automation testing! Join our community today 👋:

    medium.com

     

    터미널열어서 아래처럼 실행해보았다. 

    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가 떠야하는 상황이고, 전처리구문에 맞게 잘 실행됐다. 👍

     

     

     

    댓글