1. ホーム
  2. Android

Appiumチュートリアル_Android

2022-02-17 05:24:33

-バイ [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