
リソースhabrahabr.ruの親愛なる訪問者! テスト自動化エンジニアのJeremy Suarezによる記事を紹介します。 RubyおよびWATIR言語を使用してプロジェクトの自動テストを整理する予定がある場合は、この記事が役立ちます。 Jeremyは、基本的な例を使用して、すべてを簡単な言語で説明します。 記事を読んだ後、プロセスの最初のステップから最終段階まで、プロセスを明確に理解できます。
資料に直接進む前に、著者にいくつかの言葉を捧げたいと思います。 ジェレミーはテストで豊富な経験を持っています。 彼の多くのプロジェクトで、開発者からテスター、プロジェクトマネージャーまで、さまざまな役割を果たしました。 現在、ThoughtWorksで働いています。
それでは始めましょう!
対象読者この資料は、主に自動化されたテストスクリプトの作成を計画しているテストエンジニア、または既製のフレームワークをサポートする予定のあるエンジニアに役立ちます。 読者はRuby構文の基本的な知識を持ち、Webアプリケーション開発の基本原則に精通していることを前提としています(「リンク」、「フォーム」、「JavaScript」などの用語はパニック攻撃を引き起こしません)。
Rubyは比較的学習しやすい言語です。 Python、C ++、Java、またはCでコードを記述した経験がある場合は、すぐに習得できます。
前提条件と制限WebアプリケーションのテストにWATIRを使用するための前提条件の一部を以下に示します。 おそらく主なものは、モジュールがIE 5.5以下でのみ動作することです。 残念ながら、Netscape、Opera、Firefox、またはその他のブラウザーで動作するようには設計されていません。 これは、WATIRを使用したクロスブラウザテストが不可能であることを意味します。 2番目の重要な詳細は、WATIRには独自のレコーダーがないことです。 概して、WATIRは、スクリプトを手動で記述するときに使用できるIEメソッドとオブジェクトのライブラリです。 最後に、3つ目-WATIRには、ページにあるオブジェクト、およびそのタイプと使用可能なメソッドを識別する手段がありません。 すべてのリンク、画像、フォームなどを収集する方法を提供します。 したがって、スクリプト開発プロセスは、試行錯誤の方法に従うことがよくありますが、偶然、必ずしも悪いわけではありません。
準備する自動化されたテストスクリプトを記述するプロセスの前に、準備プロセスが必要です。 この場合の最も重要な点は、おそらく、すべての自動テストが実際には既製の手動テストスクリプトから論理的に従うことです。 テストフレームワークを開発するための努力のほとんどは、誤って記述された手動テストのために無駄になります。 理解することが重要です-これは、手動テストと自動テストの両方をさらにサポートするための主要なポイントです。 アプリケーションを使用して実装されたビジネスプロセスの相互作用の全体像を確認し、タスクの範囲全体をカバーする説明にアプローチする必要があります。
テスト対象のアプリケーションの詳細を理解する機能要件のコレクション(ある場合)手動または自動テストの設計に直接進む前に、アプリケーションが何であるかを理解する必要があります。 最も簡単な方法は、開発要件に慣れることです。 現在、要件の文書化はほぼ普遍的です。 そして、明確で完全かつ一貫した要件が明確にある場合、これは良い出発点です。
専門家の調査機能要件の調査に加えて、そうでない場合は、製品の開発者とエンドユーザーから情報を直接取得できます。 通常、建築家、ビジネスアナリストなどもこのプロセスに参加できます。 開発者は通常、アプリケーションがどのように機能するかについて独自のアイデアを持っているため、できるだけ多くの異なる分野の専門家がディスカッションに参加することが重要です。 そして、原則として、彼らの視点はクライアントの期待とは異なります。
テストケースによるビジネスプロセスのプレゼンテーションすべてのテストアクティビティは、手動または自動にかかわらず、詳細なステップバイステップのテストシナリオに基づいている必要があります。 これがないと、テストの進捗状況、コードカバレッジの割合、およびその他のメトリックを追跡することが問題になります。 自動テストが独自のドキュメントであると考えるのは間違っています。 彼らは絶えず変化し、編集されています。 このようなアプローチは、多大な時間コストとエラーの増加につながります。
データ準備プロセスの作成多くのアプリケーションは、作業中にデータを使用または作成します。 手動と自動の両方のテスト目的で、システム内のデータの状態はサイクルごとに同じでなければなりません。 この特定のケースでプログラムが何をすべきかによって、収集、作成、またはその両方のために、データ準備スクリプトとクリーニングスクリプトを準備する必要があります。 データの準備と精製のためのテストは、通常のスクリプトと同様に発行し、後者の前提条件として使用する必要があります。
自動化に適したケースを特定する有名な広告スローガンにあるように、「すべてのヨーグルトが同じように役立つわけではありません。」 同じことがテストケースにも当てはまります。 すべてを自動化する必要はありません。 最も単純で、最も頻繁に繰り返されるものだけが良い候補です。 UIで機能するケースから始めて、データを作成および削除する必要のあるケースに注意を払ってください。 最後に、最も重要な機能セグメント(最も一般的に使用される機能)をカバーする一連のスクリプトを作成してみてください。
自動化されたスクリプトフレームワークの作成正確にテストする必要があるものの明確なビジョンが得られたら、必要な機能をステップバイステップのケースとして文書化した後、自動テストスクリプト自体の開発を安全に開始できます。 手動テストケースを空のRubyスクリプトファイルにコピーします。 スクリプト内のステップをコメント化し、別々のセクションに分割します。 分割する場合、ある場所でデータを作成し、別の場所で使用するという原則に従うこともできます。 スクリプトの作業中にデータが生成されたが、何らかの理由でケース自体が最後に到達しなかった場合、このデータを削除してスクリプトを復元しようとする方が合理的です。
実装一般に、RubyとWATIRを使用したテストスクリプト自動化プロセスの実装は、いくつかの簡単な手順になります。
•テストケースが選択され、一連の機能を使用してプログラムできます。
•IEオブジェクトの初期化または既存のブラウザーウィンドウへの接続
•アプリケーションの開始リンクに移動します
•さらなるアクションに必要なすべてのリンク、画像、フォームの収集
•収集された情報、リンクの名前、フォームに関する情報、画像の名前などから
•リンク、フォーム、画像でアクションを実行する
•必要になるまで手順3〜6を繰り返します。 各ステップの最後に、実行されたアクションが正常に終了したことを確認する必要があります。
最大の効率を達成するには、各ステップに検証を伴うことが非常に重要です。 そのようなチェックが実行されない場合-可能-スクリーンショットを撮ったり、ログをコピーしたり、少なくともわかりやすいエラーメッセージを発行したりできます。 そうしないと、「リンクが見つかりません」または「フォームxxxが利用できません」などのリスクが発生します。
スクリプト開発者のみが、何かがうまくいかなかった場合にエラーメッセージがどの程度有益であるかに依存します。 低品質のスクリプトを手動で実行して、何が起こったのかを理解する必要があります。正しくコンパイルされたスクリプトは、障害自体に関するすべての必要な情報を生成できます。
実装の技術的側面IEオブジェクトの初期化新しいブラウザーIEオブジェクトを作成するか、既存のIEオブジェクトに接続することから始めます。
$ ie = IE.new()
または
$ ie = IE.attach(:title、“ ...”)
開始リンクをたどる指定されたリンクをクリックして、アプリケーションのテストを開始します。 すべてのケースはこれで始まります。 また、スクリプト自体の実行中にリンクをたどる必要がある場合があります。
$ ie.goto(“ http:// ....”)
コンテンツ検証コンテンツを確認する最も簡単な方法は、assertコマンドを使用することです。 フォームが存在すること、ボタンが使用可能であること、ページにテキストが含まれていることなどを確認してください。RubyにはTRYループがないため、rescueキーワードを使用します。
始める
assert($ ie.pageContainsText(「ログアウト成功」))
assert($ ie.form(:name、“ Login”)。exists)
$ log.info(「テストステップ5に合格しました!」)
救助
$ log.error(「テストステップ5に失敗しました」)
$ log.info(「エラーテキストは:」、つまり.text())
終わり
必要なリンク、画像、フォームのコレクションスクリプトを記述する過程で、リンクまたは画像の正確な名前、URL形式、フィールド名などを決定することは必ずしも容易ではありません。 このような場合、ダンプをログファイルまたは画面にアップロードできます。 この情報は、テストの作成時またはデバッグ時に役立ちますが、ケースの最終バージョンでは無効にする必要があります。 出力は、ファイルおよび標準出力デバイスにも出力できます。
$ log.info()、$ log.error()、$ log.warning()log4jログファイルへのすべての出力。
すべてのリンクを表示:
puts $ ie.show_links()
すべてのフォームを表示:
puts $ ie.show_forms()
すべての画像を表示:
puts $ ie.show_images()
すべてのオブジェクトを表示:
puts $ ie.show_all_objects()
すべてのフレームを含むページ全体を表示します。
puts $ ie.html()
リンクをクリックしてくださいリンクのアクティブ化は、名前または直接URLを使用して実行できます。 JavaScriptを使用する場合、リンクはURLによってのみアクティブ化できます。リンクが画像リンクの場合は、そのイメージタグ(src、imageタグ)によってアクティブ化できます。 クリック方式は、リンクをアクティブにするための標準のWATIR方式の1つです。
$ ie.link(:text、“ Portfolio”)。クリック
リンクテキストが時間とともに変化する可能性があるが、その場所は変わらない場合、リンクインデックスを使用する方が安全です(さまざまなリンクのインデックスを検索するには、$ ie.show_links()を使用します)。
$ ie.link(:インデックス、20).click
JavaScriptを使用する場合、URL(またはhrefタグ)を使用できます。
$ ie.link(:url、/ javascript:deleteClient \(\ d ,. * /)。クリック
URLはエンコードする必要があることに注意してください(スペースは%20などで表されます)。 上記の例のように、正規表現を使用できます。
画像をクリック追加のタグscrおよびaltが存在することを除いて、画像をクリックすることは、リンクをクリックすることと大差ありません。
$ ie.image(:name、“ login.gif”)。クリック
フォーム送信フォームへの入力と送信は、おそらくサイトナビゲーション段階で完了するのが最も難しい手順です。 これを行うには、すべてのテキストフィールド、選択リスト、またはフォームに存在するその他の要素の名前を知る必要があります。 これらの目的にはie.show_all_objects()を使用します。
$ ie.textField(:name、“ username”)。set(“ testuser”)
$ ie.textField(:name、“ password”)。set(“ testpass”)
送信は、対応するオブジェクトを「クリック」することで実行されます。
$ ie.button(:value、“ Login”)。クリック
共有施設の短いツアーポップアップを使用するアクション
新規、戻る、進む、send_keys、goto、閉じる、更新、最小化、最大化、復元
$ ie.back()
$ ie.forwards()
$ ie.send_keys(“ {TAB} {TAB} {ENTER}”)
$ ie.close
$ ie.goto(「http://www.google.com」)
$ ie = IE.new()
表示機能showFrames、show_frames、showForms、show_forms、showImages、show_images、showActive、show_active、showLinks、show_links、showAllObjects、show_all_objects、show_tables、ボタン、show_spans、show_labels
$ ie.show_tables
$ ie.buttons.each {| m | mを置く}
継承オブジェクトframe、textField、span、row、selectBox、radio、select_list、text_field、
チェックボックス、ボタン、チェックボックス、リンク、セル、フォーム、テーブル
$ ie.frame(:インデックス、1)
$ ie.textField(:name、“ q”)。set(“ Test”)
$ ie.button(:value、“ OK”)。クリック
$ ie.link(:text、“ Happy link”)。クリック
$ ie.select_list(:name、“ Day”)。select_value(“ today”)
オブジェクトリストチェックボックス、ラベル、画像、スパン、ラジオ、select_lists、text_fields、ボタン、テーブル、リンク
$ ie.checkboxes.each {| m | mを置く}
$ ie.radios.each {| m | mを置く}
$ ie.links.each {| m | mを置く}
チェックgetText、text、getStatus、status、getHTML、html、pageContainsText、contains_text、title
if($ ie.text.match(“ Hallo”)!= nil)
「合格!」
他に
「失敗しました!」
$ ie.contains_text(「Google」)
戻り値:True
その他の機能getImage、getIE、enable_spinner、set_fast_speed、enable_spinner =、wait、popup、down_load_time、getLink、set_slow_speed、getTablePart、focus、url
テキストフィールド説明テキスト名=質問ID =値= alt = src =
オブジェクトtextField、text_field
認識方法$ ie.show_all_objects
$ ie.show_active
$ ie.textfields.each {| textfield | テキストフィールドを置く}
その他の方法value、value =、clear、click、send、set、enabled?、flash、html、append、getContents、focus、verify_contains
最も使用される方法値、設定、追加、verify_contains。
例$ ie.textField(:name、“ q”)。value =” Sam”
$ ie.textField(:name、“ q”)。append(“ I am”)
$ ie.textField(:name、“ q”)。value
戻り値:「Sam I am」
$ ie.textField(:name、“ q”)。getContents
戻り値:「Sam I am」
$ ie.textField(:name、“ q”)。set(“ Happy”)
$ ie.textField(:name、“ q”)。verify_contains(“ app”)
戻り値:true
ボタン説明
送信名= btnG id =値= Google検索alt = src =
オブジェクトボタン
認識方法$ ie.show_all_objects
$ ie.show_active
$ ie.buttons.each {|ボタン| ボタンを置く}
その他の方法値、表示、クリック、送信、有効?、フラッシュ、html、無効、フリーズ、フォーカス
最も使用される方法クリックして
例$ ie.button(:name、“ btnG”)。クリック
$ ie.button(:名前、“ btnG”)値
戻り値:「Google検索」
参照資料説明
「name = id = innerText = Business Solutions href = http://www.google.com/services/」
オブジェクトリンク
認識方法$ ie.show_links
$ ie.show_active
$ ie.links.each {| link | リンクを置く}
その他の方法値、タイトル、クリック、link_has_image、有効?、flash、html、href、src、text、focus、name、innerText、equal?
最も使用される方法クリックして
例$ ie.link(:テキスト、「ビジネスソリューション」)。クリック
$ ie.link(:text、“ Business Solutions”)。enabled?
戻り値:true
$ ie.link(:テキスト、「ビジネスソリューション」)。link_has_image
戻り値:false
備考:show_activeまたはshow_all_objectsメソッドが使用されている場合、リンクはタイプなしで返されます。選択リスト説明
select-one name = logonForm:_idJsp15:0:質問ID = logonForm:_idJsp15:0:質問値=猫の名前は何ですか?
オブジェクトselect_list
認識方法$ ie.show_all_objects
$ ie.show_active
その他の方法オプション、選択、値、getSelectedItems、クリック、有効?、フラッシュ、select_item_in_select_list、html、getAllContents、select_value、clearSelection
最も使用される方法select、getSelectedItems、getAllContents、select_value、clearSelection
例$ ie.select_list(:name、/Question/).value
戻り値:「あなたの猫の名前は?」
$ ie.select_list(:name、/Question/).getAllContents
配列を返します:[「好きな色は何ですか?」、「あなたの猫の名前は何ですか?」]
$ ie.select_list(:name、/Question/).select_value(「あなたの猫の名前は?」)
チェックボックス説明
チェックボックス名= option1 id =値= Milk alt = src =
オブジェクトチェックボックス
チェックボックス
認識方法$ ie.show_all_objects
$ ie.show_active
$ ie.checkboxes.each {|チェックボックス| チェックボックスを置く}
その他の方法値、クリア、クリック、設定、有効化?、チェック?、フラッシュ、html、isSet?、getState
最も使用される方法クリック、設定、クリア、チェック?
例$ ie.checkbox(:name、“ Milk”)。セット
$ ie.checkbox(:name、“ Milk”)。isSet?
戻り値:true
$ ie.checkbox(:name、“ Milk”)。クリック
$ ie.checkbox(:name、“ Milk”)。isSet?
戻り値:false
$ ie.checkbox(:名前、「牛乳」)。
$ ie.checkbox(:name、“ Milk”)。isSet?
戻り値:false
ラジオボタン説明
ラジオ名= group1 id =値=バターalt = src =
オブジェクトラジオ
認識方法$ ie.show_all_objects
$ ie.show_active
$ ie.radios.each {| radio | ラジオを置く}
その他の方法値、クリア、クリック、設定、有効?、チェック?、html、isSet?、getState
最も使用される方法セット、チェック? (明確、慎重に)
例$ ie.radio(:値、「バター」)。 セット
$ ie.radio(:value、“ Butter”)。isSet?
戻り値:true
注:ラジオボタンの明確な方法は使用しないことをお勧めします。 別のボタンを押してラジオボタンをリセットすることをお勧めします
$ ie.radio(:値、「バター」)。 クリア
フレーム(レイヤーです)説明
HTMLドキュメント名=メッセージID = src = frameshop-intro.html
オブジェクトフレーム
認識方法$ ie.show_all_objects
$ ie.show_frames
その他の方法注:フレームは通常のIEウィンドウのように動作します。 インデックスだけでなく、名(姓)でもアクセスできます。通常は、アクセスするために別の変数が作成されます。 また、多くの場合、フレームは他のフレームにネストされます。
最も使用される方法例
$ f1 = $ ie.frame(:名前、「メッセージ」)
$ f2 = $ ie.frame(:インデックス、1)
$ f1.show_all_objects
最後の行は、通常のオブジェクトのように、すべてのフレームオブジェクトを返します。
テクニックポップアップ処理JavaScriptやその他の技術を使用したクライアント側の検証スキームが広く普及しているため、Webアプリケーションのテストではポップアップが頻繁に発生します。
これらは、IEブラウザによって生成されるものと、アプリケーション自体によって生成されるものの2つのタイプに分けられます。
IEは通常、一度だけ表示されるポップアップを生成します。 少なくとも、暗号化されていないデータを転送したり、フォームを送信したり、パスワードの記憶について尋ねたりするときに表示されるWindows警告ウィンドウを確認してください。 IE設定でこのようなウィンドウの表示をブロックし、スクリプトで処理しないことをお勧めします。 JavaScriptとActiveXはウィンドウを形成し、ユーザーにこのアクションまたはそのアクションの確認を要求し、誤ったデータを表示するなど。 IEは、javascriptダイアログが閉じられるまでページが完全にロードされたとは認識しないため、Rubyスクリプトはダイアログが閉じられるまで作業を完了しません。
これは問題を引き起こす可能性があります。ウィンドウを閉じるには前の手順を実行する必要があるためですが、ダイアログボックスのために完了できません。
このような状況を防ぐには、javascriptポップアップの表示をトリガーする可能性のあるアクションを別のスレッドで実行することをお勧めします。 これにより、別のスレッドがウィンドウが閉じるのを待っている間、メインスクリプトが動作し続けることができます。
スレッド
確認ボタンをクリックして、ダイアログを閉じます。
クリッカー= WinClicker.new
Clicker.clickJavaScriptDialog(「OK」)
非表示のフレーム場合によっては、show_frames関数が0を返しますが、ページ上のフレームの多くまたはすべてが非表示フレームの一部になる場合があります。 ページにオブジェクトが視覚的に含まれているが空のリストが返される状況に直面している場合は、それらが非表示のフレームにあるかどうかを確認してください。 次のコマンドを使用します。
$ ie.frame(:インデックス、1)...
これにより、インデックスによってフレームにアクセスできます。 メインフレームのインデックスは0、2番目の行はそれぞれ1です。
インタラクティブスクリプトRubyとWATIRでスクリプトを記述するプロセスに慣れると、独自のレコーダが不足しているため、おそらく非常に時間と手間がかかることに気付くでしょう。 憂鬱な憂鬱を打破する1つの方法は、ビルトインのルビーインタープリターを時々使用することです。
インタープリターは、開いているブラウザーでスクリプトを1行ずつデバッグする機能を提供します。 最初からスクリプトを毎回実行する代わりに、show_links、show_all_objectsなどの上記のメソッドを使用して、表示されたページ上のオブジェクトを認識できます。
別の方法は、インタラクティブなshow_active_method関数です。 現在フォーカスされているオブジェクトを認識するために使用されます。
puts $ ie.show_active()
ヒントとコツ組み込みのルックアップtodaysDate変数を月月年(04212006)の形式で現在の日付に設定します
$ todaysDate = Time.now.strftime( "%m%d%Y")
文字列の日付を現在の日付値に置き換えます
pimsSQL「name = '#_ 1'およびprime_broker = 'Bobby Brown'のblotter_fundsから削除」
または同じ、文字列連結のみを使用
pimsSQL "名前= '" + $ todaysDate + "_1'およびprime_broker = 'Bobby Brown'のblotter_fundsから削除"
元の記事へのリンク:www.thoughtworks.com/insights/blog/creating-automated-test-scripts-ruby-and-watir