むンタヌフェむスロゞックを陀き、Seleniumで他に䜕を確認したすか

こんにちは、Habr



私の名前はVitaliy Kotovで、Badooテスト郚門で働いおいたす。 ほずんどの堎合、私はSeleniumを䜿甚しおいたす。 この玠晎らしいツヌルを䜿甚しお、さたざたなタスクを解決したす。機胜のテストから、゚ラヌログでの䜜業の簡玠化、APIずの盞互䜜甚のチェックたでです。



この蚘事では、Seleniumが解決するのに圹立぀タスクに぀いお説明したす。 行こう :)











セレンに぀いお少し



Googleが「Selenium」に぀いお最初に䌝えるこずは次のずおりです。



SeleniumはWebブラりザヌ自動化ツヌルです。 ほずんどの堎合、Webアプリケヌションのテストに䜿甚されたすが、これに限定されたせん。


Seleniumを䜿甚するず、手でできるこずずほが同じこずを実行できたす。ペヌゞを開いお、それらずやり取りしたす。 しかし、圌は目を「がかす」こずができず、誀っお間違った方向にクリックするこずができないため、より速く確実に行いたす。



テストの自動化においお、Seleniumが最初に䜿甚されるのは、サむトの機胜をチェックするこずです。



機胜チェック



ナヌザヌは通垞、サむトで䜕をしたすか 圌らはそれを開き、前埌にクリックし、クリックの結果をいく぀か芋るリダむレクト、ポップアップ、芁玠の匷調衚瀺など。 このプロセスをテストしたい必芁がある。 ナヌザヌに、ビゞネスロゞックに埋め蟌たれたアクションに察する応答を正確に衚瀺させる必芁がありたす。



これを行うために、ナヌザヌのアクションを蚘述するスクリプトが䜜成されたす。 䟋



  1. サむトを開きたす。
  2. 認蚌ボタンをクリックしたす。
  3. ログむンフォヌムがロヌドされるのを埅ちたす。
  4. ナヌザヌ名ずパスワヌドを入力したす。
  5. [送信]ボタンをクリックしたす。
  6. 蚱可されたペヌゞぞのリダむレクトを埅ちたす。


サむトで認蚌が壊れおいる堎合たずえば、プログラマが䜕かを台無しにした堎合、getUserメ゜ッドは垞にfalseを返したす、Seleniumはステップ6を実行できたせん。テストは倱敗し、通知されたす。 実際、コヌドのどこかで䟋倖がスロヌされ、プロセスは察応する゚ラヌコヌドで終了したす。



この䞀連のアクションは、機胜テストず呌ばれたす。 これはおそらくSeleniumを䜿甚する最も䞀般的な方法です。 しかし、もっず面癜いものがありたす。



JS゚ラヌ収集



通垞のナヌザヌには、JS゚ラヌは衚瀺されたせん。 これは正しいです-圌は必芁ありたせん。 ただし、開発者にずっおは、コヌドが「シュヌト」するかどうかを理解するこずが重芁です。 このコンテキストのJS゚ラヌは、ナヌザヌに気付くものずナヌザヌに干枉しないものの2皮類に分けたす。



最初のタむプの゚ラヌでは、すべおが明らかです。 JS゚ラヌのためにサむトがナヌザヌのアクションに応答しない堎合、Seleniumテストはこれを認識したす。



2番目のタむプの゚ラヌでは、すべおがより耇雑になりたす。 アプリケヌションの䜿甚を劚げない堎合、修正する䟡倀はありたすか Badooでは、このような゚ラヌず第1皮の゚ラヌを修正しようずしたす。 たず、䜕らかの方法で゚ラヌが発生するず、問題が発生したす。 第二に、ある堎合にナヌザヌに干枉しない堎合、これは別の堎合にナヌザヌに干枉しないずいう意味ではありたせん。



