UiPath Studio「コード化されたテストケース」で、デモサイトUiBankの処理を実装してみよう。

# はじめに

UiPath Studioの **「コード化されたテストケース」** をご紹介しました。
別パターンとしてタイトルの内容を実装して紹介します。

操作概要は前回の記事でも触れていますので、こちらも合わせて参照してみてください。

https://qiita.com/moripo/items/aabc93a6098b39cc9d00


#### ◆ デモサイトのUiBankとは…

UiPath Studioの学習などでも使われるデモ用のサイトです。
今回はこちらを使ったケースを実装してみます。URLは以下です。

https://uibank.uipath.com/

:::note
当記事の内容はUiPath Stutio v23.10を使用しています。
:::


## 当記事で使用した設定について

当記事ではUiPath Studioの「プロジェクト」と「コード化されたテストケース」を下表のように定義しました。

|プロジェクトの名前|コード化されたテストケースの名前|
|-----|----|
| **CodedTestUiBank** | **CodedTestcase** |

これがコード内の下図の名前に対応しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/d87bf3e3-e21f-0b90-5a77-35cb9d05aa36.png)

「プロジェクト」の名前（つまり **namespace** ）を合わせることで、
下に貼るC#コードをコピー＆ペーストで実行可能になります。

:::note
違うプロジェクト名を指定した場合でも、**namespace**  以下のブロックをコピー＆ペーストする手順でC#コードを別のプロジェクトで実行できます。
:::


# 手順１：　オブジェクトリポジトリを定義します。

当記事内で少し手間が掛かる作業ブロックです。
別記事としてまとめています。

https://qiita.com/moripo/items/b81538b57532f78127ee

# 手順２： 「コード化されたテストケース」を実装します。

右クリックで作成したテストケースに、以下のコードをコピー＆ペーストします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/ec152858-13f0-05a9-8c57-dcc6cd3bb9a4.png)

基本的な手順は以上です。

```CodedTestcase.cs
using CodedTestUiBank.ObjectRepository;
using System;
using System.Collections.Generic;
using System.Data;
using UiPath.CodedWorkflows;
using UiPath.Core;
using UiPath.Core.Activities.Storage;
using UiPath.Orchestrator.Client.Models;
using UiPath.Testing;
using UiPath.Testing.Activities.TestData;
using UiPath.Testing.Activities.TestDataQueues.Enums;
using UiPath.Testing.Enums;
using UiPath.UIAutomationNext.API.Contracts;
using UiPath.UIAutomationNext.API.Models;
using UiPath.UIAutomationNext.Enums;

namespace CodedTestUiBank
{
    public class CodedTestcase : CodedWorkflow
    {
        /**
         * テストケースとして実行されるのは、このExecuteメソッドです。
         * 当事例では、ここから各処理を呼び出す形で実装しました。
         */
        [TestCase]
        public void Execute()
        {
            Log("Test run started for UiBankLoanApplication.");

            /** 画面ごとに関数を分けて操作 */
            操作1();
            操作2();
            操作3();
            /** テスト内容 */
            検証();
        }
        
        /**
         * ～Opitionは各操作に応じたオプション指定です。エラー前に待つのが嫌なのでゼロ指定した後、少し調整しています。
         * 画面の描画時間に応じてカスタマイズが必要です。
         */
        public TypeIntoOptions typeIntoOpt => new TypeIntoOptions() {
            DelayBefore = 0,
            DelayAfter = 0,
            Timeout = 0
        };

        public ClickOptions clickOpt => new ClickOptions() {
            DelayBefore = 0,
            DelayAfter = 0,
            Timeout = 0
        };

        public GetTextOptions getTextOpt => new GetTextOptions() {
            DelayBefore = 1,
            DelayAfter = 0,
            Timeout = 1
        };
        /**
         * シミュレート入力で画面を開くオプション指定
         */
        public TargetAppOptions simulateOpt => new TargetAppOptions() {
            InteractionMode = NInteractionMode.Simulate,
            OpenMode = NAppOpenMode.IfNotOpen,
            AttachMode = NAppAttachMode.SingleWindow
        };
        
        /**
         * WindowMessage入力で画面を開くオプション指定
         */
        public TargetAppOptions winMsgOpt => new TargetAppOptions() {
            InteractionMode = NInteractionMode.WindowMessages,
            OpenMode = NAppOpenMode.IfNotOpen,
            AttachMode = NAppAttachMode.SingleWindow
        };
        
     
        /**
         * 以下は、操作と検証の具体的な実装内容です。
         */
        public void 操作1()
        { 
            var homeScreen = uiAutomation.Open("Chrome: UiBank", simulateOpt);
            homeScreen.Click("Products" , clickOpt);
            homeScreen.Click("Loans" , clickOpt);
        }
        
        public void 操作2()
        { 
            var app = uiAutomation.Open("Chrome: UiBank Loan" , simulateOpt);
            app.Click("Apply For A Loan" , clickOpt);          
        }
        
        public void 操作3()
        {   
            var loanScreen = uiAutomation.Open("Chrome: UiBank application" , winMsgOpt);
            loanScreen.TypeInto("Age", "18");
            loanScreen.TypeInto("Email Address",  "test@test.test" );
            loanScreen.TypeInto("Current Yearly",  "3000");
            loanScreen.TypeInto("Loan Amount Requested",  "100");
            loanScreen.TypeInto("Loan Term",  "5" );
            loanScreen.Click("Submit Loan Application");
        }
        
        public void 検証()
        {
            string loanRate = null;
            var loanRequestScreen = uiAutomation.Open("Chrome: UiBank Submitted" , simulateOpt);
            var successMsg = loanRequestScreen.GetText("Approved Message" , getTextOpt);
            Console.WriteLine(successMsg);
            if(successMsg.Contains("approved"))
            {
                loanRate = loanRequestScreen.GetText("Loan Rate");
            }
            else
                loanRate = "0";
            
            Console.WriteLine("Loan Rate: "+ loanRate);
            testing.VerifyExpression(loanRate.Contains("11"));
        }
    }
}
```


