Tuesday, 23 September 2025

Belajar ABAP Part 13: CDS Consumption View (UI Annotation) & Unit Testing AMDP

Belajar ABAP Part 13: CDS Consumption View (UI Annotation) & Unit Testing AMDP

Belajar ABAP Part 13: CDS Consumption View (UI Annotation) & Unit Testing AMDP

Ringkasan: Di Part 13 ini lo bakal belajar dua hal krusial untuk ABAP modern:
  1. CDS Consumption Views + UI Annotation — bagaimana membuat CDS yang siap dipakai Fiori/OData dengan @UI.hints agar kolom muncul rapi di apps.
  2. Unit Testing AMDP — pattern dan contoh ABAP Unit untuk menguji AMDP (SQLScript) secara repeatable di development/CI pipeline.
Target: membuat data model yang consumable & procedure DB yang dapat diuji otomatis.

Bagian A — CDS Consumption View + UI Annotation

1) Tujuan dan kapan pakai Consumption View

Consumption View adalah layer CDS yang dioptimalkan untuk konsumsi (UI, OData, analytical). Pakai ini ketika lo ingin:

  • Expose data ke Fiori/Smart Template apps
  • Menyediakan field yang relevan di grid/detail view
  • Mengontrol metadata UI (label, ordering, search, filter)

2) Contoh sederhana: CDS Consumption View dengan UI Annotations

Contoh: kita punya basic view ZCDS_PO_BASE (PO header) dan mau bikin consumption view untuk Fiori list.


@AbapCatalog.sqlViewName: 'ZV_PO_BASE'
@EndUserText.label: 'PO Base View'
define view ZCDS_PO_BASE as select from ekko {
  key ebeln,
      bukrs,
      lifnr,
      bedat,
      netwr
}
    

Sekarang bikin consumption view dengan UI annotation:


@AbapCatalog.sqlViewName: 'ZV_PO_CONS'
@EndUserText.label: 'PO Consumption for Fiori'
@AccessControl.authorizationCheck: #CHECK
@OData.publish: true
define view ZCDS_PO_CONSUMPTION
  with parameters
    p_companycode : bukrs
  as select from ZCDS_PO_BASE
{
  key ebeln                                                      as PurchaseOrder,
  bukrs                                                          as CompanyCode,
  lifnr                                                          as Vendor,
  bedat                                                          as DocumentDate,
  netwr                                                          as NetValue,

  @UI.lineItem: [{ position: 10 }]
  @UI.selectionField: [{ position: 10 }]
  netwr                                                           as Amount
}
where bukrs = :p_companycode;
    

Penjelasan annotation penting:

  • @OData.publish: true → CDS akan expose service OData otomatis (aktifkan di /IWFND/MAINT_SERVICE).
  • @AccessControl.authorizationCheck: #CHECK → mengaktifkan pemeriksaan authorization (CDS-based ACL jika ada).
  • @UI.lineItem → menentukan kolom yang tampil di table/list (Fiori Smart Template).
  • @UI.selectionField → menentukan field yang tampil di filter bar (selection).

3) Men-deploy & expose OData service

  1. Activate CDS view di ADT (Eclipse) atau SE11 (jika tersedia).
  2. Buka /IWFND/MAINT_SERVICE → tambahkan service OData yang dibuat (service name biasanya autogen dari CDS).
  3. Test OData endpoint: https://{host}:443/sap/opu/odata/sap/{SERVICE_NAME}/ (SERVICE_NAME lihat di SDA atau di service registration).
  4. Gunakan Fiori Smart Template app (List Report) untuk konsumsi otomatis berdasarkan annotations.
Note: Untuk Fiori-ready UX, lengkapi juga annotation UI seperti @UI.headerInfo, @UI.lineItem dengan label, importance, dan @Search.searchable bila diperlukan.

4) Contoh annotation tambahan (headerInfo & search)


