今回Mac OS Xアプリを作るにあたって、UIテストを自動化してみました。
XCTestを使うと簡単に自動UIテストを行うことができます!

テストファイルの作成

Xcodeプロジェクトを作成する際に、Include UI Testsにチェックをしておきます。すると [プロジェクト名]Testsというターゲットが自動作成されます。

make_test_file_4

テストしたい操作の設定

[プロジェクト名]UITests/ [プロジェクト名]UITests.swiftにテストしたい処理を登録します。

[プロジェクト名]UITests.swiftの中身

import XCTest

class HogehogeUITests: XCTestCase {
        
    override func setUp() {
        // テスト前に走る共通の処理
        super.setUp()
        continueAfterFailure = false
        XCUIApplication().launch()
    }
    
    override func tearDown() {
        // テスト後に走る共通の処理
        super.tearDown()
    }
    
    func testExample() {
   		// テスト内容
    }
    
    func testExample2() {
        // テスト内容
    }
    
    func hogeHoge() {
        // テストの中で使う関数も書ける
    }
}

メソッドの種類

メソッド 概要
setUp() テスト開始時に1回だけ呼ばれる。
tearDown() テスト終了時に1回だけ呼ばれる。
testExample() テストしたい処理をここに書く。testから始まるメソッドは全てテストコードとなる。

Recording機能

Recording機能を使うと、マウス操作をコードに自動変換してくれます。とても便利です。

recording

操作を登録したいメソッドにカーソルをおきます。次に左下の Record UI Test マークをクリックします。すると記録モードになるので、登録したい操作を行います。最後に Stop Recording UI Test マークをクリックして記録終了です。

Screenshot撮影

テストのログとしてキャプチャ画像があると嬉しいですよね。XCUITestでは自動的に撮影してくれます。

保存場所

XcodeのReport Navigatorから、撮影画像を見ることができます。

screenshot

また画像は下記のような場所に保存されています。
/Users/ユーザ名/Library/Developer/Xcode/DerivedData/プロジェクト名-ランダムな英数字/Logs/Test/Attachments

テストの実行

Command + Uで全てのテストが走ります。
メソッドを1つずつ試したい場合は、メソッドの横のダイヤ型マークをクリックします。

do_test

Mac OS XアプリでのTips

ステータスバーのメニューアイコンのクリックを登録したい

Recording機能ではステータスバーにあるメニューアイコンをクリックした時点でXcodeからフォーカスが外れ、記録が中断されてしまいます。

コードでメニューアイコンへアクセスするには以下のように設定します。

storyboard

menuのAttributes inspectorでtitleを"Menu"にします。同じくメニュー項目のtitleをItemにします。

コード

func testExample() {
	// メニュータイトルをクリック
	let menu = XCUIApplication().statusItems["Menu"]
	menu.click()
	// メニューの項目をクリック
	menu.menuItems["Item"].click()
}

スクリーンショット撮影のタイミングを指定したい

自動撮影では撮影タイミングを指定できないのが難点です。

解決法1:fastlaneを使用 => ×

iOSではこの方法が有効なようですが、残念ながらMac OS Xアプリには未対応でした。
(過去に対応していたバージョンがあったようですが、現行バージョンでは未対応に…)

解決法2:コードで明示的に記述 => ◎

撮影用メソッドを直接記述すればOKでした。
let screenshot = XCUIScreen.main.screenshot() とすると、メイン画面全体のスクリーンショットを撮ってくれます。

ただしそのままでは画像は消えてしまうので、Attachmentで保存します。

func testRecodingExample(){
	XCUIApplication().buttons["nextButton"].tap()
    let screenshot = XCUIScreen.main.screenshot()
    let attachment = XCTAttachment(screenshot: screenshot)
    attachment.lifetime = .keepAlways  // 成功後もデータを保持
    add(attachment)
}

Xcodeが自動的に撮影する分については成功後に削除設定にしておく、もしくは自動撮影しない設定にしておきましょう。

delete_default_screenshots

画像名の指定

保存する画像名は attachment.nameで設定できますが、"フォルダ名/ファイル名"みたいなことはできません。単に"フォルダ名ファイル名_{自動で付与される文字列}.png"で保存されてしまいます。残念…。

screenshot-_name

さいごに

Assertを追記すると、画面の表示内容のチェックなども行えます。まだUIテストを手動で行っているという方は、ぜひこの方法を利用してみてくださいね!

ぺったす[公式スタンプ] もよろしくお願いします!

© 2018. SuperSoftware Co., Ltd. All Rights Reserved.