그래오늘은이거야

iOS fastlane snapshot (object-c/Swift) TestUI 배포 스크린샷 및 테스트 SnapshotHelper.swift 설정및사용방법 본문

세상 개발/IOS(Swift)

iOS fastlane snapshot (object-c/Swift) TestUI 배포 스크린샷 및 테스트 SnapshotHelper.swift 설정및사용방법

jinhongstar 2020. 6. 18. 15:56
728x90
반응형

안녕하세요 Leo 입니다. 

 

이번에 쿠팡 / 카카오 / 네이버 / 우아한형제들 에서  사용하는 fastlane snapshot 셋팅에 대하여 작성해 보려합니다.

 

IOS 개발자 쿠팡면접 준비를 앞서 쿠팡에서 UITest 배포를 사용해 본적 있냐해서 한번해봐야지 했다가 1-3일정도 머리 박고 나중에 사용하려고 블로그에 직접 작성했습니다.

 

stackoverflow 와 해외사이트 구글 및 한국 사이트 들 처럼 개발 해보려고 하니 제대로 구동 방식을 한글로 쉽게 번역하거나 테스트에 관한 글이 없어서 직접 작성하였습니다.

 

1. 연관관계 

 

- object-c 로 코딩 / swift 로 프로젝트 코딩 과 TestUI 는 전혀 상관없다.

그냥 개발언어와 TestUI 쪽은 상관없습니다.

 

fastlane snapshot을 실행하면 무조건 swift 파일이 만들어집니다. 그냥 swift 로진행하면됩니다.

 

fastlane snapshot를 하기 전에 UITest 를 만들어 줍니다.

 

 

File-New-Target - UI Testing Bundle 

또는

 

프로젝트 명 Target 에 "+" 버튼을 눌러주면됩니다.

 

 

Language 는 Swift 를 권장 합니다.

 

UITest 를 만들고 아래와 같이 설치를 합니다.

 

 

fastlane snapshot은 별도의 프로그램입니다 Xcode 실행을 터미널에서 하는 용도라고 생각 하면 됩니다.

 

터미널을 실행 시킨 후 .

xcode-select --install
sudo gem install fastlane

 

설치를 한 후

 

⭐️ 중요합니다 해당 디렉토리 (프로젝트 명 디렉토리로 이동 후) Pod 파일 만들때와 동일한 위치 에서 

 

fastlane snapshot init

실행 하면 Pods 파일과 같은 위치에 파일이 2개 생성됩니다.

 

Snapfile / SnapshotHelper.swift

Snapfiel / SnapshotHelper.swift 가 생성 됩니다.

 

그리고 터미널 log 에 이렇게 나오죠 천천히 따라하시면 됩니다.

[✔] 🚀 
✅  Successfully created SnapshotHelper.swift './SnapshotHelper.swift'
✅  Successfully created new Snapfile at './Snapfile'
-------------------------------------------------------
Open your Xcode project and make sure to do the following:
1) Add a new UI Test target to your project
2) Add the ./fastlane/SnapshotHelper.swift to your UI Test target
   You can move the file anywhere you want
3) Call `setupSnapshot(app)` when launching your app

  let app = XCUIApplication()
  setupSnapshot(app)
  app.launch()

4) Add `snapshot("0Launch")` to wherever you want to trigger screenshots
5) Add a new Xcode scheme for the newly created UITest target
6) Add a Check to enable the `Shared` box of the newly created scheme

 

 

여기서 다시한번 설명드리지만 object-c/swift 로 개발했던 아무 상관없습니다. (저는 이부분이 제일 헷갈렸 습니다.)

 

Snapfile 을 열어서 환경 셋팅 해줍니다.

# Uncomment the lines below you want to change by removing the # in the beginning

# A list of devices you want to take the screenshots from
 devices([
   "iPhone 8",
   "iPhone 8 Plus",
   "iPhone SE (2nd generation)",
   "iPhone 11",
   "iPhone 11 Pro",
   "iPhone 11 Pro Max"
#   "iPad Pro (12.9-inch)",
#   "iPad Pro (9.7-inch)",
#   "Apple TV 1080p"
 ])

 languages([
   "en-US",
   "ko-KR",
   "de-DE"
#   "it-IT",
#   ["pt", "pt_BR"] # Portuguese with Brazilian locale
 ])

# The name of the scheme which contains the UI Tests
# scheme("SchemeName")

# Where should the resulting screenshots be stored?
# output_directory("./screenshots")

# remove the '#' to clear all previously generated screenshots before creating new ones
# clear_previous_screenshots(true)

# Remove the '#' to set the status bar to 9:41 AM, and show full battery and reception.
# override_status_bar(true)

# Arguments to pass to the app on launch. See https://docs.fastlane.tools/actions/snapshot/#launch-arguments
# launch_arguments(["-favColor red"])

# For more information about all available options run
# fastlane action snapshot

