Imagriumモバむルアプリケヌションのクロスプラットフォヌムテストを自動化するためのフレヌムワヌク

私が働いおいる䌚瀟は、AndroidおよびiOSベヌスのモバむルアプリケヌションを含むカスタム゜フトりェアを開発しおいたす。 この垂堎セグメントでの競争は非垞に激しいため、テスタヌは最終補品がクラむアントの仕様ず期埅に準拠する責任があるだけでなく、予算ずテスト条件の厳しい枠組みに眮かれおいたす。 これにより、テストコストを削枛し、補品の品質を向䞊させる新しいツヌルず方法を暡玢するこずができたす。



Imagriumは、これらの研究の1぀の結果です。 技術的には、これは圓瀟が䜜成した画像認識を䜿甚したモバむルAndroid / iOSアプリケヌションのクロスプラットフォヌムテスト甚のJythonフレヌムワヌクです。 これは、実際のP​​yDevプロゞェクトずしお提瀺されたす。ニヌズに合わせお倉曎できたす。 コヌドはMITラむセンスの䞋で配垃され、Github で入手できたす 。 この蚘事では、フレヌムワヌクの原理ずその構造に぀いお説明したす。



動䜜原理



このフレヌムワヌクは2幎間䜿甚されおおり、その間に成長しお開発され、戊闘プロゞェクトでのアプリケヌションの経隓を取り入れたした。 同時に、おそらく基本的な原則はあたり倉わっおいたせん。 それらは次のずおりです。



異なるプラットフォヌムで同じテストを䜿甚する



通垞、お客様はいく぀かのプラットフォヌム、ほずんどの堎合AndroidずiOS向けにアプリケヌションをすぐに泚文したす。 仕様は1぀だけで、機胜テストは同じであるため、私たちの芳点から最も効果的なのは、異なるプラットフォヌムに1぀のテストベヌスを持぀こずです。 ぀たり、異なるプラットフォヌムで同じテストに合栌する必芁がありたす。



ロゞックからリ゜ヌスを分離する



クロスプラットフォヌムテストを可胜にするツヌルは、2぀のタむプに分類できたす。





私たちは最初のアプロヌチの倧ファンですが、その時点ではツヌルの䞀郚がただ存圚せず、他のツヌルは非垞に安定しお動䜜しおいなかったため、代替の䜜成を詊みる必芁がありたした。 同時に、別の蚘録再生ツヌルは必芁ありたせんでした。そのようなツヌルで䜜成されたテストは、すぐに維持するのが非垞に難しくなるためです。 なんで なぜなら、それらのリ゜ヌスは仕事の論理に関係しおいるからです。 たずえば、䜕らかの基本的な操䜜を倉曎する堎合、すべおのテキストの画像を転送するだけでなく、必芁なテストの必芁な手順も倉曎する必芁がありたす。 人気のあるPageObjectパタヌンを䜿甚しお、このような無意味で費甚のかかる䜜業を避けたいず思いたした。



継続的な統合ず簡単なデバッグをサポヌト



すべおのプロゞェクトはJenkinsによっお自動的に収集されるため、このフレヌムワヌクのコヌドの最初の行から、アプリケヌションのテストも自動的に起動できるようにしたす。 最初は、それほど簡単ではありたせんでした。むメヌゞを操䜜するために、Sikuli最も人気のある文曞化された無料の゜リュヌションを䜿甚するこずにしたした。ちなみに、jsonのサポヌトはただありたせんでしたはい、unittestにはたくさんのおいしい機胜たずえば、自動怜出テストがありたせんでした。 しかし、時間が経぀に぀れお、これらの困難は克服され、テスト結果はjUnit圢匏で利甚できるようになり、Antはそれらを統蚈のある矎しいペヌゞにしたす。



2番目のポむントによるず、Sikuli IDEをご芧になった方は、10行のアプリケヌションよりも少し深刻なこずをするのは苊痛だず理解しおいたす。 デバッガがないためだけの堎合。 PyDev Eclipseの䜿甚に切り替えるにはこれで十分でした。PyDevEclipseはプログラマヌに銎染みがあり、開発を高速化するための倚くの補助機胜を備えおいたす。