@UI.headerInfo: { typeName: 'PurchaseOrder', typeNamePlural: 'PurchaseOrders' }
@Search.searchable: true
@UI.lineItem: [{ position: 10, label: 'PO' }]
@UI.lineItem: [{ position: 20, label: 'Vendor' }]
define view ZCDS_PO_CONSUMPTION as select from ZCDS_PO_BASE { ... }
    

5) Tips praktis untuk CDS Consumption

  • Gunakan parameter pada consumption view bila perlu scoping (sebagai filter default).
  • Gunakan @ObjectModel.representativeKey bila key composite / perlu mapping ke entity.
  • Dokumentasikan mapping antara CDS field & requirement UI (label, format, currency).

Bagian B — Unit Testing AMDP (ABAP Managed Database Procedures)

1) Mengapa perlu unit test untuk AMDP?

AMDP mengeksekusi logic di database (SQLScript). Karena logic di-database berisiko (performa, hasil berbeda), kita butuh test automated agar:

  • Validasi correctness (aggregasi, bucketing, transform)
  • Mendeteksi regresi saat deploy
  • Mendukung CI/CD untuk ABAP/transport

2) Pendekatan testing untuk AMDP

Ada beberapa pattern:

  1. Integration-style ABAP Unit: buat test class ABAP Unit yang men-setup data di DB (insert ke table/temporary table), panggil AMDP, assert hasil.
  2. Mocking layer ABAP: bungkus pemanggilan AMDP di class ABAP non-AMDP yang bisa di-mock untuk unit test biasa (lebih mudah di-run tanpa DB dependency).
  3. HANA-side tests: tulis SQLScript test di HANA jika ada framework internal (lebih advanced).
Tip: untuk reliability, kombinasi approach #1 (integration tests di dev/CI) + #2 (pure unit tests untuk business logic wrapper) paling baik.

3) Contoh AMDP (kita pakai yang dari Part 12):


CLASS zcl_amdp_po_age DEFINITION
  PUBLIC
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_amdp_marker_hdb.
    CLASS-METHODS calc_po_aging
      IMPORTING iv_days1 TYPE i iv_days2 TYPE i
      RETURNING VALUE(rt_result) TYPE TABLE OF ty_po_aging.
ENDCLASS.

" (IMPLEMENTATION seperti Part 12 - menghasilkan rt_result)
    

4) Contoh ABAP Unit Test (Integration-style)

Keterangan pendek: test ini akan insert data test ke table EKKO/EKPO (atau ke table Z-temp jika prefer), lalu memanggil AMDP dan memeriksa hasil bucket.


CLASS ltc_amdp_po_age_test DEFINITION FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PRIVATE SECTION.
    METHODS:
      setup FOR TESTING,
      teardown FOR TESTING,
      test_po_aging_basic FOR TESTING.

    DATA: mt_ekko TYPE TABLE OF ekko,
          mt_ekpo TYPE TABLE OF ekpo.
ENDCLASS.

CLASS ltc_amdp_po_age_test IMPLEMENTATION.

  METHOD setup.
    " Prepare test data: insert sample PO header & item
    " NOTE: gunakan RFC/user dengan privilege; atau gunakan Z-table test isolation
    CLEAR mt_ekko.
    CLEAR mt_ekpo.

    DATA(ls_ekko) = VALUE ekko( ebeln = 'ZTEST0001' bukrs = '1000' lifnr = '000001' bedat = '20250901' ).
    APPEND ls_ekko TO mt_ekko.

    DATA(ls_ekpo) = VALUE ekpo( ebeln = 'ZTEST0001' ebelp = '00010' netwr = '500000' ).
    APPEND ls_ekpo TO mt_ekpo.

    " Insert to DB (use transportable test data table or temporary Z-table recommended)
    INSERT ekko FROM TABLE mt_ekko.
    INSERT ekpo FROM TABLE mt_ekpo.
  ENDMETHOD.

  METHOD teardown.
    " Clean up test data
    DELETE FROM ekpo WHERE ebeln = 'ZTEST0001'.
    DELETE FROM ekko WHERE ebeln = 'ZTEST0001'.
  ENDMETHOD.

  METHOD test_po_aging_basic.
    " Call AMDP
    DATA(rt_result) = zcl_amdp_po_age=>calc_po_aging( iv_days1 = 30 iv_days2 = 60 ).

    " Assert that result contains expected bucket (e.g., '0-30' or other depending bedat)
    cl_abap_unit_assert=>assert_not_initial( act = rt_result ).
    " find row for bucket '0-30'
    READ TABLE rt_result INTO DATA(ls_row) WITH KEY bucket = '0-30'.
    cl_abap_unit_assert=>assert_true( act = sy-subrc = 0 ).
    cl_abap_unit_assert=>assert_true( act = ls_row-po_count >= 1 ).
  ENDMETHOD.

