[RealWorld Test Automation. Day 10] create test automation script for Travel booking by Ranorex

# Outline

今回は、Ranorexを使って１機能のテストコードを作成する
（いわゆる、Ranorexを使ってみた。的なw）
各過程で、重要なポイントやRanorexのtips等を執筆する

自分のtest automationの環境は、以下であり、これを前提に進めていきます

- Ranorex for test automation <A href="https://www.ranorex.com/"> Ranorex site </A>
- Using test environment Travel Serivce (本番環境では、実際に存在しないホテルやユーザーです！！)
- test automation script run once a day by Jenkins
- SPをテスト対象 (Chrome + UA change)

# Function outline

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/007e3d56-8a51-b554-28d7-422ca75eb1f8.png)

トラベルの予約処理を簡単に説明。

<B>1.Search </B>
検索のオプションを入力する

- キーワード
- 宿泊地のエリア
- 日程
- 部屋数
- 人数
- 合計料金のレンジ

検索結果でホテル・プラン一覧が表示される。
その中から、希望のプランを選択し、予約をする

<B>2.Booking</B>
予約に必要な情報を入力する

- 予約代表者
- 性別
- 電話番号
- チェックイン時刻
- 決済手段

<B>3.Result</B>
予約完了のメッセージ表示
予約内容の確認のための情報が表示される

# Test automation のテスト観点

scriptの前に、自動化で何をテストするのかを明確にする必要がある。
<A HREF="https://qiita.com/emurin/items/49c01da835e6df0555ee">2019/05/31 JaSST'19 Tohoku</A>ここで発表した通り、何をテストするのかを明確にしないと、テスト自動化が期待値通りのOUTPUTにならないからである。

テストすること

- TOPで希望したオプションを設定できる
- 検索結果で、所望のホテルプランが出力される（正常系）
- 予約情報入力で、所望の情報を入力できる（正常系）
- 予約完了できる（正常系）
- 予約完了の予約確認内容と所望の内容が一致すること（Validation）

テストしないこと（代表的なもの）

- サーチ結果がただしいこと（今回は、指定したホテルが結果に存在すればいい）
- 全般的に異常系
- デザインがただしいこと


# Scripting by Ranorex

### test suite

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/d1a01af5-3fb6-bea0-4143-8b6f647a13d4.png)


SETUP/TEARDOWNはテスト開始前、終了後に必ず実施する処理を定義。
そのため、各STEPでは以下のような処理を行う
 
<B>SETUP</B> (Common_OpenBrowser)

- ブラウザを起動する


<B>TEARDOWN</B> (Common_CloseBrowser)

- ブラウザを終了する

<B>Main</B> (Booking)

Book の test folderをTravelBookingという、Data SourceでData Drivenしてループして実行させている。
今回は、Bookの処理(Common_Logout ~ Booking_Validate_Result)を３回ループさせている。
各ループで使用するパラメータは、TravelBookingで定義されている

各Record Moduleの説明は以下の通り

1. Common_Logout : 強制的にログアウトさせる
2. Booking_Search_Hotel : 検索オプションを設定し、検索する
3. Booking_Choose_Hotel : 検索結果からホテルを選択し、宿泊情報を入力して予約を実施する
4. Booking_Validate_Result : 予約完了で、予約内容が正しいかをValidateする

### 1. Common_Logout 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/e558131b-7a4c-012b-b00e-bfa3d2cee9a1.png)

このRecord Moduleでは、単純にログアウトのページに遷移させる処理である。
この処理はデータの初期化であり、SETUPで行うべきかもしれないものであるが、Bookのループの先頭に入れた。
理由は以下の通りである。

- Book はループ処理で、Data Sourceの定義分繰り返し予約処理が行われる。そのため１ループ単位でセッションの初期化が必要になる
- Book 処理の途中で失敗した場合、そこで中断し引き続き次のループを処理させたい場合、どこで処理が失敗するかわからないため、ループの先頭に実施する必要がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/1cc9240e-b32e-c610-f419-65a6c60cf8d8.png)

Step.1 の Invoke Action Navigateは、指定したURL（ログアウトページ）に遷移させるものである。
そのときの対象Repository Itemとして、 "ANY" (domain ~ rakuten.co.jp)とした。
これは、先述の通り、この処理を実施する前提のいま開いているブラウザのURLが任意であるからである。

### 2. Booking_Search_Hotel 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/94a0fde5-b896-d462-817c-1d33cafd78ad.png)

Step1-2 はtravelのtopに遷移する処理である。

Step3-7 は宿泊地を２ステップで選択する処理である。
ページ遷移せず、モーダルがポップアップする仕組みである。
モーダルのポップアップ処理が完了する前にマウスクリップを行うと不安定になる可能性がある。
そのため、Step4,6のように、 Delayを置き、安定性を確保する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/24d70789-5c70-8b24-e3bb-ab0f8907b2f2.png)


Step8-15 はカレンダーでCheckIn,CheckOutを指定する処理である
CheckIn/CheckOutのカレンダーをオープンすると、下左のようなカレンダーが立ち上がる。
checkInの 期待値を checkIn_year/checkIn_month/checkIn_day とした場合、以下のような流れになる。
1. カレンダーのデフォルトの年月を取得
2. 希望の年月に遷移（”＞”ボタン）する
3. 希望の日をクリックする