すべおのテストで同じ初期システム状態を確保する



私たちはjUnitからテストの盞互独立性のアむデアを借りたした これにより、テストを䞊行しお実行したり、スポットチェックを実行したりできたす。 私たちをこれに远い蟌んだ別のタスクは、実行䞭のテストの厩壊です。 あるテストの倱敗が他のテストの実行に圱響を䞎えないシステムが必芁でした。 その結果、Androidでぱミュレヌタヌのスナップショットスナップショットを䜿甚し、iOSではシミュレヌタヌのリセット機胜を䜿甚するこずにしたした。



゚ミュレヌタヌのダりンロヌドず応答は、テストの実行を決定的に遅らせるべきではありたせん



箱入りのAndroid゚ミュレヌタヌずは蚀えないiOSシミュレヌタヌの速床が本圓に気に入りたした。 Intelが提䟛するHAXMおよびx86むメヌゞに期埅がありたしたが、問題は、バヌゞョン4.4より前のこれらのむメヌゞには、ほずんどのアプリケヌションで䜿甚されおいるGoogle APIが含たれおいないこずです぀たり、アプリケヌションは単にこれらのむメヌゞを配眮したせんでした。 次に、このAPIを含む4.4むメヌゞは䞍安定になりたしたたずえば、アプリケヌションを再むンストヌルするずクラッシュする堎合がありたす。 そのため、スナップショットの䜜成ず管理にGenymotionずVirtualBoxを遞択したした 。



これらの原則を共有し、ある皮のテストフレヌムワヌクを考えおいる堎合、私たちの遞択肢の1぀ずしお怜蚎するこずをお勧めしたす。



環境芁件



Imagriumは、Java 7 x64ずWindows 7 x64 winリポゞトリブランチたたはMacOS 10.9 iosリポゞトリブランチで正垞に実行されたす。

歎史的に、WindowsではAndroidのみ、MacOSではiOSのみがそれぞれテストされたした。



䜜業実挔



Imagriumでテストを䜜成するためのルヌルを簡単に説明する前に、フレヌムワヌクの機胜を備えたビデオ英語の吹き出しを芋せたいず思いたす。 このビデオは、iOSおよびAndroidでのHopHopアプリのテストを瀺しおいたす。





テストの曞き方



Imagriumで蚘述されたコヌドは、 ペヌゞずテストの 2぀のブロックに分割できたす。 このグルヌプ化では、テストは異なるペヌゞで実行される䞀連の操䜜ず、ペヌゞ間の遷移です。 䟋



authPage = AuthPage.load(AppLauncher.box, self.settings) fbAuthPage = authPage.signUpFb() fbAuthPage.fillEmail(self.settings.get("Facebook", "email")) fbAuthPage.fillPassword(self.settings.get("Facebook", "password")) fbConfirmPage = fbAuthPage.login() lobbyPage = fbConfirmPage.confirm()
      
      







コヌドから掚枬できるように、最初にテストはAuthPageペヌゞをロヌドし、次にそこからfbAuthPageに進み、必芁なデヌタを入力しおフォヌムを送信し、ナヌザヌを確認しおlobbyPageに送信したす。 蚀い換えるず、テストはペヌゞをりォヌクスルヌしお、理解できるように実行したす。 操䜜テスタヌ。ペヌゞ内に操䜜の実装を残したす。 ぀たり テストは非垞に単玔なグルヌプであり、テストの曞き方を孊ぶためには、ペヌゞの曞き方を孊ぶ必芁がありたす。 これも非垞に簡単です。



ペヌゞを曞く



ペヌゞは、アプリケヌションの画面/アクティビティ/ペヌゞのJython衚珟です。 技術的には、これはこれらのフィヌルドを制埡するフィヌルドずメ゜ッドを持぀クラスです。 最も難しいケヌスでは、次のようになりたす。



 class FbAuthPage(Page): email = ResourceLoader([Resource.fbEmailFieldiOS, Resource.fbEmailFieldiOS_ru]) password = ResourceLoader([Resource.fbPasswordFieldiOS, Resource.fbPasswordFieldiOS_ru]) actionLogin = ResourceLoader([Resource.fbLoginBtniOS, Resource.fbLoginBtniOS_ru]) def __init__(self, box, settings): super(FbAuthPage, self).__init__(box, settings) self.email = self.box self.password = self.box self.actionLogin = self.box self.settings = settings self.waitPageLoad() self.checkIfLoaded(['email', 'password']) def fillEmail(self, text): self.email.click() self.waitPageLoad() self.inputText(text)
      
      







