Android自動テストフレームワーク Robotium
Android向けのテストフレームワークは、Monkey、Appium、Robotiumなど、既に数多く存在しています。MonkeyはAndroidに付属するおなじみのシステムツールで、ユーザーイベント(キー入力、タッチパネル入力、ジェスチャー入力など)を疑似的にランダムなストリームとしてシステムに送り、開発中のアプリケーションのストレステストを行っています。ソフトウェアの安定性と堅牢性をテストするための高速で効果的な方法です。Appiumのテストは、ブラックボックステストに相当します。一般的にUIロジックの正しさをテストするために使用されるこのテストフレームワークは、ビジネスロジックのフローをテストするために昇華させることはできません。
Robotium は、Android 用のオープンソースの自動テストフレームワークです。RobotiumとAndroid自体が提供するテストフレームワークを組み合わせることで、アプリのテストを自動化することができます。RobotiumのコアクラスはSoloで、コントロールに対して様々な操作を行うことができます。
環境設定
-
開発ツールは、Junitのバージョンが4.12で、パラメトリックテストに対応できるAndroidStudioを使用しています。
-
androidTestパッケージの下にあるテストコード。AndroidStudioはプロジェクトの構造をandroidTest, main, testの3つのフォルダに分割し直します。androidTestはInstrumentationのテストパッケージ、mainはソースパッケージ、testはユニットテストパッケージです。RobotiumはInstrumentationベースのテストフレームワークなので、このパッケージにテストコードを記述します。
-
build.gradleを修正します。
defaultConfig {
applicationId cfg.package
minSdkVersion cfg.minSdk
targetSdkVersion cfg.targetSdk
versionCode cfg.version_code
versionName cfg.version_name
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
cfg.}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestCompile 'com.android.support.test:rules:0.4.1'
compile 'com.jayway.android.robotium:robotium-solo:5.6.0'
}
注:ここでは testInstrumentationRunner が
android.support.test.runner.AndroidJUnitRunner
の代わりに
android.test.InstrumentationTestRunner
.
ケースコードの書き方
-
渡す
@RunWith
実装
を使用することで
@RunWith(AndroidJUnit4.class)
のアノテーションを継承する必要はありません。
ActivityInstrumentationTestCase2
クラスで、実行のパラメータ化が必要な場合は
@RunWith(Parameterized.class)
. もちろん、この方法はJunit4の実装に基づいたものです。
setUp() は、Solo インスタンスの作成や Activity の開始など、テストを開始する前の準備作業を行います。
@Before
public void setUp() throws Exception {
solo = new Solo(InstrumentationRegistry.getInstrumentation(),
activityTestRule.getActivity());
}
tearDown()のテストは、Activityの終了など、いくつかのアフターケア作業を行います。
@After
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
上記の準備ができたら、あとはテストのボディメソッドを作るだけです。便宜上、ボディメソッドは一般に test で始まります。
@Test
public void testLogin() throws Exception {
AutoCompleteTextView name = (AutoCompleteTextView) solo.getView("atv_scarid");
EditText pwd = (EditText) solo.getView("et_pwd");
solo.enterText(name, "cnsldg");
solo.enterText(pwd, "666888");
solo.clickOnView(solo.getView("bt_login"));
}
全体の構成は以下の通りです。
@RunWith(AndroidJUnit4.class)
public class LoginAcitityTest {
@Rule
public ActivityTestRule<LoginActivity> activityTestRule =
new ActivityTestRule<>(LoginActivity.class);
private Solo solo;
@Before
public void setUp() throws Exception {
solo = new Solo(InstrumentationRegistry.getInstrumentation(),
activityTestRule.getActivity());
}
@After
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
@Test
public void testLogin() throws Exception {
AutoCompleteTextView name = (AutoCompleteTextView) solo.getView("atv_scarid");
EditText pwd = (EditText) solo.getView("et_pwd");
solo.enterText(name, ""); //clear
solo.enterText(pwd, ""); //clear
solo.enterText(name, "cnsldg");
solo.enterText(pwd, "666888");
solo.clickOnView(solo.getView("bt_login"));
boolean result = solo.waitForActivity(HistoryActivity.class, 1000);
Assert.assertEquals(true, result);
}
}
実行するテストメソッドの上で右クリック
-
これは ActivityInstrumentationTestCase2 クラスを継承することで実現しています。このクラスは古い Junit3 のアプローチに基づいており、以下のようにマークアップされています。
@Deprecated
推奨しません。
public class MainActivityTest extends ActivityInstrumentationTestCase2
{
private Solo solo;
public MainActivityTest() {
super(MainActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
solo = new Solo(getInstrumentation(), getActivity());
}
@Override
protected void tearDown() throws Exception {
solo.finishOpenedActivities();
super.tearDown();
}
public void testAdd()
{
EditText et_num1 = (EditText) solo.getView("et_num1");
EditText et_num2 = (EditText) solo.getView("et_num2");
solo.enterText(et_num1, "1");
solo.enterText(et_num2, "2");
Button btn = (Button) solo.getView("btn");
TextView tv_sum = (TextView) solo.getView("tv_sum");
solo.clickOnView(btn);
//wait for the click event to take effect
solo.sleep(200);
assertEquals("3", tv_sum.getText().toString());
}
}
注意事項 テストコードはメインスレッドで実行されないので、直接UIを変更するには、Viewを取得して .
ソロクラス
- コントロールの取得
getView(int id)
getView(int id, int index) //index means the control is the first identical control on the interface
getView(String id) //value of id property defined in xml
- TextViewのテキストを検証する
TextView textView = (TextView)solo.getView("hello");
assertEquals("hello world", textView.getText().toString());
- 入力テキスト
//get the control first.
enterText(EditText editText, String text)
//index indicates the first few input boxes on the page
enterText(int index, String text)
- ダイアログを閉じたり開いたりする待ち時間
waitForDialogToClose()
waitForDialogToClose(long timeout)
waitForDialogToOpen()
waitForDialogToOpen(long timeout)
long timeout: タイムアウトをミリ秒単位で設定します。
- Activityの読み込みを検証する
// Wait for the specified Activity to appear
waitForActivity(String)
waitForActivity(String, int)
waitForActivity(Class<? extends Activity)
waitForActivity(Class<? extends Activity, int)
文字列:アクティビティ名
int:タイムアウト時間、デフォルトは20000、単位はミリ秒
クラス
//sleep for a specified time
sleep(int time)
//Search for the specified text from the current screen
searchText(String text)
//Wait for the specified Log to appear
waitForLogMessage(String logMessage)
//wait for the appearance of the control
waitForView(int id)
//Wait for the appearance of the text
waitForText(String text)
//wait for a loading condition to be met
boolean waitForCondition (Condition condition, int timeout)
- スクロールスライド操作
//scroll to the top
scrollTop()
//scroll up and down the screen
scrollUp()/scorllDown()
//scroll to the line of the ListView
scrollListToLine(AbsListView absListView, int line)
//scroll from the left side of x,y to the end of x,y coordinates
drag(float fromX, float toX, float fromY, from toY)
- その他の事業
//Screenshot, name is the parameter of the image, default path is /sdcard/Robotium-Screenshots/
takeScreenshot()
takeScreenshot(String name)
//Take a sequence for a certain period of time
takeScreenshotSequence(String name)
//close all the currently opened Activities
finishOpenedActivities()
//click the back button
goBack()
//Keep clicking the back button until you return to the specified Activity
goBackToActivity(String name)
// Put away the keyboard
hideSoftKeyboard()
// Set the orientation of the Activity to turn the screen
setActivityOrientation(int orientation)
関連
-
armeabi-v7a armeabi arm64-v8a パラメータの意味説明
-
aapt2エラー:ログを確認する(具体的な原因の探り方)
-
android.os の NetworkOnMainThreadException。
-
AndroidStudio reports Could not resolve all artifacts for configuration ':app:classpath'.
-
Android のパッケージングに失敗し、Android リソースのリンクに失敗したことを示すプロンプトが表示される
-
アプリはGoogle検索でインデックスされません Androidmanifestのクソみたいな黄色い警告
-
ArrayAdapter は、リソース ID が TextView であることが必要です。
-
android block certificate validation CertPathValidatorException: 認証パスのトラストアンカーが見つかりません
-
Android.support.v7.widget.Toolbar が見つかりませんでした。
-
アンドロイドにおけるトークンの利用
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
adb シェルがデバイスのオフラインを求めるプロンプトを表示する
-
Gradle の同期に失敗しました。com.android.tools.build:gradle が見つかりませんでした。
-
Androidで発生した問題、解決策とヒント
-
アンドロイドのエリプサイズを使用する
-
Android ProgressBarの色を変更する
-
AndroidでListViewを使ってカスタムテーブルを描画する
-
Androidカスタムドロップダウンリストボックスコントロール
-
AndroidサポートデザインライブラリのFloatingActionButtonについて
-
android.view.InflateException: バイナリXMLファイル行番号46の例外処理
-
android.viewの解決策です。