Step10,14は、上記の１，２の処理をUser codeで実現している（下右図）
1. デフォルトの年月を正規表現で取得する
2. 期待値の年月から、何回”＞”ボタンをクリックするか算出
3. 上記で得られた回数、”＞”をクリック


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/b8b4fb0a-57a5-13a5-cf1e-a0355de9f25c.png)


上記のようにして、CheckIN, CheckOutのカレンダーを設定することができる。

Step16-22は部屋、人数を設定する処理である
Step23-24は合計料金の上限下限を設定する
Step25は検索ボタンを押す処理

### 3. Booking_Choose_Hotel 


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/1fdc44f9-b46c-ea77-0ddb-e61f9d886cb5.png)

Step1は期待値のホテルのプランの”予約”をクリックする
この”予約”ボタンのRepository Itemを取る時、ひと手間必要になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/7825d75f-c716-1802-dd34-4a469a19337b.png)

右図が”予約”ボタンのXpathである。
- ホテル名 "[stg][ForAutomationQA]Racco_domestic_hotel01" を変数 $hotel_nameとして特定する。
- ホテル名から２つ上のpathを指定する ( .. / parent::div )
- 上記pathの下にある”予約”のpathを指定する

なぜこのようにしているか。
期待値として、$hotel_nameの予約である。
Spayを使って、”予約”を取得した場合、デフォルトのXpathでは、ホテルを特定できない。

それを特定する詳細な手順は以下の通りである。

1. 期待値の”予約”のRepository itemの領域を探す。①
2. そこから、期待値の$hotel_nameのXpathを特定する　②
3. 上記xpathからあらためて、①の領域のXpathを特定する（②からの相対パス）
4. 上記①の領域から、”予約”のパスを特定する（①からの相対パス）

この流れで、Xpathを編集することで、先ほどのような期待値の一意の”予約”ボタンのXpathを取ることができる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/edb486f6-6687-a19b-e935-71bd13d1513f.png)

Step3-5はログインを求められるため、ID/Passowrdを入力し、”ログイン”をクリックする処理

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/44c78543-8f0c-5751-d6b9-c15de964826a.png)

Step6-19は、宿泊者情報を入力し、予約を確定する処理である

### 4. Booking_Validate_Result 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/49ea0e69-d6b6-6d21-c3ff-3693a39d80ad.png)

Step1-5 は予約完了ページの予約内容と期待値が同一であるかを確認する

チェックイン、チェックアウトは、年月日表示である。
期待値は、年、月、日とそれぞれ数値で定義しているので、表示フォーマットに合わせてvalidateする、User Code (Validate_Date)を作成した

料金合計は、期待値は数字で定義している。
一方表示は、カンマ区切りである。
そのため、表示フォーマット側を数値に変換してvalidateする、User Code (Validate_料金合計)を作成した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/827d4653-c82d-5741-961e-9a1b0c79f10c.png)

### Data source

Book Folderの中の各変数を以下のようなエクセルを使うことで実現することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/3a164206-61b6-f43a-ac71-ca8cd81a9b2a.png)



# summary

今回のテストの実装でのトピックは以下の通りである

- 作成時間はだいたい6時間である
- ループ処理を考慮した、初期化処理を考える
- モーダルポップアップ等は、処理不安定要素を取り除く工夫がいる
- カレンダーの日特定は、アルゴリズムを立ててからコードを書く必要がある（RanorexのGUIだけでは解決できない）
- Repository itemを一意に特定する場合、相対パスを組み入れる必要があるときがある
- Ranorexはtrial 30 days for free で使うことができます。


# Finally


次は9月18日（金）頃配信予定です。
引き続き、test automationのreal worldでのtipsを考えています


# back number

- <A HREF="https://qiita.com/emurin/items/af7b91b979159e27286a">[Lesson Test Automation. Day 01] What's Test Automation</A>
- <A HREF="https://qiita.com/emurin/items/750983107471386ea10a"> [Lesson Test Automation. Day 02] Test Layer and Tool</A>
- <A HREF="https://qiita.com/emurin/items/27f057b83bb2206868d3"> [Lesson Test Automation. Day 03] introduce test automation</A>
- <A HREF="https://qiita.com/emurin/items/34eea5255b414b3d1585">[Lesson Test Automation. Day 04] Test Automation Code Design vol.01</A>
- <A HREF="https://qiita.com/emurin/items/7feedeee162d205a1ed8">[Lesson Test Automation. Day 05] Test Automation Code Design vol.02</A>
- <A HREF="https://qiita.com/emurin/items/bb0e79fac43a569ad823">[Lesson Test Automation. Day 06] Test Automation Code Design vol.03</A>
- <A HREF="https://qiita.com/emurin/items/e9d7f26262eb599a2c7f">[Lesson Test Automation. Day 07] Test Automation Code Design vol.04</A>
- <A HREF="https://qiita.com/emurin/items/7aaa3f481cc57a340188">[Lesson Test Automation. Day 08] Test Automation Operation</A>
- <A HREF="https://qiita.com/emurin/items/b81241d159e69ab5c74e">[RealWorld Test Automation. Day 09] To reduce Jenkins operation set disable/enable in bulk</A>