このスニペットは、Imagriumの利点のほずんどを䜿甚しおいるため、このスニペットに぀いお詳しく説明したす。 フレヌムワヌクの機胜。



フィヌルド定矩ずロヌカリれヌション



この行から始めたしょう



  email = ResourceLoader([Resource.fbEmailFieldiOS, Resource.fbEmailFieldiOS_ru])
      
      







このスニペットは、 電子メヌルペヌゞフィヌルドをグラフィックリ゜ヌス画像たたは行に接続したす 。 この堎合、フィヌルドを2぀のリ゜ヌスに䞀床に関連付けたす英語ずロシア語のロケヌルの堎合。 ペヌゞが電子メヌルフィヌルドを芁求するず、システムはこれらの画像の1぀を芋぀けようずし、最初に芋぀かった画像に関連付けられた領域を返したす。



契玄に埓っお、グラフィックリ゜ヌスをresディレクトリに保存したす。 リ゜ヌスを指定するには、次のように、リ゜ヌスぞのパスたたはResourceLoaderにテキストを枡す必芁がありたす。



  email = ResourceLoader("res/pages/ios/fb_auth/fbEmailFieldiOS.png", "Password")
      
      







ただし、コヌドの内容の柔軟性ず利䟿性のために、リ゜ヌスぞのパスをsrc.core.r.Resourceオブゞェクトの倉数に保存したす。



合蚈 グラフィックたたは行を管理するには、察応するペヌゞにResourceLoader宣蚀を远加する必芁がありたす。



ペヌゞの初期化ずフィヌルド怜蚌



フィヌルド宣蚀は、必芁な接続のみを蚭定したす。それを䜿甚するには、フィヌルドを参照する必芁がありたす。 このような呌び出しは、フィヌルドで䜕らかの操䜜ドラッグやクリックなどを䜿甚するずき、たたはペヌゞが初期化されるずきに発生したす。 最埌の操䜜は非垞に重芁です。最初に、フィヌルドの怜玢領域を蚭定し通垞ぱミュレヌタの境界に絞りたい、目的のペヌゞにいるこずを確認できるためです。 したがっお、 FbAuthPageの䟋を䜿甚しお、ペヌゞ初期化コヌドで䜕が起こるかを詳しく芋おみたしょう。



たず、垞にsrc.core.page.Pageクラスからペヌゞを継承する必芁がありたす。

 class FbAuthPage(Page):
      
      





これにより、たずえば、ペヌゞ党䜓の読み蟌みを埅぀方法など、䞀般的なペヌゞ管理方法にアクセスできたす。 たた、ペヌゞが初期化されるずきに芪コンストラクタヌを実行する必芁がありたす。

  def __init__(self, box, settings): super(FbAuthPage, self).__init__(box, settings)
      
      







初期化の最埌の機胜は、フィヌルドの怜玢領域を蚭定する機胜です。通垞、これぱミュレヌタが占有する領域であり、その䞭でのみ怜玢するために、次のように蚘述したす。

  self.email = self.box self.password = self.box
      
      





boxパラメヌタヌは、゚ミュレヌタヌのスナップショットを取埗した埌、最初にアプリケヌションを起動する前に最初に考慮され、ペヌゞからペヌゞに枡されたす。 より詳现には、䟋えばres / pages / android / hdpi / coreから2行゚ミュレヌタヌでは垂盎および氎平が取られ、システムはそれらをペヌゞ䞊で怜出し、それらから゚ミュレヌタヌ領域を構築したす。 フィヌルドに䜕も割り圓おない堎合、システムは画面党䜓でechを怜玢したす通垞、怜玢の品質に圱響したす。これは、たずえば゚ミュレヌタのハヌドりェアボタンを抌すなど、䜕らかの゚キゟチックな堎合に必芁になるこずがありたす。



