テスト部第6回MTG(Android)で知ったRobolectricを試してみようと、Eclipse Quick Start | Robolectricを見ながら試してみましたが、私の英語力の低さにより(?)うまくいかなかったので、じっくりと意訳しながら試してみます。
下準備
Downloads | Robolectricから robolectric-X.X.X-all.jar をダウンロードしておきます。
robolectric-X.X.X.jar をダウンロードすると私のように残念な結果になってしまいます。
Androidプロジェクトの作成
新規Androidプロジェクトのダイアログ
テスト用ソースディレクトリを追加
- パッケージエクスプローラの‘MyProject’で右クリックして、新規→フォルダー(ソース・フォルダーを作成しないこと)
- フォルダー名:test
- 完了を押す
テスト用のJavaプロジェクト作成
テスト用プロジェクトにjarファイルを追加
エクスプローラでもコマンドラインでもいいので、
- MyProjectTest の下に lib ディレクトリを作成する
- lib ディレクトリに
robolectric-X.X.X-jar-with-dependencies.jarrobolectric--X.X.X-all.jar をコピーする
ビルドパスの設定
Eclipseに戻る
- “MyProjectTest”で右クリック
- “リフレッシュ”を選択(libフォルダが表示される)
- “MyProjectTest”で右クリック
- “ビルドパス”を選択→“ビルド・パスの構成”
JUnitライブラリの追加
- “ライブラリー”タブを選択
- “ライブラリー”の追加
- “JUnit”を選択
- “次へ”をクリック
- “JUnit4”を選択(Robolectric は JUnit3 と互換性がない)
- “完了”をクリック (MyProjectTestのプロパティーは開いたまま)
Robolectric の jar を追加
- “Jar 追加”をクリック
- MyProjectTest → lib を展開
robolectric-X.X.X-jar-with-dependencies.jarrobolectric--X.X.X-all.jar を選択- “OK”をクリック (MyProjectTestのプロパティーは開いたまま)
Android の jar を追加
- “外部 Jar 追加”をクリック
\platforms\android-8\android.jar を選択 - “開く”をクリック (MyProjectTestのプロパティーは開いたまま)
- “外部 Jar 追加”をクリック
\add-ons\addon_google_apis_google_inc_8\libs\maps.jar を選択 - “開く”をクリック (MyProjectTestのプロパティーは開いたまま)
- MyProjectTestプロパティーの“OK”をクリック
テストの実行設定
- “実行” → “実行構成”
- ”JUnit”をダブルクリック (“Android JUnit Test”ではないので注意)
- 名前: MyProjectTestConfiguration
- “選択されたプロジェクト、パッケージ、またはソース・フォルダー内のすべてのテストを実行”のラジオボタンを選択
- “検索ボタン”をクリック
- “MyProjectTest”を選択
- テスト・ランナー:JUnit 4
- “複数のランチャーが使用可能です”の“一つ選択”をクリックする
- “構成固有の設定を使用”をチェック
- “Eclipse JUnit ランチャー”を選択
- “OK”をクリック
- “引数”タブをクリック
- “作業ディレクトリー:”の下にある“その他:”を選択する
- “ワークスペース”をクリック
- “MyProject”を選択(“MyProjectTest”ではない。エディットボックスの中は‘${workspace_loc:MyProject}’になる)
- “適用”をクリック
- “閉じる”をクリック
セットアップの検証
- “MyProjectTest”配下の“test”フォルダーで右クリック
- “新規”→ ”クラス”
- パッケージ:“com.example”
- 名前:“MyActivityTest”
- “完了”をクリック
- 下記ソースを追加:
package com.example; import com.example.MyActivity; import com.example.R; import com.xtremelabs.robolectric.RobolectricTestRunner; import org.junit.Test; import org.junit.runner.RunWith; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; @RunWith(RobolectricTestRunner.class) public class MyActivityTest { @Test public void shouldHaveHappySmiles() throws Exception { String hello = new MyActivity().getResources().getString(R.string.hello); assertThat(hello, equalTo("Hello World, MyActivity!")); } }
テストの実行
- “実行” → “実行構成”
- “JUnit” → “MyProjectTestConfiguration”を選択
- “実行”をクリック
実行結果
java.lang.NoClassDefFoundError: javassist/Loader
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at com.xtremelabs.robolectric.RobolectricTestRunner.isInstrumented(RobolectricTestRunner.java:137)
at com.xtremelabs.robolectric.RobolectricTestRunner.(RobolectricTestRunner.java:86)
at com.xtremelabs.robolectric.RobolectricTestRunner.(RobolectricTestRunner.java:59)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:32)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:41)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:31)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: javassist.Loader
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 33 more
なんでやねん・・・
とりあえず呟いてみた
java.lang.NoClassDefFoundError: javassist/Loader ばびょーん
@nakaji 日本語でおk
2011-07-06 00:26:24 via TweetDeck to @nakaji
@AnotherSpooky へるぷみー
2011-07-06 00:26:46 via Tween to @AnotherSpooky
@nakaji なにしてるんです?
2011-07-06 00:27:04 via YoruFukurou to @nakaji
@AnotherSpooky これですー URL JavaVMで動くAndroid用のテスティングフレームワーク
2011-07-06 00:28:41 via Tween to @AnotherSpooky
@nakaji あぁ、エミュレータ使わずにテストしようっていうフレームワークですかな?設定とかではまってるっぽいんです?
2011-07-06 00:33:14 via TweetDeck to @nakaji
@AnotherSpooky うふふ、QuickStartの通りに試しただけなんですけど、java.lang.NoClassDefFoundErrorになっちゃうんです><
2011-07-06 00:34:11 via Tween to @AnotherSpooky
@nakaji 単純にクラス見えてないだけだと思うので、設定周りかtypoしてるかとかですかなー
2011-07-06 00:35:35 via YoruFukurou to @nakaji
@AnotherSpooky もちっとよく見てみます。ありがとですー
2011-07-06 00:37:19 via Tween to @AnotherSpooky
@nakaji サンプルプロジェクトとかもあるようですけど、そちらは動いてます?
2011-07-06 01:01:33 via TweetDeck to @nakaji
@AnotherSpooky お、まだ試してないです^^;
2011-07-06 01:03:08 via Tween to @AnotherSpooky
@nakaji こちらでもちょこちょこ触ってみようかと思ったのですが、Maven必須くさいので撤退(゜д゜)
2011-07-06 01:13:13 via TweetDeck to @nakaji
@AnotherSpooky こっちはMavenよくわからんから撤退w
2011-07-06 01:13:58 via Tween to @AnotherSpooky
なるほど。全くわからん。。。
@AnotherSpookyさん、おつきあい頂きありがとうございました。
最後に
ふとググってみました。
で、この時ダウンロードするjarに罠があって、最初 robolectric-0.9.2.jar を使ってたら、javasisstとかのライブラリが入ってなくてうまく動きませんでした。
robolectric-0.9.2-all.jar ここでこっち、all がついている方をダウンロードしておかないと涙目になります。
2010-11-27 - @vvakame の日記
な、ん、だ、とう!
というわけで、早速現時点での最新版「robolectric-0.9.4-all.jar」をダウンロードしてビルドパスのライブラリーを差し替え。
そして実行してみたら・・・
ちゃんと動きました。