# 実行結果： ログ出力は以下のようになりました。

ブラウザが起動し、一通りの自動操作が完了します。キャプチャは割愛します。
出力ログは以下です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/347d16b3-832f-8914-5b7b-01c304a43a2f.png)

#### もしエラーが発生する場合は…
「オブジェクトリポジトリ」とコード内の要素を指定する文字列が合っていないか、
「オブジェクトリポジトリ」自体の定義にミスがあるかもしれません。


# 実装の概要説明
主として実行される **Execute** メソッドは完結にして、処理内容は画面ごとに別の関数内に実装しました。
ポイントがあるとすると、 **文字列として指定する内容がオブジェクトリポジトリと対応している** ことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/6268594a-c7a0-478f-3a83-435d76ea2af3.png)

要素に対する操作のオプションを用意しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/38d5e712-e227-50a1-18f6-dda122cbc94e.png)

画面を開く際のオプションは２種類用意しました。（理由は以下に書きます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/6614668f-8cd9-eaee-2080-9f7f3ec0489f.png)

#### 画面を開くオプションを２種類用意した理由
こちらは高速な **シミュレート** 処理のみで検証したところ、
下図の **Loan Termの入力欄（テキストとプルダウンができる入力欄）** がシミュレートでの入力を受け付けませんでした。

そこで、**WindowMessage** でのオプションも用意して対策しています。
（こちらは実務向けの実装でも発生する事象だと思います）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3302589/a4b4e062-757c-8002-378d-2f66ffb7a909.png)

:::note warn
オプション無しのデフォルトでも動作することも確認していますが、明示的にオプションを指定する方法を選びました。

実運用でも、画面の仕様によって当オプションを使い分ける必要がありそうです。
:::


# まとめ

デモサイトUiBankで実装したサンプルをご紹介いたしました。
異なる画面構成を含む実装ですので、より実運用に近いのではないかと思います。

「オブジェクトリポジトリ」と「コード内の要素指定」の紐付きが認識し易いように、意図的に文字列をベタ書きにしています。

こうしてテストコードをQiitaでご紹介しやすい点も当機能のメリットの１つですね。
少しでも理解を深めていただいたり、実際に使ってみよう…と思っていただけると幸いです。