パート1
今日は、CucumberとSelenideフレームワークを使用して、サイトのUIスモークテストを作成する方法について説明します。 この記事は、これらのフレームワークについてまったく何も知らないジュニア向けに設計されています。 経験豊富な後輩は、 第2部で私が数ヶ月に達した興味深い点を見つけるでしょう。
この記事は2つの部分で構成されています。
- 最初はテストの作成を最も簡単な方法で説明します-テストが実行されず、フレームワークの複雑なものは使用されません。 Selenideを使用して、機能の説明( .featureファイル)とステップの説明クラスを作成するだけです。
- 2番目のパートでは、同じテストで、 Selenideからあらゆる種類の興味深いものを追加します。機能のテキスト(多くの「機能」という単語)を含む美しいレポートを作成する方法を確認します。
フレームワーク
Selenideは、Seleniumをラップするフレームワーク(またはライブラリ)です。 それがどのように異なるかは、著者のアンドレイ・ソルンツェフによって美しく説明されています。 主な違いは、 Selenideを使用すると、UIテストの作成時のコード行を削減できることです 。これは、テストの作成/コードの作成時の主なタスクの1つです。
Cucumberは、 BDD / TDDアプローチを実装するフレームワークです。
私はBDD / TDDの深い理論的知識を持っているふりをしていませんが、私にとってはこれまでと同じです。
実用的な観点からのBDD / TDD:
- それらはビジネスから生まれます。 プログラマがどの機能に基づいて新しい機能を登録する必要があるかに基づいて、機能-機能を作成する
プログラマーがコードを書き始める前に(ほとんどの場合行われるように)、テスターとプログラマーの両方がラウンドテーブルに座って、機能が正確にどのように機能するかを議論します。 ラウンドテーブルの結果は、紙に書かれた機能です。特定の結果につながる一連のクライアント/ユーザーアクションです。a)ここをクリックします。 b)そこに数字を入力しました。 c)そこに結果を得た
このような円卓の結果として、このすべての機能について1つの理解が作成され、紙に文書化されます。
- さらに、記述された機能に従って、プログラマーはコードを書き始めます。 また、 Cucumberのおかげで記録された機能が将来のテストであるため、テスターは並行してテストの作成を開始します。 プログラマーがコーディングを終了して初めてテストを完了することができるのは明らかですが、この方法ではコードとテストの作成が並行して行われるため、開発プロセスが高速化されます。
キュウリのその他の利点:
- テストの作成時にはログ記録は不要です-各ステップ(ユーザーアクション)は基本的にログ記録です。
- 人間が読めるテストの説明-テストは、ビジネス関係者でも理解できるようになります。これは、テストレポートのデモンストレーション時に役立ちます。
- バグを説明するときに、再現するための手順を考える必要はありません-必要な手順はコピーアンドペーストでレポートから取られます
最初の単純な部分simple_selenide_cucumberを分析しましょう。
プロジェクト構造:
Intellij IDEA 、 MavenおよびJunitを使用します。
ログイン 、テストを操作するためのアカウントパスワードはmail.txtに記録されます 。 注意:自宅で始める場合、システムは1つのログイン/パスワードでログインするユーザーの1人を除外することに注意してください。 メールを変更する
pom.xmlで 、次の依存関係を記述します。
<dependencies> <dependency> <groupId>com.codeborne</groupId> <artifactId>selenide</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-java8</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
smoketest#1.featureファイルはまさに機能(機能の説明)であり、円卓でプログラマーとテスターによって(理想的な世界では)合意されました。 ご覧のとおり、これはサイトでのユーザーのアクションの説明であり、人間が読める形式で記録されています。 また、各ステップ(アクション)が非常に複雑なロジックを意味しない限り、ログファイルでもあります。
Feature: smoke test #1, go through the service to Yandex-pay-page Scenario: go through the service to button "" #actions at first page Given open riskmarket.ru When press button with text " " And type to input with name "userName" text: "riskmarket.testoviy2016@yandex.ru" And type to input with name "password" text: "l0dcfJMB" And press element with value "" ... Scenario: go through service to yandex pay-page Given press button with text "" #actions at third page When type to input with name "lastName" text: "TESTOVIY" ...
UIテストの作成は、拡張子.featureを持つこのファイルから始まります。 test/java/…/features/
packageに入れてください
機能は次のキーワードで始まる必要があります。
Feature:
ここでは、機能が正確に行うことを一般的な用語で示します。 私たちの場合、スモークテストは「サービスを経由してYandex.Paymentsページに移動」です。
次はキーワードです。
Scenario:
スクリプトは、実際には別のテストです。 機能には、必要な数のスクリプト(テスト)を含めることができます。 すべてのシナリオは、明らかにこの機能に関連する必要があります。 この場合、2つのシナリオがあります。1つ目は「購入」ボタンに移動し、2つ目は支払いページに移動します 。 テストの規則に従って、スクリプト(テスト)は独立している必要があります。 1つのシナリオを渡すことの成功は、2番目のシナリオを渡すことの成功に依存すべきではありません。 注意 :私たちの場合、これは満たされていません-2番目のシナリオは最初のシナリオが停止した場所から開始され、最初のシナリオが落ちた場合は2番目のシナリオも始まります。
また、スクリプトには、その機能の簡単な説明も含まれています。
次はステップ自体です。 各ステップの前に、キーワードGiven, When, Then, And
またはBut
いずれかが必要です。
Given
-初期条件を示します、 「与えられた:そのようなものとそのようなもの」
When
-ユーザーのアクション: ここをクリックして、その後待機します
Then
-得られる結果:ほとんどの場合、それは特定のチェックです、私たちの場合のように
Then element with tag "search-result-item" should exist
そして
Then verify that page with url "http://money.yandex.ru/cashdesk" is opened
And
、 But
-は、読みやすくするために「and」 、 「but」の結合として使用されます。 「and」を使用すると、すべてが明確になります。 「しかし」は、例えば、 「...このものは見えるはずですが、このものは隠されるべきだ」という考えを説明するステップで使用できます。
これらの3つの部分( Given, When, Then
)へのステップの分離を観察してください。 これらはBDD / TDDルールです。
機能を記述した後、テストを実行できます(機能ファイルを右クリック->実行)。 結果は、多くのUndefined step: < >
ます。 システムは、各ステップを完了する方法がわからないことを示唆しています。 ステップ実行のロジックをスリップする必要があります。 IDEAで記述する場合、未定義のすべてのステップが強調表示されます。 Altキーを押しながらEnterキーを押し、値を変更せずにすべてのダイアログボックスを表示します。 MyStepdefs
クラスが作成されます(便宜上、 steps
パッケージに配置しました)。 次のようなものが表示されます。
@Given("^open riskmarket\\.ru$") public void openRiskmarketRu() throws Throwable { // Write code here that turns the phrase above into concrete actions throw new PendingException(); }
デフォルトでは、ステップを定義するメソッドはPendingException()
スローします。 これは、不確実な手順がなく、テストを書き続けることができるようにするために必要です。 つまり 機能はプログラマーによって作成されますが、一部の手順は既に決定されている場合があり、一部はプログラマーがコードを作成するのを待つ必要があります。 テストを実行するたびに、システムはまだ決定されていないステップを通知します。
ラムダ式を使用して手順を説明することもできます。 しかし、ここではそれを説明しません。なぜなら、 これは別の問題です。 昔ながらの方法で行います。
stepの定義をさらに詳しく調べてみましょう。
@Given("^open riskmarket\\.ru$") public void openRiskmarketRu()
最初の行は注釈であり、 Cucumberはこの定義がどのステップを参照しているのかを理解しています。 @Given
に、前述のように、 @And/@Then/@But/@When
が@Given
ます。 次に、 正規表現引数が注釈引数で使用されます。
正規表現は別の記事のトピックであり、どこかで読むと、資料はいっぱいです。
開始に使用される主要な正規表現記号は次のとおりです。
- ^-行の始まり
- $-行末
- (。*)-任意のテキスト
- "([^"] *) "-任意のテキスト、ただし引用符内
次の行はpublic void openRiskmarketRu()
はメソッドの名前です。 ステップを定義するメソッドは常にpublic void
なければなりません。 Alt + Enterを使用すると、IDEA自体がメソッドの名前を合成します。ほとんどの場合、これで十分です。
いくつかのステップを分析しましょう。
ステップ論理記述で使用されるセレン化物
機能ビュー:指定さ
Given open riskmarket.ru
MyStepdefsで表示:
@Given("^open riskmarket\\.ru$") public void openRiskmarketRu() { open("http://riskmarket.ru"); }
Selenideの
open(…)
メソッドのおかげで、 WebDriverのインスタンスが 1行(デフォルトではFirefox)で作成され、指定されたURLへの遷移が発生します。 インスタンスを閉じる/殺す必要はありません、それはセレニドを作ります
機能の入力:
When press button with text " "` And press button with text " " Given press button with text "" And press button with text ""
MyStepdefsで表示:
@When("^press button with text \"([^\"]*)\"$") public void press(String button) { $(byText(button)).waitUntil(Condition.visible, 15000).click(); }
ステップを再利用する例を次に示します。 コードを生成しないで、できるだけ頻繁に手順を再利用してください。 この例では、注釈引数で「ボタンには任意のテキストを含めることができますが、引用符で囲む」ことを示しています 。 すばらしいのは、どの言語でも使用できることです。
一般的に言えば、ステップを説明するために任意の言語を使用することもできます。次のように書くことができます。
And ""
ボタンの名前は引数であるため、メソッドシグネチャで指定します。
public void press(String button)
$()
は、ページ上の要素を見つけるためのSelenideメソッドです。 さまざまな便利なオプションがあります。 この場合、テキストを含む要素を探しています。 インターネットがあまり高速でない場所から記事を書いているので、要素が表示されるまで待機時間を増やす必要があります。 4秒間の組み込みタイムアウトでは不十分です。$(byText(button)
は$(byText(button)
型のオブジェクトを提供します。これは、他のメソッドの中でも特にwait-waitUntil(Condition, timeout)
待機している条件です。
Condition
はSelenideクラスであり、多くの異なる条件を記述します。外観は便利です。
そして最後に、要素の出現を待ってからクリックします。
ところで、ここで1行で説明しているのは、純粋なSeleniumでは、WebDriverWaitを作成して、数行のコードを取得することです。
機能の入力:
And type to input with name "userName" text: "riskmarket.testoviy2016@yandex.ru" And type to input with name "password" text: "l0dcfJMB” When type to input with name "lastName" text: "TESTOVIY" And type to input with name "firstName" text: "TEST"
MyStepdefsで表示:
@And("^type to input with name \"([^\"]*)\" text: \"([^\"]*)\"$") public void typeToInputWithNameText(String input, String text) { sleep(1000); $(byName(input)).sendKeys(text); }
このステップはフレームの出現後のいずれかの時点で使用されるため、入力を表示する前に一時停止する必要があります-Selenide
sleep(timeout with ms)
を使用して実行します。
sendKeys(String)
-テキストを要素に送信します。
機能の入力:
And select countries: , ,
MyStepdefsで表示:
@And("^select countries: (.*)$") public void selectCountries(List<String> countries) { for (String str : countries) { $("#countryInput").sendKeys(str); $("#countryInput").pressEnter(); } }
ステップをパラメーターとして記述する場合、リストを取ることができます-アイテムはコンマでリストされます。
残りの手順は、上記の手順と同様です。
pom.xmlでは 、正しいURLが開かれていることの確認がassertThat()を使用して行われる最後のステップのためにのみ、Junitがこのプロジェクトに追加されました。
これで最初の部分は終了します。 自動スクリーンショット、カスタムCondition
、 PageObject 、要素の注釈、美しいレポートの作成についての第2部をお読みください。