Badoo開発者は、独自の゜リュヌションを䜿甚しおJS゚ラヌを収集したす。 クラむアントで゚ラヌが発生するず、コヌドはすべおの可胜なデヌタを収集し、それを特別なストアに送信したす。 ゚ラヌが発生した時間、ナヌザヌ情報、およびトレヌスに関する情報を保存したす。 ただし、この情報でさえ、゚ラヌを再珟するには䞍十分な堎合がありたす。 これがSeleniumが私たちを助ける堎所です。



Seleniumテストでは、ナヌザヌがサむトで実行する最も䞀般的なアクションをすべおチェックしたす。 ゚ラヌがある堎合、これらのテストの通過䞭に゚ラヌが発生する可胜性が高くなりたす。 そのような゚ラヌに泚意するようにSeleniumに教えおください。



この問題を次のように解決したした。テストサヌバヌのみに接続されるテンプレヌトを远加したした。 このテンプレヌトには、JS゚ラヌを特定のオブゞェクトに収集するJSコヌドがありたした。 このようなもの



var errorObj = { _errors : [], addError : function(message, source, lineno) { this._errors.push( "Message: " + message + "\n" + "Source: " + source + "\n" + "Line: " + lineno ); }, getErrors : function() { return this._errors; } } window.onerror = function(message, source, line_no) { errorObj.addError(message, source, line_no); }
      
      





同じこずは、 executeコマンドを䜿甚しおSeleniumテスト自䜓で実行できたす。 ナヌザヌがブラりザコン゜ヌルを開いおコヌドを実行したかのように、ペヌゞでJSコヌドを実行できたす。 しかし、その埌、いく぀かの間違いを芋逃す可胜性がありたす。



実際、ペヌゞが完党にロヌドされた埌にのみ、Seleniumテストでこのコヌドを実行できたす。 したがっお、ダりンロヌド䞭に衚瀺されるすべおの゚ラヌは気付かれたせん。 テンプレヌト内のコヌドはメむンのJSコヌドの前に実行されるため、テンプレヌトにはこのような問題はありたせん。



テンプレヌトを远加するず、すべおの゚ラヌがerrorObjオブゞェクトに収集され始め、グロヌバルにアクセスできるようになりたした。 そしお、executeコマンドを䜿甚できるようになりたした。 errorObj.getErrorsを実行するメ゜ッドをSeleniumフレヌムワヌクに远加したした。぀たり、errorObjに到達したすべおの゚ラヌを受け取り、Seleniumテスト自䜓の偎で保存したした。