ENDCLASS.
    

Catatan penting tentang contoh di atas:

  • Penggunaan EKKO/EKPO langsung di DEV bisa berbahaya → lebih aman pakai Z-table test atau transactionally isolated test data.
  • Pastikan user yang menjalankan test punya privilege INSERT/DELETE pada table target (biasanya di DEV/CI saja).
  • Gunakan TRANSPORTABLE atau test data reset agar test idempotent (selalu bisa di-run ulang tanpa efek samping).

5) Teknik Mocking / Wrapper untuk AMDP

Untuk unit test murni (tanpa DB), bungkus pemanggilan AMDP ke class non-AMDP (interface). Di unit test, mock class wrapper tersebut untuk mengembalikan hasil yang diharapkan.


INTERFACE if_po_aging_service.
  METHODS calc_aging IMPORTING iv_d1 TYPE i iv_d2 TYPE i RETURNING VALUE(rt) TYPE TABLE OF ty_po_aging.
ENDINTERFACE.

" Prod implementation: wrapper yang memanggil AMDP
CLASS zcl_po_aging_service DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_po_aging_service.
ENDCLASS.

CLASS zcl_po_aging_service IMPLEMENTATION.
  METHOD if_po_aging_service~calc_aging.
    rt = zcl_amdp_po_age=>calc_po_aging( iv_days1 = iv_d1 iv_days2 = iv_d2 ).
  ENDMETHOD.
ENDCLASS.

" Di unit test, buat fake/mock class (atau local test double) yang implement interface dan return static data.
    

6) Best Practices untuk Testing AMDP

  • Prefer test data di Z-tables khusus test agar tidak mengotori master/transactional table.
  • Jalankan integration tests di DEV/CI environment, bukan di sandbox/production.
  • Gunakan TEARDOWN untuk selalu bersih-bersih data test (DELETE by unique key).
  • Document precondition (HANA version, schema privileges, necessary objects).
  • Gunakan mocking wrapper bila perlu rapid unit testing.

Kesimpulan — Part 13

- CDS Consumption Views + UI annotations membuat model siap konsumsi Fiori/OData dengan sedikit usaha. - AMDP harus diuji: buat integration ABAP Unit tests (setup data → panggil AMDP → assert) dan gunakan wrapper/mocking untuk pure unit tests jika ingin tanpa DB dependency. - Kombinasi CDS (untuk modelling/exposure) + AMDP (untuk logic DB-heavy) + test automation = strategy yang kuat untuk aplikasi S/4HANA yang reliable dan performa tinggi.

👉 Lanjut ke: Belajar ABAP Part 14: Performance Tuning & HANA Optimization


Catatan: snippet di atas disederhanakan untuk pembelajaran. Untuk produksi, sesuaikan naming convention, object transport, dan policy keamanan (authorizations). Pastikan selalu validasi SQLScript functions pada HANA versi target.

No comments:

Post a Comment

Belajar SAP ABAP RAP

  Belajar SAP ABAP RAP: Pengenalan dan Konsep Dasar Restful ABAP Programming Model Kalau kamu seorang ABAPer yang mulai terjun ke dunia SAP...