이런식으로 #을 제외하고 특정 디바이스만 스크린샷을 남길수 있고 저는 아래와 같은 셋팅을 추천합니다.

# Uncomment the lines below you want to change by removing the # in the beginning

# A list of devices you want to take the screenshots from
# devices([
#   "iPhone 8",
#   "iPhone 8 Plus",
#   "iPhone SE (2nd generation)",
#   "iPhone 11",
#   "iPhone 11 Pro",
#   "iPhone 11 Pro Max"
#   "iPad Pro (12.9-inch)",
#   "iPad Pro (9.7-inch)",
#   "Apple TV 1080p"
# ])

 languages([
   "en-US",
   "ko-KR",
   "de-DE"
#   "it-IT",
#   ["pt", "pt_BR"] # Portuguese with Brazilian locale
 ])

# The name of the scheme which contains the UI Tests
# scheme("SchemeName")

# Where should the resulting screenshots be stored?
# output_directory("./screenshots")

# remove the '#' to clear all previously generated screenshots before creating new ones
# clear_previous_screenshots(true)

# Remove the '#' to set the status bar to 9:41 AM, and show full battery and reception.
# override_status_bar(true)

# Arguments to pass to the app on launch. See https://docs.fastlane.tools/actions/snapshot/#launch-arguments
# launch_arguments(["-favColor red"])

# For more information about all available options run
# fastlane action snapshot

이런식으로 기본 셋팅만 하면 알아서 스크린샷을 남깁니다.

 

설정을 다 맞친 후 생성된된 SnapshotHelper.swift 를 드래그앤드롭 (Drag&Drop)으로 생성한 UITests 폴더 안으로 넣어 줍니다.

 

 

이렇게 하면 기본환경셋팅 끝

 

FastlaneTestUITests.swif 파일에

//
//  FastlaneTestUITests.swift
//  FastlaneTestUITests
//
//  Created by jinhong.park on 2020/06/18.
//  Copyright © 2020 jinhong.park. All rights reserved.
//

import XCTest

class FastlaneTestUITests: XCTestCase {
    override func setUp() {
        continueAfterFailure = false
        let app = XCUIApplication()
        setupSnapshot(app)
        app.launch()
        
    }

    
    func testScreenshots() {
        
                
    // 스크린샷을 찍은snapshot() 함수를 호출합니다
        
        
        let webViewsQuery = XCUIApplication().webViews.webViews.webViews
        snapshot("0Launch")
        
        webViewsQuery.staticTexts["Tour"].tap()
        snapshot("1Main")
                        
     
            
    
    }

 
    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.
    }

    func testExample() throws {
        // UI tests must launch the application that they test.
        let app = XCUIApplication()
        app.launch()

        // Use recording to get started writing UI tests.
                // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

    func testLaunchPerformance() throws {
        if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
            // This measures how long it takes to launch your application.
            measure(metrics: [XCTOSSignpostMetric.applicationLaunch]) {
                XCUIApplication().launch()
            }
        }
    }
}

 

소스를 이렇게 수정 한후 테스트를 해 볼 수 있습니다.

//첫 시작은 버튼 클릭이 없으니 첫 기동 launcher 화면이 main화면이 촬영될 것이고

snapshot("저장텍스트명AAAA")

이벤트 탭이후 스크린샷 찍어라 소스 작성 후 

snapshot("저장텍스트명BBBB")

이런식으로 여러장의 스크린샷을 동시에 찍을 수 있습니다.

 

이벤트를 거는 방법은 아래와 같습니다.

 

시뮬레이터 디바이스를 일단 기본으로 맞춰놓고

 

상단에 플레이 버튼을 누르면 testScreenshots 가 실행되면서 자동으로 촬영이 되는지 확인 할 수있습니다.

그리고 나서 하단에 녹화버튼 을 누르면 촬영이 자동으로 한바퀴 돌면서 스크린샷 폴더에 지정한 시뮬레이터 디바이스 아이폰8의 스크린샷이 저장되는 것이 보일겁니다.

그리고 나서 녹화버튼을 눌러서 시뮬레이터에서 마우스로 클릭하면 자동으로 클릭이벤트 소스가 생성 됩니다.

ex) staticTexts["Tour"].tap() 

그다음 snapshot("지정할이름") 하면 알아서 스크린샷 이 찍힐 겁니다.

테스트가 끝났으면

이제 아래와 같이 터미널 명령어를 실행하면 각각의 디바이스별 스크린샷이 별도로 촬영되어 

fastlane snapshot

 

Sanpfile 내부에 설정되어있는

# output_directory("./screenshots")

 

프로젝트명 / screenshots 에 이미지가 저장되어있을 겁니다.

 

성공 했다면 터미널에 성공 적인 하트가 보일 겁니다.

 

그리고 해당 스크린샷 폴더에도 이미지가 저장되어 있을 것 입니다.

 

 

반응형
Comments