Appiumチュートリアル_Android
-バイ [email protected] 2016-05-16
I. Appiumの紹介
Appiumは、iOSとAndroidプラットフォームのネイティブ、モバイルブラウザベース、ハイブリッドアプリをサポートする、オープンソースの自動テストツールです。
1. Appiumの理念
Appiumは、4つのコンセプトに基づいてモバイルプラットフォームのテスト自動化の要件に対応するように設計されています。
1) アプリのテストを自動化する必要があるからといって、アプリを再コンパイルしたり、修正したりする必要はありません。
2) テストを実装し実行するために、特定の言語と特定のフレームワークに固定する必要はない。
3) 自動化APIをテストする場合、モバイルテストフレームワークは車輪の再発明をするべきではないでしょう。
4) モバイルテスト自動化フレームワークは、精神的にも、事実上も、名前もオープンソースであるべきです!
2. 自動化テストにAppiumを使うメリットは2つある
Appiumはプラットフォーム間で標準的な自動化APIを使用しているので、クロスプラットフォーム化する際に自分のアプリを再コンパイルしたり修正したりする必要がない。
AppiumはSelenium WebDriverがサポートするすべての言語、例えばjava, Object-C, JavaScript, Php, Python, Ruby, C#, Clojure, or Perlをサポートしており、Selenium WebDriverのApiではさらに多くの言語がサポートされています。Appiumのサポート Appiumは真のクロスプラットフォーム自動テストを可能にします。(この記事はPythonの使い方にフォーカスしています)
3. Appiumのアーキテクチャ
AppiumはNode.jsで書かれたHTTPサーバーで、iOSやAndroidなどの異なるプラットフォームと対話するために複数のWebDriverセッションを作成・管理します。
Appiumはテストを開始すると、テスト対象のデバイス(スマホ)上にサーバーを立ち上げ、Appiumサーバーからのコマンドを待ち受けます。iOSとAndroidのように、プラットフォームごとに実行方法や相互作用の仕方が異なります。そこでAppiumはスタブでそのプラットフォームに"hack"して、テストケースを実行するための指示を受け付けます。
II. Appium環境構築(Android)
1. まず用意するもの
1) jdk (長ったらしい手順はもういいや)
2) android SDK, http://developer.android.com/sdk/index.html でダウンロード、sdk toolsをダウンロード、FQが必要な場合があります、国内のダウンロードアドレスを提供してください: http://www.androiddevtools.cn/
3) appium, http://appium.io/ からダウンロード
4) nodejs、ダウンロードはこちら: https://nodejs.org/en/
5) appium lib, ダウンロード先 http://appium.io/downloads.html
LibのPythonのバージョンを選択します。Appium-Python-Client-0.22.tar.gzを選択します。
Appium は Selemium に依存しているので、Selemium Lib もダウンロードしてください:selenium-2.53.2.tar.gz https://pypi.python.org/pypi/selenium
6) python、ダウンロードはこちら https://www.python.org/ をクリックし、2.X版をダウンロードしてください。
上記のソフトウェアが全て揃ったら、ビルドのステップに移ります。
2. インストール、設定
上記のソフトを順番にインストールします。
1) android sdkをインストールしたら、環境変数の設定
ANDROID_HOMEを新規作成 D:♪ProgramFiles (x86)♪Android ♪android-sdk
PATHに追加: %ANDROID_HOME%platform-tools;%ANDROID_HOME%tools;
2) nodejs がインストールされたら、環境変数を設定します。
PATH に D:\Program Filesnodejs を追加してください。
3) appiumのインストールが完了したら、環境変数の設定を行います。
D:\Program Files (x86)\Appiumnode_modules.bin;
4) 設定したら、cmd を起動します。
node -v と入力すると、ノードのインストールバージョンが表示されます。
appium-doctorと入力すると、以下のようにappiumのインストール環境が成功したかどうかが確認できます。
5) Pythonをインストールし、C: \Python27 などの環境変数を設定し、設定が成功するかどうか、以下のように確認します。
III. 起動例(Python)
1) Appiumを起動する
コマンドラインを開き、appiumと入力し、successful start ofを表示します。
2) Android端末(またはエミュレーター)と接続する場合
3) クライアントコードを書く
ここでは、E: \PythonTestAppiumClientPythonというディレクトリにコードを配置するとします。まず、Appiumディレクトリを Appium-Python-Client-0.22.tar.gz から AppiumClientPython に、seleniumディレクトリを selenium-2.53.2.tar.gz から AppiumClientPython に展開します。
ファイル hello_appium.py を作成し、内容を編集します。
<テーブル#coding=utf-8
from appium import webdriver
desired_caps = {}です。
desired_caps['platformName'] = 'Android'。
desired_caps['platformVersion'] = '4.4.2' です。
desired_caps['deviceName'] = 'Androidエミュレータ'
desired_caps['appPackage'] = 'com.android.calculator2'
desired_caps['appActivity'] = '.calculator'。
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
ドライバー.find_element_by_name("1").click()
ドライバー.find_element_by_name("5").click()
ドライバー.find_element_by_name("9").click()
ドライバー.find_element_by_name("9").click()
ドライバー.find_element_by_name("5").click()
ドライバー.find_element_by_name("+").click()
ドライバー.find_element_by_name("6").click()
ドライバー.find_element_by_name("=").click()
ドライバ.quit()
4) 実行
コマンドラインを開き、E: \PythonTestAppiumClientPythonにcdし、python hell_appium.pyを実行すると、通常は携帯電話がコードコントロールに従って、計算機を開き、ボタンを一つずつクリックすると計算が完了するのが見えます。
IV. Appiumのドキュメント
1. インストール後、アプリを開く
<テーブルインポート os
from appium import webdriver
APK_PATH = 'apk/my-debug.apk' です。
command_executor_url = 'http://localhost:4723/wd/hub'
希望するキャップ数 = {}
desired_caps['platformName'] = 'Android'。
desired_caps['platformVersion'] = '5.0' です。
desired_caps['deviceName'] = 'アンドロイドエミュレータ'
desired_caps['app'] = os.path.abspath(APK_PATH)
driver = webdriver.Remote(COMMAND_EXECUTOR_URL, desired_caps)
2. コントロールの検索
1) 名前で探す
btn = driver.find_element_by_name("+")
2) IDで検索する
start_btn =driver.find_element_by_id('com.cn21.myapp:id/instruction_close_btn')
または start_btn = driver.find_element_by_id('instruction_close_btn')
3) クラス名で検索する
child_text = parent.find_element_by_class_name('android.widget.TextView')
4) android_uiautomatorによる検索
start_btn =driver.find_element_by_android_uiautomator('new UiSelector().clickable(true)')です。
上記の find_element_by_XX はすべて、条件に一致する最初のコントロールを返します。複数のコントロールを返したい場合は、リストを返す find_elements_by_XX を呼び出すとよいでしょう。
注意:条件に一致するコントロールが見つからない場合は、例外がスローされます。
(5) ノードを見つけ、例外を返したくない場合は、単に関数を書きます。
<テーブルdef find_element_by_id_no_except(driver, id):
要素 = なし
を試してみてください。
element = driver.find_element_by_id(id)
except Exception,e:
print Exception, ':', e
要素を返す
3. ボタンクリックをシミュレートする
login_btn.click()
注:アニメーションを待つ必要があるクリックや、ネットワークへのリクエストは、しばらく待つことをお勧めします。
<テーブルインポート時間
time.sleep(2) # 2秒間のスリープ
4. テキストを入力するための入力ボックス
user_input.send_keys('123456')
注意:Androidでは、正しく入力する場合はシステム独自の入力メソッドを使用する必要があります。サードパーティ製の入力メソッドでは正しく入力できません。
5. 戻るボタンをタップするシミュレーション
ドライバ.press_keycode(4)
ボタンの位置はAndroidのKeyEvent.javaで定義されているので、他のAndroidのボタンもサポートされています。
6. ドライバを閉じる
ドライバ.quit()
注意: ドライバを閉じるのを忘れないようにしないと、次回接続時に Appium が前回閉じていないと判断して例外が発生し、セッションの作成に失敗する可能性があります。
コード内で例外が発生し、それを閉じないようにするには、例外をキャッチしたときにそれを閉じるようにします。
7. スライド式インターフェース
次の例は、画面の中央をクリックして上に引き上げる(これでリストの下のコンテンツを見るのと同じことになる)ことを実演しています。
<テーブルfrom appium.webdriver.common.touch_action import TouchAction
def test_scroll_down(driver):
screen = driver.get_window_size()
アクション = TouchAction(ドライバ)
action.press(x=screen['width']/2,y=screen['height']/2)
action.move_to(x=0,y=-screen['height']/10)
action.release()
action.perform()
ちょっと待って、正しさを検証するためにインターフェースのプロパティを取得するにはどうしたらいいのでしょうか?
8. インターフェースプロパティ、コントロールプロパティの取得
1) 現在のアクティビティ名を取得する
アクティビティ = driver.current_activity
2) 画面の幅と高さを取得する
screen = driver.get_window_size()
3) コントロールのテキストを取得する
mobile_name.get_attribute('text') または mobile_name.text
4) コントロールクラス名の取得
mobile_name.get_attribute('className')を使用します。
5) コントロールが表示されているかどうかの判定
mobile_name.is_displayed()または mobile_name.get_attribute('displayed')
6) コントロールの位置を取得する
モバイル名.位置
7) コントロールのサイズを取得する
モバイル名.サイズ
8) 制御子ノードの検索
parent.find_elements_by_class_name('android.widget.TextView')です。
同様に、コントロールを見つけるための他のメソッドは、子ノードを見つけるためにも適用されます。
ポストインタラクションの検証では、特定のデータの内容を検証できない場合、現在のアクティビティ、テキスト、リストが空かどうかなどを検証することができます。
その他の参考文献はこちら http://blog.csdn.net/crisschan/article/details/50416860
V. ユニットテストフレームワークと連動したユースケースの書き方
Pythonにはユニットテスト用のunittestが付属しており、これはJUnitと似た構造になっています。
テストクラスは unittest.TestCase を継承する必要があり、メソッド setUp はテストの初期化に使われ、各ユースケースの開始前に呼ばれ、 tearDown はユースケースの終了時に呼ばれ、 test で始まる各関数はユースケースとして扱われます。
test_random.py
<テーブルインポートランダム
unittestをインポートする
class TestSequenceFunctions(unittest:)
def setUp(self):
self.seq = range(10)
def test_shuffle(self):
# シャッフルされたシーケンスが要素を失わないことを確認する
ランダム.シャッフル(self.seq)
self.seq.sort()
self.assertEqual(self.seq, range(10))
# immutable sequence の場合は例外が発生するはずです。
self.assertRaises(TypeError, random.shuffle, (1,2,3))
def test_choice(self):
要素 = random.choice(self.seq)です。
self.assertTrue(self.seq内の要素)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(要素がself.seqにない)
if __name__ == '__main__':
unittest.main(verbosity=2)
このテストを実行する: python test_random.py テストの結果を見る
上記の結果から、2つのユースケースがテストに合格し、1つのユースケースが不合格であることがわかります。
testで始まるテストファイルをディレクトリに複数記述し、以下のコマンドで全てのテストクラスを実行することができます。
python -m unittest discover ・・・ -v
VI. 完全な例
1. ログインとログアウトの機能テスト
test_myapp_login_logout.py
<テーブル
#coding=utf-8
#
ログインとログアウトの機能テスト
#
ユースケース1:クイックログイン、ログイン後のActivityがMainActivityであることを確認する。
# 使用例 2: 通常ログイン、ユーザー名とパスワードを入力、ログイン後のアクティビティが MainActivity であることを確認する。
# 使用例 3: クイックログインとログアウト、ログアウト後のアクティビティがLoginActivityであることを確認する。
インポート
ユニテスト
インポート
appium_myapp
インポート
appium_util
から
アピウム
インポート
ウェブドライバ
インポート
os
クラス
LoginLogoutTest(unittest.TestCase):
##
デフ
setUp(
自己
):
#print('インストール中 ...')
desired_caps = {}とする。
desired_caps[ ]を指定します。
'プラットフォーム名'
] =
'アンドロイド'
希望キャップ
'プラットフォームバージョン'
] =
'5.0'
希望キャップ
'deviceName'
] =
'アンドロイドエミュレーター'
希望キャップ
'アプリ'
] = os.path.abspath(appium_myapp.APK_PATH)
自己
.driver = webdriver.Remote(appium_util.COMMAND_EXECUTOR_URL, desired_caps)
デフ
tearDown(
自己
):
自己
.driver.quit()
デフ
test_FastLogin(
自己
):
appium_myapp.tree_document(
自己
.driver)
appium_myapp.quick_login()。
自己
.driver)
自己
.assertTrue(
自己
.driver.current_activity.endswith()
'MainActivity'(メインアクティビティ
))
デフ
test_SlowLigin(
自己
):
appium_myapp.tree_document(
自己
.driver)
appium_myapp.slow_login()。
自己
.driver)
自己
.assertTrue(
自己
.driver.current_activity.endswith()
'MainActivity'(メインアクティビティ
))
デフ
test_Logout(
自己
):
appium_myapp.tree_document(
自己
.driver)
appium_myapp.quick_login()。
自己
.driver)
もし
(
自己
.driver.current_activity.endswith()
'MainActivity'(メインアクティビティ
)):
appium_myapp.test_logout()
自己
.driver)
自己
.assertTrue(
自己
.driver.current_activity.endswith()
'LoginActivity'(ログインアクティビティ
))
もし
__name__ ==
'__main__'
:
unittest.main()
冗長性
=
<スパン
2
)
2. 自動乱雑ドットテストクラッシュ
auto_test_myapp.py
<テーブル
#coding=utf-8
インポート
ランダム
インポート
時間
インポート
トレースバック
インポート
appium_myapp
デフ
auto_interact(driver)です。
アクティビティ = driver.current_activity
#
<スパン
一定確率でスライド、リターンボタン、クリック
レート = random.random()
もし
レート <
0.1
:
プリント
アクティビティ+α
' スクロールダウン
appium_myapp.test_scroll_down(driver)
エリフ
レート <
<スパン
0.2
:
プリント
アクティビティ+α
' スクロールアップ
appium_myapp.test_scroll_up(driver)
エリフ
レート <
0.3
:
プリント
アクティビティ+α
' キーバック'
ドライバ.press_keycode(
4
)
さもなくば
:
btn_list = driver.find_elements_by_android_uiautomator()
'新しいUiSelector().clickable(true)'。
)
もし
(
len
(btn_list) >
0
):
index = random.randint()
0
,
len
(btn_list)・・・。
1
)
プリント
アクティビティ+α
' クリックボタンのインデックス = %d'
% (インデックス,)
btn_list[index].click()を実行します。
デフ
main():
ドライバー =
なし
試す
:
driver = appium_myapp.install_app()
time.sleep(appium_myapp.LONG_WAIT_TIME)
appium_myapp.tree_document(driver)
appium_myapp.quick_login(ドライバ)
ステップ =
<スパン
0
間に
ステップ <
100
:
もし
(driver.current_activity.endswith()
'LoginActivity'(ログインアクティビティ
)):
appium_myapp.test_login(driver)
エリフ
(driver.current_activity.endswith()
'.Launcher'
)):
ドライバ.background_app(
1
)
ドライバ.launch_app()
さもなくば
:
auto_interact(ドライバ)
time.sleep(appium_myapp.CLICK_WAIT_TIME)
ステップ +=
<スパン
1
#
<スパン
正常終了
ドライバ.quit()
ただし
例外
, e:
プリント
例外
,
":"
, e
traceback.print_exc()
#
例外終了
もし
(ドライバ !
なし
):
ドライバ.quit()
もし
__name__ ==
'__main__'
:
に対して
i
で
<スパン
範囲
(
<スパン
20000
):
試みる
:
main()
ただし
例外
, e:
プリント
例外
,
":"
, e
traceback.print_exc()
注:Pythonのコードを書きやすくするために、Javaと同じように簡単にコードを編集できるPyCharm IDEの使用をお勧めします。
VII. 参考文献
1) 公式サイト http://appium.io/index.html
2) appium/python-client の使用法に関するドキュメント https://github.com/appium/python-client
3) appium用のandroid環境の構築 http://www.cnblogs.com/qiaoyeye/p/5131382.html
4) Appiumモバイル自動化テスト(IV) http://www.cnblogs.com/fnng/p/4579152.html
5) AppiumPython API http://blog.csdn.net/crisschan/article/details/50416860
6)appiumの共通メソッドのまとめ http://www.cnblogs.com/fanxiaojuan/p/4882676.html
関連
-
ADBサーバーがACKしない問題を解決しました。
-
アプリの実行エラー。デフォルトのアクティビティが見つかりません
-
Android studio java ファイル表示 j burst red
-
RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi Androidの開発において、アクティビティを開始できません。
-
android:ems="10 "の意味。
-
adb push 権限拒否の解決策
-
Androidです。ViewPagerで現在のインターフェイスのFragmentを取得する
-
Androidリストウィジェット開発詳細
-
AndroidのSMSメッセージ
-
ColorDrawableの簡単な使い方
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
Android のリストビューでアダプタを使用しているときに null オブジェクトの参照に対して仮想メソッド xxxxxxxx を呼び出そうとする問題が解決されました。
-
Androidでの録音とMP3へのローカルトランスコード
-
Android フロントカメラのビデオ録画に失敗しました (MediaRecorder: start failed: -19)
-
ログアウトしたエラー: java.lang.RuntimeException: アクティビティを開始できません ComponentInfo
-
ArrayAdapter のソリューションでは、リソース ID が TextView である必要があります。
-
パッケージが見つからないエラー 解決策と jdk の切り替え
-
オーディオとビデオを再生するための資産と生でAndroidの練習
-
Androidスレッドの詳細
-
Android SpinnerのsetSelectionとonItemSelectedイベントのトリガー順について
-
Android開発日記】SwipeRefreshLayoutにプルアップ読み込み機能を追加しました