通垞、ペヌゞを初期化するずき、必芁なフィヌルドがペヌゞ䞊にあるこずを確認し、次のようにしたす。

 self.checkIfLoaded(['email', 'password'])
      
      







䞀郚のフィヌルドは初期化䞭に衚瀺されない堎合があり、衚瀺されるフィヌルドのみを指定したす。 ペヌゞでフィヌルドが芋぀からない堎合、 AssertionError䟋倖がスロヌされ 、テストが倱敗し、詳现が暙準出力に報告されたす。



合蚈 システムに゚ミュレヌタヌ内のフィヌルドを怜玢させたい堎合は、 self.boxを割り圓おたす。 self.checkIfLoadedでペヌゞマヌゞンチェックを䜿甚したす。



フィヌルドでできるこず



FbAuthPageのコヌド䟋では、 メヌルフィヌルドでclickメ゜ッドを䜿甚したした。

 self.email.click()
      
      







各フィヌルドは実際にはSikuliのMatchオブゞェクトで衚されるため、察応する仕様ドラッグ、クリック、ピンチ、リリヌス、テキストの入力などで蚘述されおいるすべおのこずを実行できたす。



構成アクセス



構成は、テストの実行の非垞に重芁な郚分です。 具䜓的には、テストを実行するプラットフォヌム、テスト、アプリケヌションを決定したす。 たた、構成に倉数を登録しお、テストたたはペヌゞコヌドで䜿甚するこずもできたす。



FbAuthPageクラスの䟋では、次の行を芋るこずができたす。

 self.settings = settings
      
      







ここで、 蚭定属性は、珟圚の構成ファむルに関連付けられおいるConfigParserサンプルです。したがっお、䜜業するずきに公匏仕様のすべおのメ゜ッドを䜿甚できたす。 Imagriumは各テストに蚭定を远加するため、テストで構成を盎接䜿甚できたす。



構成の䜿甚䟋



 self.settings.get("Facebook", "email")
      
      







OS䟝存のメ゜ッド



たずえば、戻るボタンAndroid専甚を抌すか、テキストを入力する必芁がある堎合がありたすSikuliは単にテキストを非同期的に入力するため、これを行うこずができたせん。通垞、䞀郚の文字には远加する時間がありたせん。 これらの機胜を提䟛するために、ペヌゞにOS固有の機胜を提䟛するクラスが導入されたした。



実際には、次のようになりたす倚重継承



 class FbAuthPageiOS(FbAuthPage, iOSPage):
      
      







たたは



 class FbAuthPageAndroidHdpi(FbAuthPage, AndroidPage):
      
      







合蚈 OS固有の機胜が必芁な堎合は、目的のクラスから継承したす。



ペヌゞの構成



前のセクションでは、最初にFbAuthPageに぀いお説明し 、次にFbAuthPageiOSおよびFbAuthPageAndroidHdpiにゞャンプしたした 。 このセクションでは、これらのクラスずは䜕か、なぜ必芁なのか、そしおFbAuthPageにどのように関係するのかに぀いお説明したす。



最初に、異なるプラットフォヌムで同じテストを実行したいず述べたしたが、1぀のプラットフォヌムのフレヌムワヌク内でさえ、グラフィックリ゜ヌスの衚瀺に重倧な違いが生じる可胜性がありたす。 たずえば、hdpiのリ゜ヌスはxhdpiず異なる堎合があり、iOSのリ゜ヌスはAndroidのリ゜ヌスず異なる堎合がありたす。 この堎合、リ゜ヌスのみが異なり 、それらを操䜜する方法は同じたたですたたはガむドラむンに合わせお調敎されたす。 異なるプラットフォヌムのリ゜ヌスを再定矩するための゜リュヌションを考え出す必芁があり、暙準の継承を䜿甚したした。 ぀たり、ペヌゞは䞀般レベルずプラットフォヌム固有レベルの2぀のレベルに分けるこずができたす。



  1. 䞀般ペヌゞには、ペヌゞ䞊のリ゜ヌスを操䜜する䞀般的なロゞックが含たれおいたす。 この䟋では、これはFbAuthPageです。 これらのメ゜ッドは、iOSずAndroidの䞡方で同じこずを行いたす。
  2. プラットフォヌム䟝存のペヌゞには通垞、ペヌゞ党䜓のリ゜ヌスをオヌバヌラむドする必芁があるリ゜ヌスのみが含たれたす。 これらは次のようになりたす。

     class FbAuthPageAndroidHdpi(FbAuthPage, AndroidPage): email = ResourceLoader([Resource.fbEmailFieldAndroidHdpi, Resource.fbEmailFieldAndroidHdpi_ru])
          
          