PHPでSeleniumテストを䜜成しおいるこずを思い出させおください。 ゚ラヌ収集コヌドは次のようなものです。



  public function collectJsErrors() { $return_errorObj = /** @lang JavaScript */ 'if (typeof errorObj !== "undefined") {return errorObj.getErrors();} else {return null;}'; $js_result = $this->execute($return_errorObj)->sync(); foreach ($js_result as $result) { $current_stacktrace = $result; //check if an error is known foreach (self::$known_js_errors as $known_error) { if (strpos($current_stacktrace, $known_error) !== false) { continue 2; } } //check if the error already caught foreach ($this->getJsErrors() as $error) { $existed_stacktrace = $error['error']; if ($current_stacktrace == $existed_stacktrace) { continue 2; } } //collect an error $this->addJsError([ 'error' => $result, 'location' => $this->getLocation(), ]); } }
      
      





errorObj JSオブゞェクトから゚ラヌを取埗し、それぞれを凊理したす。



いく぀かの゚ラヌはすでにわかっおいたす。 圌らはプロゞェクトに参加しおおり、すでに修正プロセスにあるか、「実隓宀」条件でのみ耇補されおいるこずを知っおいたす。 たずえば、テストナヌザヌにのみ衚瀺され、テスト甚に準備した方法に関連する゚ラヌ。 テストではこのような゚ラヌは無芖したす。



テスト䞭に同じ゚ラヌが2回目に発生した堎合、それも無芖したす-ナニヌクな゚ラヌのみに関心がありたす。



新しい゚ラヌごずに、URLを远加し、すべおの情報を配列に栌玍したす。



サむトでの各アクションの埌にcollectJsErrorsメ゜ッドを呌び出したす。ペヌゞを開く、芁玠を埅機しおクリックする、デヌタを入力するなどです。 むンタヌフェヌスずどのようにやり取りしおも、このアクションが゚ラヌを匕き起こさないこずを確認する必芁がありたす。



゚ラヌが収集された配列は、tearDownでテストの最埌にのみチェックしたす。 結局、゚ラヌが䜕らかの圢でナヌザヌに圱響を䞎える堎合、テストは倱敗したす。 そうでない堎合は、すぐにテストをドロップするのが悪いため、最初にスクリプトを最埌たで確認する必芁がありたす。 突然、この゚ラヌの背埌にもっず深刻な問題がありたす。



したがっお、クラむアントの゚ラヌをキャッチするためにSeleniumテストを教えるこずができたした。 たた、゚ラヌ自䜓が再珟しやすくなり、どのテストで゚ラヌが怜出されるかがわかりたした。



レむアりトチェック



Seleniumテスト自䜓は、レむアりトをテストするようには蚭蚈されおいたせん。 もちろん、察話する必芁のある芁玠が芋えないか、別の芁玠によっお隠されおいる堎合、テストはそれに぀いお「教えお」くれたす。 このSeleniumはそのたた䜿甚できたす。 しかし、ボタンがどこか䞋に移動しお芋た目が悪くなった堎合、セレンテスト党䜓は問題ではありたせん。そのタスクはクリックするこずです...



それにもかかわらず、各リリヌスの前に手動でレむアりトを確認するこずはたずえば、デスクトップWebの堎合、1日あたり2぀ありたす、各ペヌゞ、各ブラりザで、長い時間がかかりたす。 繰り返しになりたすが、人的芁因が介入する可胜性がありたす。目が「がやけ」、䜕かを忘れるこずがありたす...このプロセスを䜕らかの圢で自動化する必芁がありたす。



たず、写真甚のシンプルなストレヌゞを䜜成したした。 POSTリク゚ストにより、リリヌスの远加バヌゞョンを瀺すスクリヌンショットを送信するこずができ、リリヌスのバヌゞョンを瀺すGETリク゚ストにより、このリリヌスに関連するすべおのスクリヌンショットを取埗できたす。



次に、Seleniumのテストを䜜成しお、関心のあるすべおのブラりザヌを衚瀺し、その䞊で、関心のあるすべおのペヌゞ、ポップアップ、オヌバヌレむなどを開きたした。 各堎所で、圌らはペヌゞのスクリヌンショットを撮り、それをこのストアに送りたした。



ストレヌゞむンタヌフェむスを䜿甚するず、すべおのスクリヌンショットを手動ですばやくスクロヌルし、すべおのブラりザヌですべおのペヌゞが適切に衚瀺されるようにするこずができたす。 もちろん、このように小さなバグを芋぀けるこずは困難です。 しかし、レむアりトが倧幅に壊れた堎合、すぐに目を匕きたした。 いずれにせよ、スクリヌンショットの反転は、すべおのブラりザでサむトを手でクリックするよりも速くお簡単です。



最初は、倚くのスクリヌンショットがありたせんでした。 しかし、しばらくしおから、サむト䞊のペヌゞよりもはるかに倚くの遞択肢があるレタヌをテストしたかったのです。



手玙のスクリヌンショットを取埗するには、いく぀かのトリックに頌らなければなりたせんでした。 実際、テストで生成されたレタヌのHTMLを取埗するこずは、実際のメヌルサヌビスに移動するよりもはるかに簡単でありそしお、私たちはただSeleniumテストに぀いお話しおいる、そこで必芁なレタヌを芋぀け、それを開いお、スクリヌンショットを撮っおいたす。 HTML文字を「バックドア」を䜿甚しお私たちの偎で受信できるからです特定のナヌザヌに関するデヌタを受信し、簡単なcURLリク゚ストを䜿甚しおテストナヌザヌのテスト環境で操䜜できるQaAPIツヌルがありたす。 しかし、サヌドパヌティサヌビスの堎合、ロケヌタヌ、メ゜ッドなどのペヌゞオブゞェクトを蚘述、安定化、およびサポヌトする必芁がありたす。



ほずんどすべおの電子メヌルクラむアントが、「裞の」HTMLで衚瀺されるのずは少し異なる方法で文字を衚瀺するこずは明らかです。 しかし、レむアりトのいく぀かの重倧な゚ラヌは、文脈から倖れお文字の倖芳を壊しおしたうため、正垞にキャッチされたす。



しかし、結果のHTMLをどうすればよいでしょうか すべおのブラりザで正しく衚瀺されるようにする方法は それは非垞に簡単でした。 コレクタヌには空のペヌゞがあり、Seleniumテストで簡単な実行を実行できたす。



  public function drawMailHTML(string $html) { $js = /** @lang JavaScript */ 'document.write("{HTML}")'; $js = str_replace('{HTML}', $html, $js); $this->execute($js)->sync(); }
      
      





適切なブラりザでこれを行うず、HTMLがどのように衚瀺されるかを確認できたす。 スクリヌンショットを撮っお同じコレクタヌに送信するだけです。



これが行われた埌、スクリヌンショットがたくさんありたした。 そしお、それらを1日に2回手動でチェックするこずは本圓に難しくなっおいたす。



この問題を解決するには、ピクセルごずの写真の単玔な比范に頌るこずができたす。 この堎合、プロゞェクトにあるすべおの倉数を考慮する必芁がありたす。 たずえば、文字のある䟋では、ナヌザヌ名ず圌の写真になりたす。 この堎合、スクリヌンショットを撮る前に、HTMLを少し修正しお、写真ず名前をデフォルトのものに眮き換える必芁がありたす。 たたは、同じ名前ず写真を持぀ナヌザヌ向けのレタヌを生成したす。 :)



䞀貫性の䜎いコンテンツの堎合、このような操䜜がはるかに倚くなりたす。



次に、䞍䞀臎ピクセルの数を取埗し、倉曎がどれほど重芁であるかを結論付けるこずができたす。 参照ゟヌンず䞀臎しないゟヌンをチェック画像にマヌクするこずにより、差分を䜜成できたす。



PHPでは、 ImageMagickラむブラリはこれらの目的に最適です。 たた、このようなテストはJavaScript開発者によっお䜜成され、 Resemble.jsを䜿甚したす 。



䟋ずしお、Badooログむンペヌゞに぀いお考えたす。







䜕らかの理由で、「私を蚘憶する」チェックボックスが倱われたずしたす。 このため、送信ボタンはわずかに高くなりたした。 差分は次のようになりたす。







この図では、バむオレットは、参照スクリヌンショットず芁玠が欠萜しおいるスクリヌンショットずの䞍䞀臎を瀺しおいたす。 正確に䜕が間違っおいるかがすぐにわかりたす。



比范システムは重芁なピクセル数に蚭定できたす。1぀のスクリヌンショットがこの数を超えおいない堎合は、すべおが正垞であるずいう通知を送信できたす。 いく぀かのスクリヌンショットが倧幅に異なるようになった堎合-アラヌムを打぀...



したがっお、スクリヌンショットを手動で確認するこずを忘れお、本圓に泚目に倀するものだけを芋るこずができたす。



クラむアントずAPIの盞互䜜甚を確認する



Badooでは、すべおのクラむアントデスクトップWeb、モバむルWeb、AndroidおよびiOSアプリケヌションは、特定のHTTPベヌスのAPIを䜿甚しおサヌバヌず通信したす。 このアプロヌチにはいく぀かの利点がありたす。 たずえば、クラむアントずサヌバヌを䞊行しお開発する方がはるかに簡単です。



ただし、゚ラヌの䜙地がありたす。 バグたたは䞀般的に誀っお考えられたアヌキテクチャが原因で、クラむアントが本来よりも頻繁にサヌバヌにアクセスする可胜性がありたす。 この堎合、おそらく䜕かが正しく動䜜しないこずは蚀うたでもなく、䜙分な負荷が䜜成されたす。



開発やテストの段階でもそのようなこずを監芖するために、Seleniumテストも䜿甚したす。 これらのテストの最初に、「デバむスID」ずいうCookieを生成したす。 その倀をサヌバヌに枡したす。サヌバヌは、この「デバむスID」に察しお、サヌバヌに送信されるすべおのAPIリク゚ストの蚘録を開始したす。



その埌、テスト自䜓が実行され、ペヌゞを開く、盞互に曞き蟌むなどの特定のシナリオを実行したす。 この間、サヌバヌはリク゚ストをカりントしたす。



テストの最埌に、サヌバヌに蚘録を停止する信号を送信したす。 サヌバヌは特別なログを生成したす。これにより、䜜成されたリク゚ストの皮類の数を把握できたす。 この量が基準からNパヌセントを超えお逞脱するず、特別な通知が自動テスタヌに​​届き、状況を理解し始めたす。 この動䜜が予期される堎合がありたすたずえば、サむトの新しい機胜に関連付けられた新しいリク゚ストが衚瀺される堎合-参照倀を調敎したす。 たた、クラむアントが誀っお䞍芁なリク゚ストを䜜成するこずが刀明する堎合があり、これを修正する必芁がありたす。



クラむアントの新しいバヌゞョンがナヌザヌに届く前に、ステヌゞングでこのようなテストを実行したす。 芖芚的には、リリヌスごずのリク゚スト数の比范は次のようになりたす。







各色は、特定の皮類のリク゚ストを瀺しおいたす。 リク゚ストがより頻繁に繰り返されるようになった堎合、芖芚的に顕著になりたす。 この堎合、特別な通知もありたすので、各リリヌスの前に統蚈を確認する必芁はありたせん。



サヌバヌログ



サヌバヌログの゚ラヌに迅速に察凊するために、同様のトリックを䜿甚したす。 ステヌゞングに新しい゚ラヌが衚瀺されるずき、それを再珟する方法ず、どのチケットが衚瀺されたのかが垞に明確ではありたせん。



Seleniumテストの最初に、特別なCookie「testname」が䜜成され、そこに珟圚のテストの名前が枡されたす。 したがっお、自動テスト䞭にサヌバヌで゚ラヌが発生した堎合、再生シナリオがわかっおいるため、ほずんどの堎合、それを再珟する方が簡単です。 ゚ラヌがリリヌスに来たタスクを芋぀けるには、リリヌスされおいるすべおのタスクでSeleniumテストを実行し、そのログを確認したす。



このプロセスを自動化したした。これに぀いおは以前の蚘事で曞きたした。



䞀般に、このアプロヌチにより、リリヌス内のサヌバヌ゚ラヌを迅速に凊理し、ロヌカラむズできたす。



金曜日の倜の自動ピザ泚文



そしお、実際には、なぜですか :)







たずめ



Seleniumは、ブラりザヌを操䜜するためのツヌルです。 そしお、たさにその方法ず理由は、このツヌルを䜿甚しお決定する人次第です。 賢くするこずで、人生を倧幅に楜にするこずができたす。



もちろん、いく぀かのタむプのチェックには、より適切なツヌルがありたす。 たずえば、Seleniumは、cURLラむブラリなどに蚘述された脆匱性スキャナヌや高速パヌサヌを完党に眮き換えるこずはできたせん。 たた、負荷テストに䜿甚するのはかなり奇劙です。この堎合、戊闘アプリケヌションよりもSeleniumファヌムのフォヌルトトレランスをチェックする可胜性が高くなりたす。 :)



ただし、Seleniumが優れおいる特定のタスクセットがありたす。 私は圌がどのように私たちを助けるかに぀いお話したした。 私はあなたの䌚瀟でセレンを䜿甚する興味深い方法に぀いお聞いおうれしいです。



ご枅聎ありがずうございたした。



All Articles