Cordova – hybrid app 만들기 위한 프레임워크

  • CORDOVA
    • Apache 재단에서 지원중인 하이브리드 앱 제작을 위한 프레임워크다.
    • https://cordova.apache.org/docs/en/6.x/guide/overview/index.html  참조
    • Cordova 프로젝트를 기반으로 진행되고 있는 프로젝트들
      • PhoneGap : 폰갭은 코르도바를 폰갭 콘트롤러로 패키징했는데, 기본 코르도바 플러그인들과 추가적인 폰갭 플로그인들을 이용해서 모바일 디바이스용 웹 페이지를 만들어 하이브리드 앱을 개발할 수 있는 프레임워크이다.
        링크된 페이지에서 설치부터 앱 작성, 빌드하는 과정 등이 상세히 설명되어 있음.
      • Ionic : Angular.js를 사용하여 모바일 디바이스용 웹 페이지를 좀 더 쉽게 만들 수 있게 해준다는 점이 코르도바나 PhoneGap과 다름
      • Monaca : PhoneGap/Coredova와 함께 html5 하이브리드 앱을 쉽게 개발할 수 있게 해줌
    • 사전 설치
      • node 설치
      • cordova cli 설치
        • npm install -g cordova
        • 업데이트
          • npm update -g cordova
      • 앱 템플릿 생성
        • cordova platform add android –save
        • cd hello
      • add platforms( 플랫폼 데이타를 추가해 준다)
        • cordova platform add ios –save
        • cordova platform add android –save
        • cordova platform ls : 현재 set이 어떤 플랫폼에 대한 셋인지 체크한다.
        • 플랫폼 업데이트
          • cordova platform update android –save
          • cordova platform update ios –save
      •  앱을 빌드
        • 빌드하기 위해서 SDK가 설치되어 있어야 함
        • SDK 설치되었는지 확인하는 방법
          • cordova requirements
        • cordova build android
      • 에뮬레이터 실행
        • cordova emulate android
        • 혹은 원하는 에뮬레이터 실행해 놓는다.
      • 앱 실행
        • cordova run android
      • IDE(Xcode, android, eclipse 등으로 앱을 불러와서 www 폴더 아래에서 앱을 수정할 수 있다)
      • 플러그인 추가
        • 설치할 플러그인 검색
          • cordova plugin search camera
            browser가 열리며 camera를 이름에 포함하는 모든 plugin을 표시해 준다. 각 plugin은 이름과 함께 어떤 플랫폼에서 지원되는지 나타내준다.
        • 플러그인 설치
          • cordova plugin add cordova-plugin-camera
            플러그인을 설치하면 app/platforms/android/res/xml/config.xml에 설치된 플러그인에 대한 feature 를 추가해 준다.
        • 플러그인 제거
          • cordova plugin remove cordova-plugin-camera
        • 설치된 플러그인 검색
          • cordova plugin ls
      • plugin 소개
      • 그 밖에 디버깅 툴 소개
        • weinre : WebView를 위한 리모트 디버깅이 지원되지 않는 경우 리모트에서 디버깅해줄 수 있도록 한다.
      • Core Plugin API 사용
      • app을 위한 템플릿 사용하기
        • npm package
          • cordova create hello com.example.hello HelloWorld –template <npm-package-name>

        • git repository
          • cordova create hello com.example.hello HelloWorld –template <git-remote-url>

        • local
          • cordova create hello com.example.hello HelloWorld –template <path-to-template>

      • 데이터 저장
      • security guide
  • 테스트 샘플
광고