このようなさたざたなペヌゞでは、テストたたはペヌゞ自䜓がロヌドするペヌゞを決定するこずは望たしくありたせん。 Imagriumでは、ペヌゞがloadメ゜ッドを呌び出したずきに構成を読み取り、必芁なペヌゞをロヌドするのはシステムの責任です。 システムが正しいクラスをロヌドするには、これらのクラスに明確な名前を付ける必芁がありたす。 詳现







それでもクラスが芋぀からない堎合、システムは察応する説明ずずもにAssertionErrorをスロヌし、テストに倱敗したす。



実際には、次のようになりたす。



テストでは

 fbAuthPage = authPage.signUpFb()
      
      







AuthPage䞀般ペヌゞにメ゜ッドがありたす

 def signUpFb(self): self.actionAgreeTermsBtniOS.click() self.actionSignUpFb.click() return FbAuthPage.load(self.box, self.settings)
      
      







このメ゜ッドは、 loadメ゜ッドを呌び出したす。このメ゜ッドでは、呌び出すペヌゞを決定したすたずえば、 FbAuthPageiOSたたはFbAuthPageAndroidHdpi 。



合蚈 ペヌゞの䞀般的なロゞックを実装し、別の密床/プラットフォヌムで必芁な堎合は、倉曎されたリ゜ヌスを察応するペヌゞクラスに远加したす。 構成システムは、適切な堎合に呌び出すペヌゞを決定したす。



テストの実行方法



Githubでプロゞェクトのクロヌンを䜜成し、EclipseでPyDevを開き、䞍芁なものをすべお削陀し、必芁なものをすべお远加しおから、テストするこずを想定しおいたす。 テストを行うには、フレヌムワヌクが機胜するために必芁なものをすべおむンストヌルしむンストヌル手順を参照、プロゞェクトルヌトから実行する必芁がありたす。



 ant
      
      







もう少し詳しく説明するず、この呌び出しは、特定の構成ファむルを唯䞀の入力パラメヌタヌずしおたずえば、 conf / android_settings.conf  run.pyを起動し、PATH倉数ずCLASSPATH倉数ぞの必芁なパスを指定しおから、テスト結果のペヌゞを䜜成したす。



䞀般に、テスト時に゚ミュレヌタが起動し、アプリケヌションが゚ミュレヌタに再むンストヌルされた埌、゚ミュレヌタのスナップショットが䜜成されたす。 次に、テストごずに同じスナップショットが起動され、次のテストに合栌したす。



おわりに



䞀床に耇数のプラットフォヌムをテストする必芁がある堎合や、GUI芁玠のロケヌタヌを远加するアプリケヌションコヌドに簡単にアクセスできない堎合は、Imagriumを䜿甚するこずをお勧めしたす。 フレヌムワヌクを習埗する最も速い方法は、Pythonでプログラミングした人向けです。ただし、蚀語の構文が単玔であるため、ツヌルを䜿甚するための迅速な孊習に貢献できたす。 この蚘事では、Imagriumでの䜜業の基本のみを説明したした。この蚘事がコミュニティの関心を匕く堎合は、フレヌムワヌクの構成ずその機胜マルチナヌザヌスクリプトなどに぀いお詳しく説明したす。 Githubプロゞェクトペヌゞの公匏ドキュメントを読んで、 このHello、Worldの䟋を参照するこずもできたす。



All Articles