【ABAP】ABAP Unitを使ってみよう(3)　～CDSビューのテスト

##はじめに
この記事は、「ABAP Unitを使ってみよう」シリーズの3回目です。
過去の記事はこちら↓
[【ABAP】ABAP Unitを使ってみよう(1)　～簡単なところから](https://qiita.com/tami/items/374c315ff88249db1b7d)
[【ABAP】ABAP Unitを使ってみよう(2)　～Test Doubleで依存性を解決する](https://qiita.com/tami/items/117952bfe22ec2ba0e0f)

##【今回のテーマ】CDS Test Double Framework
CDSビューのテストをするときの課題は、テスト対象のビューが他のCDSビューやテーブルに依存している場合があるということです。これらのビューやテーブルをTest Doubleに置き換えるために、CDS Test Double Frameworkが用意されています。

##テストの種類
CDSのテストには以下の2種類があります。

###①Unit Test
テスト対象のビューの直下にあるオブジェクトをTest Doubleに置き換えて行うテスト。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/c16377c6-2a84-87bd-3526-c2790791880f.png)
[ABAP CDS Test Double Framework](https://help.sap.com/viewer/5371047f1273405bb46725a417f95433/Cloud/en-US/cbedc08ff4de48ffa8d04d3067ef08e7.html)より引用

###②Hierarchy Test
①階層関係にある複数のCDSビューをまとめてテストする方法。階層にあるすべてのCDSをテストするには、最下層にあるテーブルをTest Doubleに置き換える必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/036959c1-a121-65d8-aa4a-eb6e0204fa9a.png)
[ABAP CDS Test Double Framework](https://help.sap.com/viewer/5371047f1273405bb46725a417f95433/Cloud/en-US/cbedc08ff4de48ffa8d04d3067ef08e7.html)より引用

##テストシナリオ
受注にひもづく、最大の明細の最大の納入日程行を取得するCDSビューを作成しました。CDSビューは以下のような階層になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b683d512-db18-0e55-96cc-fcc51f8becbd.png)

てっぺんにあるのがテスト対象のCDSビューです。今回はビューで使用するDBを全てTest Doubleに置き換えます。

＜テストの観点＞
①1件の受注に複数明細、複数納入日程行がある場合に、1行だけに絞れているか
②取得した行が本当に最大明細、最大納入日程行になっているか

##テストの手順
###テスト用クラスを登録
Project Explore上でテスト対象のCDSビューを右クリックし、New ABAP Test Classを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/663d416c-120a-d9ed-cd84-c47760981336.png)
複数階層のCDSビューをテストするので、Test TypeはHierarchy Testを選択します。Test Doubleに置き換えるテーブルとして、vbapとvbepにチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/699f99dc-4b16-a499-8603-6e3425fe256a.png)


###テストデータの登録
次の画面では、テスト用のメソッド名と、テストデータを入力します。赤枠で囲ったボタンを押すと、行を追加することができます。また、右端のボタンからはテストデータをテキストファイルでインポートすることができます。
※後に、受注番号を全て'0000000001'に変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f0f9aa78-f92a-74dd-9905-53b4354cc3d5.png)

vbepにも同様にテストデータを登録しようとしましたが、なぜか2行目までしか入りませんでした。この後生成されるコードに手で追加することにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/966810b5-4cb1-9db6-24d7-eeb77f131485.png)


**テストデータを登録する部分のソース（抜粋）**
最終的に以下のようにテスト用のコードが自動で生成されます。テストクラスの中身は[前回](https://qiita.com/tami/items/117952bfe22ec2ba0e0f)のABAP SQL Test Double Frameworkのテストクラスと非常によく似た構成になっています。
自動生成コードのデメリットは、データ1行追加するのに行を取ることですね…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/edce5f9c-bbaa-63a3-fb11-735cbce20ba6.png)

納入日程行のテストデータを、以下の内容で追加します。（網掛けが最大明細、最大納入日程行の行）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/f9f9e448-ddd6-3284-64f3-ae658670ee85.png)


###テストを書く
今回、ひとつのメソッドに2つのassertを書きました（1回のSELECT結果に対する確認なので）。
assert_equalsメソッドのパラメータquitに`if_aunit_constants=>quit-no`を指定すると、エラーがあってもテストが続行されます。

```abap
  METHOD get_schedule_line.
    data: ls_exp type zmob49_i_soschedule_max.

    prepare_testdata_set( ).
    SELECT * FROM zmob49_i_soschedule_max INTO TABLE @act_results
    WHERE vbeln = '0000000001'.

    "テスト1: 1行だけ取得されること
    describe TABLE act_results lines data(lv_lines).
    cl_abap_unit_assert=>assert_equals(
      EXPORTING
        act                  = lv_lines
        exp                  = 1
        msg                  = 'Number of records is not 1'
        quit                 = if_aunit_constants=>quit-no "エラーでも続行
    ).

    "テスト2: 最大の明細、納入日程行が取得されたこと
    read table act_results into data(ls_result) index 1.
    ls_exp = value #( vbeln = '0000000001' posnr = '000020' etenr = '0002').
    cl_abap_unit_assert=>assert_equals(
      EXPORTING
        act                  = ls_result
        exp                  = ls_exp
        msg                  = 'Max item, schedule line has not been retrieved'
        quit                 = if_aunit_constants=>quit-no
    ).

  ENDMETHOD.
```
##テスト結果
正常終了しました。CDSの場合、実物を作る前にテストを書くというわけにはいかなさそうです。CDSからテストクラスを作るのですから…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/9d793d2b-ac66-fcc3-563c-816e7cad7cbd.png)

##CDS Test Double FrameworkとABAP CDS Test Double Frameworkの違いは？
CDS Test Double FrameworkとABAP CDS Test Double Framework、同じ使い方のように見えますが違いは何なのでしょうか。ヘルプ（[ABAP](https://help.sap.com/viewer/5371047f1273405bb46725a417f95433/Cloud/en-US/1432ca1fc7b547d493f691cdd09245ae.html)、[CDS](https://help.sap.com/viewer/5371047f1273405bb46725a417f95433/Cloud/en-US/cbedc08ff4de48ffa8d04d3067ef08e7.html)）を参考にできることを比べてみると以下のようになります。ざっくりとですが、CDS Test Double Frameworkのほうが色々できて、WRITE accessだけはABAP Test Double Frameworkでやる必要がある、ということでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4380af90-1759-d4ea-d918-734addf52dbb.png)

##感想
CDS Test Double Framework、ウィザード形式でテストデータも登録できるので、かなり便利です。多段階のCDSや複雑なパターンがあるときに役立ちそうです。