Android – constraintlayout, hybrid app(browser type)

  • constraintlayout
    • 안드로이드 스튜디오가 버전 2.3이 되면서 Activity의 기본 layout으로 설정됨
      (API 9(Android 2.3)이상 Android Studio 2.3이상에서만 동작함)
    • 화면 구성요소간 구성요소와 화면간의 제약사항을 정해 layout을 정하게 한다.(iOS의 autolayout와 유사하다)
    • 안드로이드 스튜디오에서 제공하는 UI로 조정하기 어렵다. 차라리 코드로 치는게 난 듯하다.
    • 안드로이드 스튜디오에서 제공하는 UI를 사용하여
      • 구성 요소들을 여러개 선택하여 선택된 구성요소간의 정렬을 지정할 수도 있고
      • 구성 요소를 선택하면 선택된 구성요소 사면의 각면 가운데에 점이 생기는데 그 점과 다른 구성요소를 연결하여 구성요소간 간격 속성을 설정할 수도 있다.
  • hybrid app
    • 웹앱과 네이티브 앱이 합쳐진 형태이다. 네이티브 앱은 각 OS에서 제공하는 SDK를 가지고 만든 앱을 말한다.  웹앱의 형태로 만들어져서 네이티브 앱처럼 설치형 앱으로 사용된다.
    • 각 OS별로 WebView 기능을 지원하고 있어 html, css, javascript등을 이용한 코드는 WebView를 통해 동작하게 하고 네이티브 기능을 함께 사용하도록 하고 앱으로 빌드하기 위한 frameworkwork이 필요하다.
      • 폰갭(코르도바)은 각 OS에 대한 네이티브 기능을 사용하도록 한 것으로 WebView와 Native 코드가 통신하는 방법을 정의한다. 각 OS별로 통신 규격이 다르다. (라이브러리 형태로, 이클립스나 개발 툴을 통해 라이브러리 다운로드 받아 사용)
      • 앱스프레소 또한 멀티 디바이스(iOS, Android)의 hybrid app 을 개발할 수 있도록 하는 개발 프레임워크이다. 앱스프레소는 UI 템플릿을 제공한다. 이 프레임워크에는 Sencha Touch, JQuery Touch, JO 등의 템플릿을 제공하고 있다. 웹 앱을 개발하다가 네이티브 코드를 호출하여 사용하는 방식이다. (에디터 형태로 제공됨, sencha touch 등을 위한 라이브러리는 따로 받아야 함)
      • 앱셀러레이터 티타늄, 리액트 네이티브 : JavaScript로 Native 모바일 앱을 만드는 크로스 플랫폼 프레임워크

iOS 1 – tabview, autolayout

  • autolayout
    • UI 요소의 크기와 위치가 아닌 그것에 대한 제약사항을 넣어서 파편화 문제를 해결하려 함
    • constraint 추가 방법
      • align : UI 요소의 전체 뷰에 대한 align(가로 중간, 세로 중간) 제약 사항이나 다른 UI요소와의 정렬에 대한 제약 사항 정의
      • pin : UI 요소의 전체 뷰에 대한 공간적 길이(상단 x, 왼쪽 y, 위 z, 아래 w) 제약 사항이나 다른 UI 요소와의 공간적 길이에 대한 제약 사항 정의
    • 사용 방법
      • 제약 설정하려는 기준이 되는 UI요소인 경우, 설정하려는 UI요소 클릭하여 선택하고 View 아래 오른쪽 화면에 Align이나 Add New Constraints 아이콘 클릭하여 데이타 입력
      • 첫번째 요소가 아닌 경우, 제약 설정하려는 기준이 되는 UI 요소 클릭하고 키보드의 Ctrl 버튼 누르고 기준을 삼은 UI요소 쪽으로 드래그 하여 이동하면 기준을 삼은 UI요소가 회색으로 선택되면 드래그와 Ctrl 버튼 클릭 해제한다. 그러면 팝업이 떠서 constraint 설정할 수 있게 나옴(기준이 되는 UI는 전체 뷰가 될 수도 있음)
    • 예제 작성
      • Tab을 세 개 가짐 => tabbed application + 1 View Controller
      • 각 탭마다 이미지와 이미지 아래 이름과 이미지에 대한 정보가 표시됨
      • 각 탭 별로 이미지를 기준, 이미지는 수평 가운데 위치, 이미지 아래 8 pixel 아래 이름 텍스트 표시, 그 아래 8 pixel 아래 정보 텍스트 표시
    • App github

Appium 사용기 – IOS swift app UI 테스트

Android 앱에 대한 Appium 사용기는 많으나 iOS에 대한 내용이 없는 거 같아 사용기를 적어 보았다

Appium 개요 및 배경

Appium은 모바일 애플리케이션의 테스트 자동화를 가능하게 해주는 오픈소스 프레임워크이다. native, hybrid, mobile web 등 모든 타입의 모바일 애플리케이션의 테스트 자동화를 가능하게 해준다. 자동화된 테스트는 실제 디바이스나 에뮬레이터, 혹은 시뮬레이터에서 실행될 수 있다.

오늘날 대부분의 모바일 앱은 iOS, Android 두 가지 플랫폼 기반으로 작성되고 있다. 같은 기능의 앱일지라도 서로 다른 플랫폼을 기반으로 작성되고 실행되어야 하기 때문에 유지보수 비용이 두 배로 증가한다. 이러한 환경에서 Appium은 하나의 테스트 코드로 서로 다른 플랫폼(Android, iOS, Windows, FirefoxOS)의 앱을 테스트할 수 있도록 하여 제품 유지보수의 비용을 줄여준다.

