[iOS] UI自動化テストフレームワークEarlGreyでテストを書いてみた(Objective-C版)

2016.03.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

昨日は、2月に公開されたばかりの、googleのUI自動化テスト・フレームワーク EarlGrey のデモを動かすところまでやってみましたが、今日は、自前のプジェクトにEarlGreyを組み込んで、簡単なテストコードを書くところまでやってみました。

EarlGreyについては、下記をご参照ください。

[iOS] 明確で簡潔なテストを書くことができる iOS UI自動化テスト・フレームワークEarlGreyを試してみました。

2 ターゲットプロジェクトの作成

まずは、テスト対象となる簡単なプログラムを作成します。

(1) プロジェクト作成

Single View Applicationの雛形から、新しいプロジェクトを作成します。(ここでは、プロジェクトの名前をSampleAppとしました)

(2) ログイン画面

ストーリーボードで、次のようなUIを作成します。

009

動作としては、ユーザ名とパスワードを入力して「ログイン」ボタンを押すと、「ログイン成功」若しくは「ログイン失敗」のメッセージが表示されるという簡単なものです。

「ログイン」ボタンを押した時のコードは次のようになっています。

- (IBAction)tapLoginButton:(id)sender {
    bool isSuccess = false;
    NSString *user = self.userTextField.text;
    NSString *pass = self.passwordTextField.text;

    if([user isEqual: @"taro"] && [pass isEqual:@"123"]){
        isSuccess = true;
    }

    // 通信中を模擬して3秒のウエイトを置く
    [NSThread sleepForTimeInterval:3.0];

    NSString *title = (isSuccess) ? @"SUCCESS" : @"ERROR";
    NSString *message = (isSuccess) ? @"ログインしました" : @"ユーザー名若しくは、パスワードが違います";
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title
                                                                             message:message
                                                                      preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
    }]];
    [self presentViewController:alertController animated:YES completion:nil];

}

ユーザー名が「taro」で、パスワードが「123」の時だけ、ログイン成功が表示されます。また、サーバとの通信に時間がかかることをイメージして結果がでるまでに3秒のウエイトを起きました。

010 011

(3) Accessinility

後で、テストから識別できるように、2つのUITextFieldUIButton(ログインボタン)のAccessinility Identifierを設定しました。

図は、ユーザー名のテキストフィールドにuserTextFieldと言う識別子を設定している様子です。

012

3 EarlGreyの組み込み

(1) テストの追加

メニューからEditor - Add target - iOS - Test - iOS Unit Testing Bundle を選択し、新しいユニットテストを追加します。(ここでは、名前をSampleTestsとしました。 )

001

(2) スキームの追加

New Schemeで、ターゲットをSampleAppTestsとした新しいスキームを追加します。

002

ここでは、名前をSampleAppTestsとしました。

003

Manage Schemesを開いて、今追加したSampleAppTestsSharedにチェックを入れます。

004

(3) Cocoapodによるインストール

ここで一旦、Xcodeを終了し、このプロジェクトのフォルダにPodfileを作成します。

PROJECT_NAME = 'SampleApp'
TEST_TARGET = 'SampleAppTests'
SCHEME_FILE = 'SampleAppTests.xcscheme'

xcodeproj PROJECT_NAME
target TEST_TARGET, :exclusive => true do
  pod 'EarlGrey'
end

post_install do |installer|
  load('configure_earlgrey_pods.rb')
  configure_for_earlgrey(installer, PROJECT_NAME, TEST_TARGET, SCHEME_FILE)
end
~

続いて、このフォルダにconfigure_earlgrey_pods.rbをダウンロードします。 (configure_earlgrey_pods.rbは、Podfileの中で使用されています)

プロジェクトフォルダに、Podfileconfigure_earlgrey_pods.rbがある状態で、pod installを実行します。

$ pod install
[!] Unable to load a specification for the plugin 
Updating local specs repositories

CocoaPods 1.0.0.beta.5 is available.
To update use: `gem install cocoapods --pre`
[!] This is a test version we'd love you to try.

For more information see http://blog.cocoapods.org
and the CHANGELOG for this version http://git.io/BaH8pQ.

