ページ

2015/01/26

[Android] Support Library に追加された testing-support-lib や Espresso 2.0 で JUnit4 な Android のテストを書く

Android Support Library に UI テストを行う Espresso 2.0 や
JUnit4 でテストを行うための testing-support-lib が追加されました。

前置き

概要とドキュメントなど

Espresso 2.0 is here!

android-test-kit - Google's Testing Tools For Android - Google Project Hosting


サンプルコード

googlesamples/android-testing


関連エントリ

Espresso 2.0 が Android support library の一部としてリリースされた - ひだまりソケットは壊れない
Espressoがsupport libraryになってAndroidでJUnit4が使えるようになったと聞いたので試してみた - みんからきりまで
続・AndroidでJUnit4を使う方法(Android SDKで正式サポートされました!) - Qiita
support packageに追加されたtesting-support-libを使ってAndroidのテストをJUnit4で書く - visible true


JUnit4 で Activity のテストを書いてみる

@@ -10,6 +10,8 @@ android {
         targetSdkVersion 21
         versionCode 1
         versionName "1.0"
+        // testing
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
     buildTypes {
         release {
@@ -17,9 +19,16 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+    packagingOptions {
+        exclude 'LICENSE.txt'
+    }
 }

 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile 'com.android.support:appcompat-v7:21.0.3'
+    // testing
+    compile 'com.android.support:support-annotations:21.0.3'
+    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
+    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
 }
package com.wada811.android.junit4;

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.ActivityInstrumentationTestCase2;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;

@RunWith(AndroidJUnit4.class)
public class MainActivityTest extends ActivityInstrumentationTestCase2 {

    private MainActivity activity;

    public MainActivityTest(){
        super(MainActivity.class);
    }

    @Before
    public void setUp() throws Exception{
        super.setUp();
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        activity = getActivity();
    }

    @After
    public void tearDown() throws Exception{
        super.tearDown();
    }

    @Test
    public void checkPrecondition(){
        assertThat(activity, notNullValue());
        assertThat(getInstrumentation(), notNullValue());
    }

}

参考

Getting Started - EspressoSetupInstructions - android-test-kit
AndroidJUnitRunnerUserGuide - android-test-kit

テストを実行する

./gradlew connectedAndroidTest コマンドを実行

端末もしくはエミュレータでテストを実行することができます。
しかし、何故か MainActivityTest.java は実行されませんでした。
JUnit3 なテストは実行されていますが、 JUnit4 な テストは実行されないみたいです。

プロジェクトエクスプローラで右クリックから Run...

ファイルを指定して実行すれば JUnit4 なテストも実行できます。


Edit Configurations... から Android Test を追加してクラスを指定して実行

クラス(ファイル)を指定して実行すれば JUnit4 なテストも実行できます。
All in Module や All in Package では JUnit4 なテストは実行されませんでした。


クラスを指定しなくても JUnit4 なテストを実行したい

これは偶然なのか考えられているのかわからないけど Jake 神の ActivityRule を使うと
直接クラスを指定しなくてもテストを実行できるようになります。
package com.wada811.android.junit4;

import android.support.test.runner.AndroidJUnit4;
import com.jakewharton.test.ActivityRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.*;
import static android.support.test.espresso.assertion.ViewAssertions.*;
import static android.support.test.espresso.matcher.ViewMatchers.*;
import static org.hamcrest.Matchers.*;

@RunWith(AndroidJUnit4.class)
public class MainActivityTestWithRule {

    @Rule
    public final ActivityRule activityRule = new ActivityRule<>(MainActivity.class);

    @Test
    public void checkPrecondition(){
        // MatcherAssert.assertThat(activityRule.instrumentation(), Matchers.notNullValue());
        assertThat(activityRule.instrumentation(), notNullValue());
    }

    @Test
    public void showHelloWorld(){
        // Espresso.onView(ViewMatchers.withId(R.id.textView)).check(ViewAssertions.matches(ViewMatchers.withText(R.string.hello_world)));
        onView(withId(R.id.textView)).check(matches(withText(R.string.hello_world)));
    }

}
Espresso 2.0 でテストを書いてみました。
クラス名を覚えるのは辛い感じなので static import でメソッド書くだけにしたい感じがあります。

ソースコードは wada811/Android-JUnit4 にあります。
Activity だけじゃなく他のテストについても増やしていきたいです。

参考

A JUnit @Rule which launches an activity when your test starts. Stop extending gross ActivityInstrumentationBarfCase2!

2015/01/08

2014年の反省と2015年の目標

あけましておめでとうございます。
2012/01/08に始まったこのブログも
3周年を迎えました。
2013年は117記事でしたが、
2014年は72記事となって減少傾向です。
細かい Tips などは Qiita
書くようになったので
wada811(Qiita) もよろしくお願いします。
昔からの人も最近からの人も
2014年、お世話になりました!
2014年のエンジニア人生を振り返って
2015年の目標を立ててみようと思います。

2014年

結婚した

撮った写真を披露宴会場のスクリーンに表示するシステムが3万円くらい、と
結婚式の2週間前に TV でやっているのを見て
こんなのすぐできる!1人日程度だろ?と思って写真アップロードシステム作ったのは良い思い出でした。
実際は細切れにしか作業できなかったので総日数としては3日くらいかかりましたが。
借りてたさくらのVPSにPHPをインストールしてなかったとか
ドメインを取ってなかったので契約からスタートとか色々ありましたが、
開発だけなら1人日程度でできたと思います。
wada811/wedding.wada811.com
とにかく時間がなくて画面も3枚だけだったので手っ取り早く素の PHP で作りました。
脆弱性とかはないと信じたい。。。
開発で一番時間がかかったのは PDO の薄いラッパーを探すことで、
プリペアドステートメントでクエリ発行できるやつが見つからなかったので仕方ないから自分で作りました。
あとは、CSS3 の transform をアニメーションの調整くらい。
関連記事
さくらのVPSにスタードメインで取得した独自ドメインを設定してみた
jquery.transform.js で CSS3 の transform をアニメーションさせる
exif-js と ios-imagefile-megapixel でスマホからの画像アップロードのプレビュー表示に対応する

Androider としての技術力を更に高める

どちらかというとライブラリ作ってた感じ。
wada811/Android-DialogFragments
wada811/Android-Material-Design-Colors
カメラのライブラリも作ってほぼほぼできていたけど放置していて完成したのかどうかも忘れている現状…。
カメラのライブラリは設計がいいのかどうかもわからなくて、
他の人がカメラアプリ作るときどんな感じに作っているのか知りたい。
The Android Arsenal - LandscapeVideoCameraとか、
そこの See Also とか見ればわかるかな。

新しい言語を学ぶ

Ruby on Rails 始めました。
Qiitaで Ruby とか Rails の知見を共有しています。
View は Slim で書いていて、もう PHP で、HTML で、というのには戻れない感じです。
そういう感じなのでブログも生の HTML を書くのが面倒になってきて Markdown で書きたいなぁという感じです。

OpenGL を学ぶ

やりませんでした。たぶん来年もやりませんね。

UnitTest / CI を学ぶ

Rails で Rspec を使ってテスト書いたり、 Guard でファイル変更を監視して自動的に Rspec を実行とかやった。
Rails はとにかくすぐ壊れる印象なのでテストがないとリファクタリングできないという感覚になっている。
テストを書く習慣が定着してるのはそういうことか〜という感じです。

個人でのプロダクトを出す

ライブラリをプロダクトと呼ぶかは微妙だけど、それ以外で言うと何もないなぁという感じです。
ひたすら GitHub Star を集めたり Qiita Stock を集めたりしてモチベーションを保っていた。

収入を増やす

一応増えたけどコスパ良くない。税金が重い。社会は厳しいという感じ。

2015年

もっと Android

あんまり Android で DB を使ったアプリを作ってないので作りたい。
RxJava, RxAndroid, Lombok あたりを使ってモダンな感じで作りたい。
Material Design に対応したい。
この3本で頑張っていこうと思います。

もっと Ruby on Rails

まだ1ヶ月やっただけなので、もっと経験を積みたいです。
アプリのバックエンドで使ってみる。

もっと UnitTest / CI

コミットしたらテスト実行されて…という環境を作る。

個人でのプロダクトを出す

新しいものを考えてはある。あとは作るだけ。

収入を増やす

コスパあげたい。

ブログを移行する

GitHub Pages に移行して Markdown で記事書きたい。
でも GitHub Pages をやめちゃった人がいて、面倒なのかとか気になっているところ。
ブログのカスタマイズにはあまり時間を掛けたくないので悩んでいる。

2015年もよろしくお願いします!

さらなる飛躍の年にするべく頑張ります!