이것이 가능한 이유는 아래 그림에서 볼 수 있듯이 Appium의 소프트웨어 구조가 서로 다른 플랫폼 벤더가 제공하는 테스트 프레임웍(UIAutomation, XCUITest for OSX, UIAutomator, Selendroid for Android, WinAppDriver for Windows, Marionette for Firefox OS)을 공통의 WebDriver API(Selenium WebDriver API)로 랩핑을 하고 있기때문이다. 이러한 구조적 특성으로 인해 유사한 역할을 하는 Calabash와는 다르게 앱을 수정하거나 재컴파일할 일이 없다는 것도 주목할 만한 점이다.

appium_supported_platform[그림 1 Appium 의 테스트 기반 프레임워크]

Appium Architecture

Appium의 아키텍쳐이다.

appium architecture

1) JSON wire protocol로 automation command를 보낸다.
2) vendor 디펜던트한 방식으로 automation command를 호출시킨다.
3) 실행 결과를 appium 서버로 전송한다.
4) 실행 결과를 콘솔에 로깅한다.

Appium은 벤더가 제공한 테스트 프레임워크를 Selenium WebDriver API로 랩핑한 client library들을 다양한 개발 언어로 개발자에게 제공한다.

개발자는 기호에 맞는 언어와 테스트 프레임워크를 선택하여 라이브러리가 제공하는 API(WebDriver JSON Wire Protocol)를 사용하여 자동화된 테스트 스크립트를 작성한다.

Appium 서버는 node.js로 작성되었으며 WebDriver 세션을 생성하고 관리하는 HTTP 서버 이다. 스크립트 상의 명령어들을 각 벤더의 메카니즘에 따라 실행하고 디바이스에서의 실행 결과를 받아와 콘솔에 기록한다.

아래의 그림은 iOS에서의 Appium 아키텍쳐 그림이다.

ios appium

Appium Server와 디바이스 사이에서 iOS가 제공하는 instruments 환경을 사용하여 디바이스에서 명령어를 실행한다.

아키텍쳐 그림을 통해 테스트 라이프사이클을 알 수 있다.

  1. Client(스크립트의 API)은 WebDriver JSON Wire Protocol을 사용하여 Appium서버와 통신한다.
    Appium Server는 client 요청을 받아 client와의 automation session을 생성한다. 그리고 클라이언트가 원하는 기능(capabilities)을 확인한 후 vendor가 제공하는 UIAutomation(iOS 9.3 이하)이나 XCUITest(iOS 9.3 이상) 으로 client와 연결 시킨다.
  1. 이후 client의 요청은 연결된 UIAutomation나 XCUITest 를 통해 device/simulator내에서 실행되고 있는 js로 전달된다.
  2. js는 AUT(Application Under Test) 상에서 클라이언트가 요청한 action이 실행되도록 한다.

본 문서는 iOS의 사용기이니 다른 플랫폼의 세부 라이프사이클은 생략하기로 한다.

테스트 자동화 개발환경 구성

Appium을 사용해 iOS 앱의 테스트 자동화를 실행하기 위해서는 iOS 앱 실행 환경과 Appium 서버 실행 환경, 테스트 스크립트 작성 및 실행 환경이 필요하다.

iOS 앱 실행 환경 구성하기

아래에서는 OSX 에서 iOS Application을 검증하기 위해 필요한 환경 설정 방법을 정리한 것이다. 원문은 https://github.com/appium/appium/blob/master/docs/en/appium-setup/running-on-osx.md#authorizing-ios-on-the-computer 참조하기 바란다.

  • MAC OS X 10.10 이상이 설치될 것을 권고한다.
  • Xcode와 iOS SDK(s)가 설치되어야 한다.
    • Xcode를 설치하면 기본적으로 iOS SDK가 설치된다.  Xcode 7.1 이상은 풀 테스팅을 지원하고, 이전 버전은 제한된 테스팅을 지원한다.
  • iOS Simulator 사용에 대한 인증이 필요하다
    • 아래 그림에서와 같이 npm으로 authorize-ios을 설치한다.
      install_ios_authorize

      • 실행방법은 두가지가 있다.
        Command line으로 실행시, sudo authorize_ios, Appium.app 실행시, GUI로 인증 가능하다.
        그림은  Command line을 통해 실행한 결과이다.
        authorizeios
  • Xcode 7.x 이상(iOS >-9.0) 사용시, instruments 의 delay이슈가 있다. 이는 테스트 속도를 느리게 한다. 이를 해결하기 위해 appium은 IWD(instruments without delay)를 제공한다.

sh /bin/xcode-iwd.sh

