狠狠撸
Submit Search
Unit test in android
5 likes
1,930 views
Tatsuya Maki
Unit test in Android using Robolectric.
Technology
Read more
1 of 92
Download now
Download to read offline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
More Related Content
What's hot
(20)
KEY
Clojrue 13 testing
Kiyotaka Kunihira
?
PDF
闯补惫补セキュアコーディングセミナー东京第3回演习の解説
JPCERT Coordination Center
?
PDF
Async design with Unity3D
Kouji Hosoda
?
PDF
今日からはじめる骋笔补谤蝉
fumokmm
?
PDF
Synthesijer hls 20150116
Takefumi MIYOSHI
?
PDF
あんなテスト、こんなテスト(this and that about testing)
Takuya Tsuchida
?
PDF
xUnit Test Patterns - Chapter19
Takuto Wada
?
PDF
About Jobs
Shinichi Kozake
?
PDF
Qunit再入門 (Version 1.10.0 編)
Koji Nakamura
?
PDF
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
なおき きしだ
?
PDF
贰肠尘补蝉肠谤颈辫迟2015とその周辺について
豊明 尾古
?
PDF
Easy Going Groovy(Groovyを気軽に使いこなそう)
Uehara Junji
?
PPTX
Javascript basic code
Shinsuke Matsuda
?
PDF
Ajax 応用
Katsuyuki Seino
?
PDF
痴别谤颈濒补迟辞谤と厂测蝉迟别尘颁
Mr. Vengineer
?
PDF
基礎からのCode Contracts
Yoshifumi Kawai
?
PDF
Apache Wicketのユニットテスト機能
Hiroto Yamakawa
?
PDF
鲍苍颈迟测で覚える颁#
Masamitsu Ishikawa
?
PDF
関西笔丑辫勉强会の濒颈尘别の话
Hisateru Tanaka
?
PDF
Android Lecture #03 @PRO&BSC Inc.
Yuki Higuchi
?
Clojrue 13 testing
Kiyotaka Kunihira
?
闯补惫补セキュアコーディングセミナー东京第3回演习の解説
JPCERT Coordination Center
?
Async design with Unity3D
Kouji Hosoda
?
今日からはじめる骋笔补谤蝉
fumokmm
?
Synthesijer hls 20150116
Takefumi MIYOSHI
?
あんなテスト、こんなテスト(this and that about testing)
Takuya Tsuchida
?
xUnit Test Patterns - Chapter19
Takuto Wada
?
About Jobs
Shinichi Kozake
?
Qunit再入門 (Version 1.10.0 編)
Koji Nakamura
?
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
なおき きしだ
?
贰肠尘补蝉肠谤颈辫迟2015とその周辺について
豊明 尾古
?
Easy Going Groovy(Groovyを気軽に使いこなそう)
Uehara Junji
?
Javascript basic code
Shinsuke Matsuda
?
Ajax 応用
Katsuyuki Seino
?
痴别谤颈濒补迟辞谤と厂测蝉迟别尘颁
Mr. Vengineer
?
基礎からのCode Contracts
Yoshifumi Kawai
?
Apache Wicketのユニットテスト機能
Hiroto Yamakawa
?
鲍苍颈迟测で覚える颁#
Masamitsu Ishikawa
?
関西笔丑辫勉强会の濒颈尘别の话
Hisateru Tanaka
?
Android Lecture #03 @PRO&BSC Inc.
Yuki Higuchi
?
Similar to Unit test in android
(20)
KEY
テスト初心者础苍诲谤辞颈诲别谤のためのソフトウェアテスト入门
Satoshi Watanabe
?
PPTX
Junit4
ichikaz3
?
PDF
Nds#24 単体テスト
Kazumune Katagiri
?
KEY
GroovyなAndroidテスト #atest_hack
Takahiro Yoshimura
?
PDF
C# から java へのプログラム移植で体験したtddの効果は?
Shinichi Hirauchi
?
PDF
Androidテスティング実践3 ユニットテスト?CI編
株式会社 NTTテクノクロス
?
PDF
Android test tutorial
Kazuaki Ueda
?
PDF
Unit testing JavaScript with JUnit/JavaFX
Shinya Mochida
?
PDF
Introduction to Spock
Takahiro Sugiura
?
PDF
奥别产アプリの动的部分に着目したグレーボックス统合テストとテンプレート変数カバレッジの提案
Kazunori Sakamoto
?
KEY
JUnit実践入門 xUnitTestPatternsで学ぶユニットテスト
Shuji Watanabe
?
PPTX
アプリの不具合を少なくするために
Kenichi Tatsuhama
?
KEY
Unit testで定時帰宅!
Funato Takashi
?
PDF
Db unitを使って なれる! レガシーコードメンテナー
Youtarou TAKAHASHI
?
PDF
XunitとMoq 公開用
ESM SEC
?
PDF
レガシーコード改善はじめました 横浜道場
Hiroyuki Ohnaka
?
PDF
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
nkazuki
?
PDF
[豆ナイト]Java small object programming
Yuichi Hasegawa
?
PDF
エクストリームエンシ?ニア4
T-arts
?
PDF
Kink: invokedynamic on a prototype-based language
Taku Miyakawa
?
テスト初心者础苍诲谤辞颈诲别谤のためのソフトウェアテスト入门
Satoshi Watanabe
?
Junit4
ichikaz3
?
Nds#24 単体テスト
Kazumune Katagiri
?
GroovyなAndroidテスト #atest_hack
Takahiro Yoshimura
?
C# から java へのプログラム移植で体験したtddの効果は?
Shinichi Hirauchi
?
Androidテスティング実践3 ユニットテスト?CI編
株式会社 NTTテクノクロス
?
Android test tutorial
Kazuaki Ueda
?
Unit testing JavaScript with JUnit/JavaFX
Shinya Mochida
?
Introduction to Spock
Takahiro Sugiura
?
奥别产アプリの动的部分に着目したグレーボックス统合テストとテンプレート変数カバレッジの提案
Kazunori Sakamoto
?
JUnit実践入門 xUnitTestPatternsで学ぶユニットテスト
Shuji Watanabe
?
アプリの不具合を少なくするために
Kenichi Tatsuhama
?
Unit testで定時帰宅!
Funato Takashi
?
Db unitを使って なれる! レガシーコードメンテナー
Youtarou TAKAHASHI
?
XunitとMoq 公開用
ESM SEC
?
レガシーコード改善はじめました 横浜道場
Hiroyuki Ohnaka
?
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
nkazuki
?
[豆ナイト]Java small object programming
Yuichi Hasegawa
?
エクストリームエンシ?ニア4
T-arts
?
Kink: invokedynamic on a prototype-based language
Taku Miyakawa
?
Ad
Recently uploaded
(9)
PDF
安尾 萌, 藤代 裕之, 松下 光範. 協調的情報トリアージにおけるコミュニケーションの影響についての検討, 第11回データ工学と情報マネジメントに関する...
Matsushita Laboratory
?
PPTX
勉強会_ターミナルコマント?入力迅速化_20250620. pptx. .
iPride Co., Ltd.
?
PPTX
Vibe Codingを始めよう ?Cursorを例に、ノーコードでのプログラミング体験?
iPride Co., Ltd.
?
PDF
論文紹介:Unbiasing through Textual Descriptions: Mitigating Representation Bias i...
Toru Tamaki
?
PPTX
色について.pptx .
iPride Co., Ltd.
?
PDF
論文紹介:AutoPrompt: Eliciting Knowledge from Language Models with Automatically ...
Toru Tamaki
?
PDF
安尾 萌, 北村 茂生, 松下 光範. 災害発生時における被害状況把握を目的とした情報共有システムの基礎検討, 電子情報通信学会HCGシンポジウム2018...
Matsushita Laboratory
?
PDF
安尾 萌, 松下 光範. 環境馴致を計量可能にするための試み,人工知能学会第4回仕掛学研究会, 2018.
Matsushita Laboratory
?
PDF
Forguncy 10 製品概要資料 - ノーコードWebアプリ開発プラットフォーム
フォーガンシー
?
安尾 萌, 藤代 裕之, 松下 光範. 協調的情報トリアージにおけるコミュニケーションの影響についての検討, 第11回データ工学と情報マネジメントに関する...
Matsushita Laboratory
?
勉強会_ターミナルコマント?入力迅速化_20250620. pptx. .
iPride Co., Ltd.
?
Vibe Codingを始めよう ?Cursorを例に、ノーコードでのプログラミング体験?
iPride Co., Ltd.
?
論文紹介:Unbiasing through Textual Descriptions: Mitigating Representation Bias i...
Toru Tamaki
?
色について.pptx .
iPride Co., Ltd.
?
論文紹介:AutoPrompt: Eliciting Knowledge from Language Models with Automatically ...
Toru Tamaki
?
安尾 萌, 北村 茂生, 松下 光範. 災害発生時における被害状況把握を目的とした情報共有システムの基礎検討, 電子情報通信学会HCGシンポジウム2018...
Matsushita Laboratory
?
安尾 萌, 松下 光範. 環境馴致を計量可能にするための試み,人工知能学会第4回仕掛学研究会, 2018.
Matsushita Laboratory
?
Forguncy 10 製品概要資料 - ノーコードWebアプリ開発プラットフォーム
フォーガンシー
?
Ad
Unit test in android
1.
ユニットテスト入門 Androidアプリケーションへのユニットテスト導入
2.
Tatsuya Maki Android Application
Developer
3.
はなすこと 1. ユニットテストの導入 2. 効率的なユニットテスト 3.
ユニットテストの罢颈辫蝉
4.
ユニットテストの導入 1
5.
Q. ユニットテストとは
6.
A. メソッドなど小さな単位で行うテスト
7.
public static String
fizzbuzz(int value) { String message; if (value % 15 == 0) { message = "FizzBuzz"; } else if (value % 5 == 0) { message = "Buzz"; } else if (value % 3 == 0) { message = "Fizz"; } else { message = String.valueOf(value); } return message; } FizzBuzz
8.
@Test public void fizzbuzzShouldReturnBuzzWhenValueIs10()
{ // 実行結果 String actualValue = fizzbuzz(10); ! // 期待結果 String expectedValue = "Buzz"; ! // テスト assertThat(actualValue, is(expectedValue)); } FizzBuzzTest
9.
Androidでの問題点 1. デバイスが必須 2. 実行速度が遅い 3.
テストしにくい
10.
Robolectric http://robolectric.org/
12.
遅い DalvikVM 必要 JUnit3 速い JVM 不要 JUnit4 AndroidTestCase 実行速度 VM デバイス JUnit Robolectric
14.
TextView Shadow getText() Hello, world.
15.
@Implements(TextView.class) class MyShadowTextView extends
ShadowView { ! @Implementation public CharSequence getText() { return "Hello, Robolectric!"; } ! } Shadowの例
16.
@Test @Config(shadows = {
MyShadowTextView.class }) public void getTextShouldReturnHelloRobolectric() { // SetUp Context context = Robolectric.application.getApplicationContext(); TextView textView = new TextView(context); // Exercise CharSequence actualText = textView.getText(); // Verify assertEquals(actualText, "Hello, Robolectric!"); } Shadowの利用例
17.
まとめ 1. デバイスが不要 2. JVM上で動作する 3.
厂丑补诲辞飞オブジェクト
18.
効率的なユニットテスト 2
19.
3つのツール 1. FEST 2. Mockito 3.
EclEmma
20.
FEST https://code.google.com/p/fest/
21.
蚕.アサーションとは
22.
A. 実行結果と期待結果を比較検証する宣言
23.
// 実行結果 int actualValue
= 10 / 2; ! // 期待結果 int expectedValue = 5; ! // "10 / 2"が"5"と等しくなることを表明 assertEquals(actualValue, expectedValue); アサーションの例
24.
FESTのメリット 1. アサーションの记述が容易 2. エラーメッセージが明确 3.
础苍诲谤辞颈诲と亲和性が高い
25.
アサーションの记述が容易
26.
// Exercise List<String> devices
= new ArrayList<String>(); devices.add("Nexus 5"); devices.add("Nexus 7"); ! ! // Verify assertNotNull(devices); assertEquals(2, devices.size()); assertTrue(devices.contains("Nexus 5")); JUnit
27.
// Exercise List<String> devices
= new ArrayList<String>(); devices.add("Nexus 5"); devices.add("Nexus 7"); ! ! // Verify assertThat(devices, is(notNullValue())); assertThat(devices.size(), is(equalTo(2))); assertThat(devices, hasItem("Nexus 5")); Hamcrest
28.
// Exercise List<String> devices
= new ArrayList<String>(); devices.add("Nexus 5"); devices.add("Nexus 7"); ! ! // Verify assertThat(devices) .isNotNull() .hasSize(2) .contains("Nexus 5"); FEST
29.
エラーメッセージが明确
30.
// テストコード List<String> devices
= new ArrayList<String>(); devices.add("Nexus 5"); devices.add("Nexus 7"); assertTrue(devices.contains("Nexus 4")); ! ! // エラーメッセージ java.lang.AssertionError ! ! ! ! JUnit
31.
// テストコード List<String> devices
= new ArrayList<String>(); devices.add("Nexus 5"); devices.add("Nexus 7"); assertThat(devices, hasItem("Nexus 4")); ! ! // エラーメッセージ java.lang.AssertionError: Expected: a collection containing "Nexus 4" but: was "Nexus 5", was "Nexus 7” ! ! Hamcrest
32.
// テストコード List<String> devices
= new ArrayList<String>(); devices.add("Nexus 5"); devices.add("Nexus 7"); assertThat(devices).contains("Nexus 4"); ! ! // エラーメッセージ java.lang.AssertionError: expecting: <['Nexus 5', 'Nexus 7']> to contain: <['Neuxus 4']> but could not find: <['Neuxus 4']> FEST
33.
础苍诲谤辞颈诲と亲和性が高い
34.
// テストコード TextView textView
= (TextView) activity .findViewById(R.id.text_view); assertThat(textView.getText()) .isEqualTo(activity.getString(R.string.message)); assertThat(textView.getVisibility()) .isEqualTo(View.VISIBLE); ! ! // エラーメッセージ org.junit.ComparisonFailure: expected: <[0]> but was: <[8]> FEST
35.
// テストコード TextView textView
= (TextView) activity .findViewById(R.id.text_view); assertThat(textView) .hasText(R.string.message) .isVisible(); ! ! ! // エラーメッセージ java.lang.AssertionError: Expected to be visible but was gone ! FEST Android
36.
Mockito http://mockito.org/
37.
Q. モックオブジェクトとは
38.
A. オブジェクトの呼び出しを検証する
39.
class MockInputStream extends
InputStream { ! private boolean mIsRead; private boolean mIsClosed; ! @Override public int read() throws IOException { mIsRead = true; return 0; } ! public boolean isRead() { return mIsRead; } ! @Override public void close() throws IOException { mIsClosed = true; } ! public boolean isClosed() { return mIsClosed; } ! } モックオブジェクトの例
40.
Mockitoでできること 1. 呼び出しの検証 2. 振る舞いの変更 3.
フィールドの変更
41.
// モックオブジェクトの生成 InputStream mocked
= mock(InputStream.class); // InputStreamをクローズする mocked.close(); ! // closeメソッドの呼び出し検証 verify(mocked).close(); 呼び出しの検証
42.
振る舞いの変更 // モックオブジェクトの作成 InputStream mocked
= mock(InputStream.class); ! // 戻り値の変更 when(mocked.read()).thenReturn(-1); ! // 例外の送出 when(mocked.read()).thenThrow(new IOException()); ! // ロジックの変更 when(mocked.read()).thenAnswer(new Answer<Integer>() { ! @Override public Integer answer(InvocationOnMock invocation) throws Throwable { int length; ... return length; } });
43.
フィールドの変更 // 内部にInputStreamを保持するクラス MyObject object
= new MyObject(); // フィールドの取得 InputStream stream = (InputStream) Whitebox .getInternalState(object, “mStream"); ! // スパイオブジェクトの作成 Socket spied = spy(stream); ! // フィールドの変更 Whitebox .setInternalState(object, "mStream", spied);
44.
Mockitoでできないこと 1. ?nalクラス/メソッドのモック 2. privateメソッドのモック 3.
蝉迟补迟颈肠メソッドのモック
45.
EclEmma http://www.eclemma.org/
46.
Q. カバレッジとは
47.
A. テストがどれだけ網羅できているか
48.
カバレッジの種類 C0: 命令網羅率 C1: 分岐網羅率 C2:
条件网罗率
49.
EclEmmaで測定できるもの C0: 命令網羅率 C1: 分岐網羅率 C2:
条件网罗率
50.
EclEmmaで測定できないもの C0: 命令網羅率 C1: 分岐網羅率 C2:
条件网罗率
51.
ユニットテストの罢颈辫蝉 3
52.
Q. void型メソッドをテストしたい
53.
A. 別のメソッドを使って検証する
54.
List<String> list =
new MyList<String>(); list.add("Android"); // 別のメソッドで検証 assertThat(list).hasSize(1); サンプル
55.
A. メソッドの呼び出しを検証する
56.
InputStream mocked =
mock(InputStream.class); IoUtils.close(mocked); ! // closeメソッドの呼び出し検証 verify(mocked).close(); サンプル
57.
Q. privateメソッドをテストしたい
58.
A. 諦める
59.
A. package privateに変更する
60.
// privateメソッドなので呼び出せない private String
buildMessage() { String message; // do something return message; } ! // package privateに変更 String buildMessage() { String message; // do something return message; } サンプル
61.
Q. 非同期処理をテストしたい
62.
A. CountDownLatchを使う
63.
// timeoutを指定 @Test(timeout =
1000) public void test() throws InterruptedException{ CountDownLatch latch = new CountDownLatch(1); AsyncProcess.execute(new Callback() { @Override public void onComplete() { // 処理完了時にcountDownを呼出 latch.countDown(); } }); ! // 処理完了まで待機 latch.await(); ! ... } サンプル
64.
Q. HTTP通信の外部依存をなくしたい
65.
A. FakeHttpLayerを使う HttpClientの場合
66.
// 常に同じレスポンスを返却 FakeHttpLayer layer
= Robolectric.getFakeHttpLayer(); layer.setDefaultHttpResponse(200, "Hello, World!"); ! ! // 順番にレスポンスを変更 FakeHttpLayer layer = Robolectric.getFakeHttpLayer(); layer.addPendingHttpResponse(200, "Hello, Nexus 4!"); layer.addPendingHttpResponse(200, "Hello, Nexus 5!"); layer.addPendingHttpResponse(200, "Hello, Nexus 7!"); ! ! // 動的にレスポンスを変更 FakeHttpLayer layer = Robolectric.getFakeHttpLayer(); layer.addHttpResponseRule(new MyResponseRule()); サンプル
67.
A. URLStreamHandlerを設定する HttpURLConnectionの場合
68.
class StubURLStreamHandler extends
URLStreamHandler { @Override protected URLConnection openConnection(URL url) throws IOException { // HttpURLConnectionを作成 return new StuHttpURLConnection(url); } } ! class StubURLStreamHandlerFactory implements URLStreamHandlerFactory { @Override public URLStreamHandler createURLStreamHandler( String protocol) { // URLStreamHandlerを作成 return new StubURLStreamHandler(); } } ! // URLStreamHandlerFactoryを設定 URL.setURLStreamHandlerFactory( new StubURLStreamHandlerFactory()); サンプル
69.
Q. データベースのスローテストを解消したい
70.
A. インメモリデータベースを使う
71.
// DatabaseMapのinterfaceを実装 class MemoryDatabaseMap
implements DatabaseMap { ! @Override public String getDriverClassName() { return JDBC.class.getName(); } ! @Override public String getConnectionString(File file) { // インメモリデータベースを使うように指定 return "jdbc:sqlite::memory:"; } ! @Override public String getMemoryConnectionString() { // インメモリデータベースを使うように指定 return "jdbc:sqlite::memory:"; } ! @Override public int getResultSetType() { return ResultSet.TYPE_FORWARD_ONLY; } ! @Override public String getSelectLastInsertIdentity() { return "SELECT last_insert_rowid() AS id"; } ! } サンプル
72.
// UsingDatabaseMapで指定 @UsingDatabaseMap(MemoryDatabaseMap.class) @RunWith(RobolectricTestRunner.class) class DatabaseHelperTest
{ ... } サンプル
73.
Q. Activityをテストしたい
74.
A. ActivityControllerを使う
75.
// ActivityControllerを生成 ActivityController<MainActivity> controller
= Robolectric.buildActivity(MainActivity.class); ! // Activityの生成 controller.create().start().resume().visible(); ! // Activityの取得 MainActivity activity = controller.get(); // Activityの操作 TextView textView = (TextView) activity .findViewById(R.id.text_view); ... ! // Activityの破棄 controller.pause().stop().destroy(); サンプル
76.
Q. Serviceを検証したい
77.
A. ライフサイクルに合わせてメソッドを呼び出す
78.
private MyService mService; ! @Before public
void setUp() { // Serviceを生成 mService = new MyService(); mService.onCreate(); } @Test public void test() { // Serviceを実行 Intent intent = new Intent(Intent.ACTION_SEARCH); intent.putExtra(SearchManager.QUERY, "Hello, World!"); mService.onStartCommand(intent, 0, 0); } ! @After public void tearDown() { // Serviceを破棄 mService.onDestroy(); } サンプル
79.
Q. Widgetのテストをしたい
80.
A. ShadowAppWidgetManagerを使う
81.
// ShadowAppWidgetManagerの生成 Context context
= Robolectric.application .getApplicationContext(); AppWidgetManager manager = AppWidgetManager.getInstance(context); ShadowAppWidgetManager shadowManager = Robolectric.shadowOf(manager); // Widgetの生成 int widgetId = shadowManager.createWidget( MyWidgetProvider.class, R.layout.activity_main); // Viewの取得 View widgetView = shadowManager.getViewFor(widgetId); ! ... サンプル
82.
Q. ContentProviderのテストをしたい
83.
A. ShadowContentResolverを使う
84.
// ShadowContentResolverの生成 ContentResolver resolver
= Robolectric.application.getContentResolver(); ShadowContentResolver shadowResolver = Robolectric.shadowOf(resolver); ! // ContentProviderの登録 shadowResolver.registerProvider( “com.example.android.unittest” new MyContentProvider()); ... // INSERTステートメントの取得 List<InsertStatement> insertStatements = shadowResolver.getInsertStatements(); // UPDATEステートメントの取得 List<UpdateStatement> updateStatements = shadowResolver.getUpdateStatements(); // DELETEステートメントの取得 List<DeleteStatement> deleteStatements = shadowResolver.getDeleteStatements(); // notifyChangeで通知されたURIの取得 List<NotifiedUri> notifiedUris = shadowResolver.getNotifiedUris(); サンプル
85.
Q. BroadcastReceiverのテストをしたい
86.
A. ShadowApplicationを使う
87.
// 事前処理 ShadowApplication shadowApplication
= Robolectric.getShadowApplication(); Context context = Robolectric.application.getApplicationContext(); // 登録済みBroadcastReceiverの取得 List<Wrapper> registered = shadowApplication.getRegisteredReceivers(); // Intentに該当するBroadcastReceiverの取得 Intent intent = new Intent("MY_ACTION"); List<BroadcastReceiver> receivers = shadowApplication.getReceiversForIntent(intent); // Intentを擬似的に受信 BroadcastReceiver receiver = receivers.get(0); receiver.onReceive(context, intent); サンプル
88.
まとめ 4
89.
まとめ 1. 課題はRobolectricで解消できる 2. 既存のライブラリを使って効率的に 3.
大体テストできるので书いてみよう
90.
Q. おすすめの本はなんですか
92.
https://github.com/t28hub/UnitTestInAndroid/
Download