Analyzing dependencies
Downloading dependencies
Installing EarlGrey (1.0.0)
Generating Pods project
Checking and Updating SampleApp for EarlGrey.
Adding EarlGrey Framework Location as an Environment Variable 
EarlGrey setup complete. You can use the Test Target : SampleAppTests for EarlGrey testing.
Integrating client project

[!] Please close any current Xcode sessions and use `SampleApp.xcworkspace` for this project from now on.
Sending stats
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.

(4) ワークスペースを開く

pod installで生成されたSampleApp.xcworkspaceをXcodeで開くと、Podsの中に、EarlGrey.frameworkを確認できます。

005

(5) Copy Phase の追加

SampleAooTestsBuild PhasesNew Copy Phaseを選択し、Phaseを1つ追加します。

006

追加したPhaseは、次のように設定します。(ここでは、分かりやすいように名前をEarlGray Copy Filesとしました)

  • Destination: Absolute Path
  • Path: $(TEST_HOST)/..
  • Copy files only when installing: Deselect
  • Name: Path to EarlGrey.Framework with Code Sign on Copy selected.

007

4 テストの作成

(1) テストコード

SampleAppTestsのSampleAppTest.mを次のように編集します。

内容としては、ユーザ名に「taro」、パスワードに「xxx」を入力して、ログイン失敗のメッセージがポップアップされることを確認し、続いて、パスワードを正しいものに修正して、今度は、ログイン成功のメッセージが表示されることを確認しています。

テストコードとしては、かなり不適切に冗長になっていますが、サンプルとして、分かりやすいかと思い、わざとづらづら書いていることをご了承ください。

@import EarlGrey;
#import <XCTest/XCTest.h>

@interface MyFirstEarlGreyTest : XCTestCase
@end

@implementation MyFirstEarlGreyTest

- (void)testLogin {

    //*****************************************************
    // ログイン失敗
    //*****************************************************
    NSString *user = @"taro";
    NSString *pass = @"xxx";

    // ユーザ名の入力
    [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"userTextField")]
     performAction:[GREYActions actionForTypeText:user]];
    // パスワードの入力
    [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"passwordTextField")]
     performAction:[GREYActions actionForTypeText:pass]];
    // ログインボタンを押す
    [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"loginButton")]
     performAction:grey_tap()];

    // ERRORというテキストが表示されていることを確認する
    [[EarlGrey selectElementWithMatcher:grey_text(@"ERROR")]
     assertWithMatcher:grey_sufficientlyVisible()];

    // OKボタンを押して、アラートを閉じる
    [[EarlGrey selectElementWithMatcher:grey_text(@"OK")]
     performAction:grey_tap()];

    //*****************************************************
    // ログイン成功
    //*****************************************************
    pass = @"123"; // 正しいパスワードに変更

    // パスワードの修正
    [[[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"passwordTextField")]
      performAction:grey_clearText()]
     performAction:[GREYActions actionForTypeText:pass]];

    // ログインボタンを押す
    [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"loginButton")]
     performAction:grey_tap()];

    // SUCCESSというテキストが表示されていることを確認する
    [[EarlGrey selectElementWithMatcher:grey_text(@"SUCCESS")]
     assertWithMatcher:grey_sufficientlyVisible()];

    // OKボタンを押して、アラートを閉じる
    [[EarlGrey selectElementWithMatcher:grey_text(@"OK")]
     performAction:grey_tap()];

}

@end

(2) テスト実行

⌘+U でテストを実行している様子です。

008

5 最後に

今回は、自前のプロジェクトに、EarlGreyを組み込んで、実際にテストコードを書いてみました。

EarlGreyのテスト用APIのドキュメントをみると、かなりのファンクションが用意されています。 また、対象のコントロールなどを捕まえる方法も、厳格に指定する方法から、非常にファジーに捕まえる方法まで用意されているようです。

これを機会に、UIテストについても、色々試してみたいと思いました。

6 参考資料

[iOS] 明確で簡潔なテストを書くことができる iOS UI自動化テスト・フレームワークEarlGreyを試してみました。
EarlGrey - iOS 向けの UI 機能テスト フレームワーク
https://github.com/google/EarlGrey
iOS UIテストフレームワーク EarlGrey のセットアップ
http://www.testingexcellence.com/earlgrey-open-source-test-automation-tool-for-ios/
https://kazucocoa.wordpress.com/2016/02/17/ios-test-ui-with-googleearlgrey/