실행 예제는 다음과 같다.
sh ./bin/xcode-iwd.sh /Applications/Xcode.app /Users/xyz/appium-instruments/

  • Xcode 6 사용 시, 아래 사항을 주의한다.
    • sendKeys기능을 사용하기 원하는 경우, simulator를 먼저 띄우고 soft keyboard 사용되도록 디폴트 설정을 바꿔야 한다.
    • Xcode Feature중 Devices를 가지는 경우, device list에 중복되는 device 이름을 가지지 않도록 해야한다.
  • iOS8 사용 시, 아래 사항을 주의한다.
    • UIAutomation으로 테스트 시. 아래 그림에서와 같이 device/emulator의 device setting에서 UIAutomation을 반드시 enable시킨 후 테스트해야 한다.
      setting
    • XCUITest(iOS 10.0, Xcode 8.0이상)으로 테스트 시, 아래 그림과 같이 Carthage를 설치해야 한다.
      xcuitest_install
    • Xcode 8.x 이상(iOS >10.0) 사용시, Appium GUI 버전 App은6이상을 사용해야 한다. 현재 1.6은 Inspector를 사용할 수가 없다. 테스트 케이스를 만들기 위해, 화면을 구성하는 Element들의 reference를 알아야 하며, 이를 알기위해 Inspector 사용이 필수적이다. 아래와 같이 이전 버전의 Appium GUI App을 사용해 1.6번의 Appium을 기동시키고, Inspector는 1.5.3 버전을 사용하도록 한다.
      • Xcode 8.x 이상(iOS >10.0) 사용시, Appium GUI 버전 App은6이상을 사용해야 한다. 현재 1.6은 Inspector를 사용할 수가 없다. 테스트 케이스를 만들기 위해, 화면을 구성하는 Element들의 reference를 알아야 하며, 이를 알기위해 Inspector 사용이 필수적이다. 아래와 같이 이전 버전의 Appium GUI App을 사용해 1.6번의 Appium을 기동시키고, Inspector는 1.5.3 버전을 사용하도록 한다.
        • 1.5.3 버전의 Appium GUI App을 실행시킨다. Platform Version에서 10이상의 버전이 존재하지 않는 경우 수기로 버전을 적어 넣는다.
          스크린샷 2017-04-16 오후 9.21.19
    • Xcode 8.x 이상(iOS >10.0) 사용시, Appium GUI 버전 App은6이상을 사용해야 한다. 현재 1.6은 Inspector를 사용할 수가 없다. 테스트 케이스를 만들기 위해, 화면을 구성하는 Element들의 reference를 알아야 하며, 이를 알기위해 Inspector 사용이 필수적이다. 아래와 같이 이전 버전의 Appium GUI App을 사용해 1.6번의 Appium을 기동시키고, Inspector는 1.5.3 버전을 사용하도록 한다.
      • 1.5.3 버전의 Appium GUI App을 실행시킨다. Platform Version에서 10이상의 버전이 존재하지 않는 경우 수기로 버전을 적어 넣는다.
      • GUI버전에서 Launch를 시키지 않고, 터미널 프로그램을 통해 6 이 설치된 디렉토리로 이동하여 command line상에서 Appium을 기동시킨다.
        • 아래와 같은 에러가 발생하는 경우, GUI의 doctor 프로그램을 실행하여 GUI 버전을 통해 설치된 화일들 중에서 해당 에러를 표시하는 화일들을 찾아 에러가 나지 않도록 수정한다. 그리고 Xcode를 업데이트 해준다.(상세 내용은 http://stackoverflow.com/questions/40129794/how-to-fix-error-could-not-detect-mac-os-x-version-from-sw-vers-output-10-12/40168992#40168992 참조)GUI버전에서 Launch를 시키지 않고, 터미널 프로그램을 통해 6 이 설치된 디렉토리로 이동하여 command line상에서 Appium을 기동시킨다.Error : Could not detect Mac OS X Version from sw_vers output: ’10.x.x
          • 아래 이미지처럼 GUI에서 빨간색 부분을 클릭하여 Doctor program 실행
            inspector
          • Doctor 실행 결과를 터미널을 띄워 알려준다.
            doctor
          • 빨간색으로 표시된 파일들을 찾아 에러가 발생하지 않도록 10.x 대 버전을 추가해 준다.
            error patch
          • Xcode 업데이트
            스크린샷 2017-04-04 오후 6.21.44
          • GUI  버전 App을 통해 Doctor를 한번 더 실행하여 문제 해결되었는지 확인한다.
            스크린샷 2017-04-16 오후 10.24.03

Appium Server 환경 구성하기

  • Nodejs, NPM(https://nodejs.org/download/)
    •  homebrew 사용하거나 소스를 받아 Node를 설치한다. Node를 설치하면 NPM이 함께 설치된다.
      nodejs
  • Appium(http://appium.io)
    • npm을 사용하거나 설치화일을 다운로드 받아 Appium과 Appium과 dependency있는 모듈들을 한번에 설치한다.
      appium install
    • Appium 실행할 수 있는지 dependency를 체크한다.
      터미널 프로그램으로 실행 가능하다.
      appium doctor
    • Appium Server 실행
      Appium 서버는 터미널 프로그램을 통해 실행시킬 수 있다.
      스크린샷 2017-04-19 오후 3.06.01

Appium 테스트 코드 개발 환경 구성하기

Appium스크립트는 다양한 언어로 개발될 수 있다. 본 사용기에서는 자바 개발 환경을 설치할 것이다.

Appium 스크립트는 화면을 구성하는 구성요소에 사용자 액션(click, swipe….)을 발생시키는 코드의 집합이다.

그러므로 테스트 스크립트 작성을 위해서 앱을 구성하는 구성요소들의 정보를 알아야 한다. 이를 위해 Application의  화면을 구성하는 구성요소들의 정보를 확인할 수 있는 Inspector를 설치해야 한다.

  • Java SDK설치 (http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)

    • 자바로 테스트 코드를 작성하기 위해서는 Java SDK 다운로드하여 설치한다.
      java
    • Java 환경 변수 설정
      환경 설정 파일에 JAVA_HOME 환경변수를 만들고 설치된 SDK Home을 설정해 준다 설정된 값이 적용될 수 있도록 source 명령어를 실행한 후 설정되었는지 확인한다.
      java path
  • JAVA IDE 설치 (Eclipse, https://eclipse.org/downloads/)
    IDE는 코딩디버그컴파일배포 등 프로그램 개발에 관련된 모든 작업을 하나의 프로그램 안에서 처리하는 환경을 제공한다. IDE를 다운로드 받아 압축을 풀면 eclipse 디렉토리가 보인다. 디렉토리 아래 eclipse App화일을 더블클릭하여 실행시킨다.
    eclipse
  • Maven설치 (https://maven.apache.org/source-repository.html)
    Maven은 Java 코드를 위한 빌드도구이다. homebrew를 사용하거나 소스를 다운     받아 maven을 설치하고 환경 변수를 설정한다. 설정된 값이 적용될 수 있도록 source 명령어를 실행한다. 환경변수 값이 제대로 설정되었는지 확인한다.maven
  • Eclipse를 위한 Maven Plugin설치 (http://download.eclipse.org/technology/m2e/releases/)
    Eclipse에서 Maven을 사용하기 위해 Eclipse를 위한 Maven Plug in을 설치한다. Eclipse의 Eclipse Help > Install New Software… 서브 메뉴를 통해 설치한다.genymotion for eclipse
  • Inspector 설치
    어플리케이션 화면을 구성하는 구성요소들에 대한 정보를 얻기 위해 Inspector 프로그램을 사용할 수 있다. Appium GUI App은 Appium Server 기능 외에 iOS 앱을 위한 Inspector기능 또한 제공한다. 

    • http://appium.io에서 Appium을 설치한다.guiappium
    • Launchpad (응용 프로그램) 에서 Appium UI 버전 앱 아이콘을 확인할 수 있다.
      icon
    • Appium GUI App실행 결과이다.
      appium gui functionsDoctor 프로그램을 실행시켜 Appium 실행을 위해 필요한 라이브러리들이 설치되었는지 필요한 설정이 정상적으로 되었는지 확인하고, Inspector 프로그램을 실행시켜 연결된 device/emulatord에서 실행중인 App을 미러링 하여 App의 화면 구성요소들에 대한 정보를 얻을 수 있다. iOS App 실행 환경 설정 프로그램을 실행하여 연결된 device/emulator에서 실행되어야 할 App의 위치 및 설정 정보를 셋팅할 수 있다. Appium 서버 실행 프로그램을 사용하여 연결된 GUI 프로그램이 내장하고 있는 Appium 서버를 실행시킬 수 있다.

Appium 테스트 코드 개발 환경 구성하기

  • 테스트 앱 준비
    테스트 케이스를 개발하기 위해서 iOS용 앱이 필요하다. 아래 위치에서 앱 소스를 다운로드 받고 컴파일 해보도록 한다.https://developer.apple.com/sample-code/swift/downloads/09_PersistData.zip음식 메뉴를 등록하고 해당 메뉴에 대한 Score를 등록하는 앱이다. Swift로 작성되어 있으며 아래 사이트 App 개발에 대한 step by step 이 상세하게 나와 있다.https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/index.html#//apple_ref/doc/uid/TP40015214-CH2-SW1

    Swift는 정적 바인딩을 제공하는 언어로 코드 상에서 런타임시 발생할 수 있는 Null 체크 같은 오류에 대한 안전성은 확보되지 않지만, 정적인 타입 체크를 컴파일 시간에 잡을 수 있어서 프로그램 작성시에는 좀 불편할 수 있으나 동적 바인딩 기능을 제공하는 언어에 비해서 안정성을 제공한다는 점이 좋은 거 같다.

    Xcode로 앱 소스 코드를 불러와 컴파일 해보자

    open swift app
    소스 코드를 오픈 한다.
    open xcode prj

    iPhone 6 에뮬레이션에서 실행할 것으로 설정한다.

    set_device_emulator

    Clean & Build & 실행한다.

    build

    실행시 아래와 같은 화면을 볼 수 있다. 세 개의 음식에 대한 Score가 등록되어 있다.

    스크린샷 2017-04-17 오후 3.45.08

    Edit을 클릭하면, 아래와 같은 화면이 나와 등록된 음식에 대한 평가 내용을 지울 수 있다. 지우고 싶은 평가에 대해 – 버튼을 누르고  Done을 클릭한다.

    스크린샷 2017-04-17 오후 4.17.32

    + 버튼을 클릭하면, 아래와 같은 화면이 나와 음식에 대한 평가를 등록할 수 있다. 음식명, 음식 사진, 그리고 별 모양을 눌러 점수를 등록한 후 Save 버튼을 클릭한다.

    스크린샷 2017-04-17 오후 4.17.47

  • 테스트 코드 작성
    • 테스트 소스 구조 설정software architecturePageObject 패턴을 사용한다. PageObject 패턴은 화면 단위로 어플리케이션을 모델링하여 테스트할 수 있게 해주며, 시나리오와 실제 로직 사이의 디펜던시를 없애 유지보수가 용이하고 중복되는 코드를 없애는데 효과적이다. 동일한 테스트 코드로 서로 다른 플랫폼의 GUI 기반 테스트를 하는 Appium에 적합하다. 관련하여 selenium에서 Page 객체를 인스턴스화하기 위한 PageFactory API를 제공한다.화면의 종류에 따라 FoodTrackerMainPage, FoodTrackerRegisterPage, PhotoPage 세 개의 Page를 가지며, 각각은 Interface Type의 형태를 가진다. 모든 Interface는 IOS, Android 용의 구현화일에 의해 구현된다. 각 구현화일은 xpath, name 으로 Page에 속한 UI구성요소에 대한 레퍼런스를 가지고 있으며, 레퍼런스를 리턴하거나 각 플랫폼 의존적인 동작을 하는 API를 가진다.

      테스트 시나리오 화일은 각 Page에 대한 인스턴스를 가지고 있으며, 인스턴스에 정의된 메소드를 가지고 테스트 시나리오를 구성하고, 결과를 검증한다. 인스턴스는 Interface Type으로, IOS와 Android에 따라 구현된 구현 클래스를 객체화한 변수이다. Interface Type을 가지기때문에 IOS, Android 어떤 플랫폼이나 동일하게 가지는 메소들로 구성된다.

    • 테스트 시나리오 작성
      테스트는 시나리오는 다음과 같다. 테스트 시나리오 작성시 모든 화면을 구석 구석 들어가보고 각 화면의 모든 UI 구성요소에 모든 액션들을 발생시켜 보도록 작성하고 액션 발생순서 또한 다양하게 해보는게 중요한 것 같다. 하지만 예제에서는 각 페이지를 들어가 보고 눈에 띄는 액션들만 한번씩 발생시키는 것을 목표로 했다.

      1.  애플리케이션을 실행시킨다. Main 화면을 구성하는 UI 요소들이 정상적으로 표시되었는지 확인한다.

      2. Edit 버튼을 눌렀을때 음식 메뉴를 삭제할 수 화면이 표시되는지 확인한다. 다시 한번 눌러 삭제 모드에서 나오는지 확인한다.
      3. 삭제 버튼을 클릭하여 지정된 음식이 삭제되는지 확인한다. 현재 등록된 음식을 하나씩 모두 삭제한다.

      4. 음식에 대한 평가 20개를 하나씩 등록한다.

      5. 화면을 아래로 스크롤 한다.(10회)

      6. 화면을 위로 스크롤 한다.(10회)

    • 테스트 코드 작성
      아래에서 설명하는 테스트 코드는 https://github.com/heeseon/IOS_SWIFT_Appium_Example 에서 받을 수 있다.

      • maven  프로젝트를 생성하고, pom.xml을 열어 디펜던시가 있는 junit, appium java-client, selenium-java 라이브러리를 설정한다.
        pom file
      • JUnit 테스트 화일은 테스트 초기화, 해제 코드 그리고 테스트 함수들이 어노테이션과 함께 작성된다. 테스트 화일은 테스트 시작, 해제 함수를 갖는 화일과 테스트 시나리오를 갖는 화일로 분리했다.
        테스트 시작, 해제 함수는 테스트 시작시, 테스트 완료시 한번만 호출되도록 @BeforeClass, @AfterClass 어노테이션과 함께 사용했다.
        testfile-start-end
        setUp 함수는 Controller의 start 코드를 호출한 후 각 Page에 대한 인스턴스를 생성한다.
        setUp과 tearDown에서 호출하는 AppiumController의 코드는 다음과 같다.
        testfile-controller테스트 시작시 불리워지는 start 함수에서는 Appium 서버에 테스트 정보를 전달하고 세션을 얻어와 driver라는 변수에 저장한다. 서버에 전달되는 테스트 정보는  DesiredCapability라는 타입의 객체로, 테스트 앱 플랫폼, 디바이스 버전, 테스트 하고자 하는 앱 화일(xxx.app) 패스, automationName(XCUITest) 등의 정보가 최소한 설정되어야 한다. iOS 9.3 이상용으로 컴파일된 앱은 automationName을 반드시 XCUITest로 지정해 주어야 한다.
        Xcode로 App을 빌드하면 결과 화일(app 확장자 화일)이 저장되는 디폴트 위치는 App의 소스 코드 패스가 아닌 Xcode 패스내에 저장된다. 저장위치는 아래와 같은 절차를 통해 확인할 수 있다.Xcode의 Preferences…를 클릭한다.app path 1

        Location 탭의 Derived Data 정보를 확인한다.

        app path 2

        Finder를 열어 Derived Data 위치에 가면 앱 프로젝트 이름에 뒤에 이상한 스트링이 붙은 폴더가 있고, 그 아래 Build>Products>Debug-iphonesimulator 폴더 아래 app 화일을 확인할 수 있다.
        appfilepath

        테스트 완료 시 불리워지는 stop함수에서는 세션을 해제하도록 driver에 quit 함수를 호출한다.

        % DesiredCapabilities는 key, value를 가지는 hash 구조를 가지며, 자동화를 수행하는 동안 테스트하기 원하는 세션의 정보를 주거나, 기능에 대한  timeout 시간을 설정하는 등과 같이 Appium 서버를 제어하기 위한 속성값을 설정할 때 사용한다. iOS와 Android는 같은 key에 대해 서로 다른 value를 가진다. 상세 사항 은 아래에 명시된 API에 대한 reference를 참고하기 바란다.
        https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/remote/DesiredCapabilities.html
        %

      • 각 화면(Page)에 대한 구현 클래스를 구현하고 인스턴스를 생성한다.
        세 화면을 위해 FoodTrackerMainPage, FoodTrackerRegisterFoodPage, PhotoPage Interface를 생성하였다.
        각각의 Interface는 화면을 구성하는 UI 구성 요소를 리턴하는 메소드와 화면에 로딩 시, 표시되어야 하는 UI 리스트를 리턴하는 API를 정의하였다. 그리고 XCUITest프레임워크에서 구현한 IOSElement의 findElements 함수가 정상적인 역할을 하지 못하는 것 같아 xpath를 통해 자식 노드들을 검색해주는 API를 정의해 주었다.
        테스트 화일에서 각 Page에 정의되 API와 MobileElement가 제공하는 API를 호출해 테스트 시나리오를 실행시킨다.
        각 Page를 구현한 구현클래스에서는 화면을 구성하는 UI 구성 요소들에 대한 reference를 정의하였다.  생성자 함수에는 MobileElement초기화를 위해 PageFactory.initElements 함수를 호출해 주고, 각 reference에 xpath와 함께 @FindBy를 달아 MobileElement라는 것을 명시해줬다.화면의 UI 구성요소의 xpath를 포함한 정보를 얻기 위해서는 Inspector를 사용해야 한다.
        Appium GUI 버전을 띄워 App의 정보(App 패스 및 실행될 iOS 플랫폼 정보)를 설정해 주고 Inspector 기능을 실행시킨다. Simulator가 실행되고 Simulator에서 App이 실행된다.스크린샷 2017-04-17 오후 3.45.08
        그리고 Inspector가 떠서 Simulator 화면을 미러링 한다.
        inspector1
        가끔 device/simulator 화면 정보를 제대로 읽어오지 못하는 경우가 있다. 이런 경우 Refresh 버튼을 사용하여 문제를 해결할 수 있다.

        미러링 화면에서 특정 UI 요소를 클릭하면 그 UI 정보가 Detail 화면에 나타나고 그 UI의 계층 구조내에서의 위치가 화면 왼쪽 계층 구조내에서 나타난다.  혹은 왼쪽 계층 구조내에서 특정 요소를 클릭하면 그 UI를 미러링된 화면에서 붉은색으로 보여준다.  아래 화면은 오른쪽 미러링 화면에서 두번쨰 음식 평에 별 모양을 클릭했을 때 별 UI 정보의 상세 정보와 계층 구조내의 위치를 보여주는 예제이다.
        inspector usage
        위와 같이 Inspector에서 특정 UI를 선택해 Details 정보 내용을 확인하여 xpath나 UI 구성요소의 속성값을 알아내고 이것을 테스트 코드에서 사용한다.
        이렇게 얻은 UI 구성요소의 정보를 가지고 그것의 레퍼런스를 알아내고 레퍼런스에 아래와 같은 사용자 액션을  실행시킨다.
        – click/ tap
        – setText/getText
        – swipe
        위와 같은 사용자 액션 외에도 Appium은 로그 수집이라든지, crash 수집 등의 기능을 사용할 수 있다. 자세한 내용은 아래 API 설명을 참고하자
        http://appium.github.io/java-client/

      •  

        Inspector는 이외에 특정 UI 구성요소에 Tap/Swipe/Shake/Text 입력 등의 사용자 액션을 발생시키는 기능과 이렇게 발생시킨 사용자 액션을 테스트 코드로 저장해 주는 기능도 있다.  사용해 보면 테스트 코드 작성시 도움이 될 듯 하다.

      • 시나리오의 각 단계를 구현한다.
        위에서 정의한 시나리오 각 단계를 @Test 어노테이션과 함께 테스트 함수로 구현해 주었다. 각 Page에서 정의한 인터페이스를 통해 화면 UI 구성요소의 reference를 얻고, MobileElement에 정의된 API를 호출해 reference에 사용자 action함수를 발생시킨다. 그리고 화면에 변화가 생겼는지 MobileElement가 제공해주는 API를 사용해 검증한다.

사용후기

요즘 모바일 디바이스 앱의 호환성 및 시나리오 테스트를 위해 가장 관심도가 높은 Appium에 대해서 사용해 본 결과 느낀점을 적어보았다. 

  1. 당연히 UI 테스트로 소프트웨어의 모든 기능 테스트를 하는 것은 불가능하다. 

기본적으로 모든 유닛에 단위 기능 테스트가 작성되어야 하며, 단위 테스트는 입력에 대한 기능을 정상적으로 하는지 출력을 정해진 대로 내는지 입력에 대한 예외 처리를 제대로 하는지 유닛 내부에 모든 패스에 대해서 테스트가 되는지를 기준으로 커버리지가 산정되어야 하며, 커버리지가 100에 가까울 수 있도록 테스트가 되어야 할 것이다. 그러나 이렇게는 시간이나 비용이 많이 드니 최소한의 테스트인 시나리오 테스트를 하는 것 아닐까 싶다. 단위 기능 테스트가 100프로 되었다고 해서 시나리오 테스트가 필요 없다는 이야기는 아니다.  

애니웨이, UI 테스트는 시나리오 테스트에 적합하며, 짧은 개발 시간에 애플케이션의 테스트를 진행하기 위해 파편화가 심한 모바일 디바이스 환경하에서 다양한 디바이스 간의 호환성 테스트하는 것에 적합하다.

2. 오픈소스인 Appium에 개발자들이 기여할 수 있는 부분이 많다.

소소한 이슈들이 많아 해결되어야 하며, 개발 시간 단축을 위해 사용하는만큼 테스트 환경 및 케이스 개발을 쉽게 할 수 있도록 하는 기능들, 테스트 결과를 쉽게 확인할 수 있도록 하는 툴이 제공되어야 한다.  툴은 Appium framework에 속한 내용일 수도 있고,  클라이언트 라이브러리와 함께 IDE에서 제공하는 형태일 수도 있고, 디바이스에서 테스트시 실행되는 또다른 애플리케이션일 수도 있고, 애플리케이션에서 사용자 액션을 저장할 수 있도록 혹은 테스트 시 어플리케이션과 통신을 위한 어플리케이션에 내장되는 라이브러리 일 수도 있겠다.

3. UI 테스트라 시간이 오래 걸린다.

개발 시간에 영향받지 않도록 별도의 프로세스로 자동으로 주기적으로 돌리고, 돌리는 동안 다른 일을 하고 이후에 결과를 확인할 수 있어야겠다. 테스트를 하는 동안 디바이스에서 일어나는 테스트 결과/AV/성능수치를 포함한 외에 모니터링되어야 하는 모든 디바이스 상태가 저장되고 이후에 한 화면에서 이것을 확인할 수 있으면 좋을 것 같다.