skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
arc-mcp/arc-1222 installs

generate-cds-unit-test

Generate an ABAP Unit test class for a CDS entity using the CDS Test Double Framework — replicates SAP Joule's "CDS Unit Test Generation" capability. Use when asked to "generate CDS unit tests", "test this CDS view", "create CDSTDF tests", or "write unit tests for ZI_SALESORDER".

How do I install this agent skill?

npx skills add https://github.com/arc-mcp/arc-1 --skill generate-cds-unit-test
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    This skill generates ABAP unit tests for SAP CDS entities by reading system metadata and source code. It includes capabilities for system modification (writing and activating code) but employs a mandatory user confirmation step as a primary safety measure. A low-risk indirect prompt injection surface is present when processing untrusted CDS source code.

  • Socketwarn

    1 alert: gptSecurity

  • Snykpass

    Risk: LOW · No issues

What does this agent skill do?

Generate CDS Unit Test

Generate an ABAP Unit test class for a CDS entity using the CDS Test Double Framework.

This skill replicates SAP Joule's "CDS Unit Test Generation" capability by combining ARC-1 (SAP system access) with mcp-sap-docs (documentation & best practices).

Smart Defaults (apply silently, do NOT ask)

SettingDefaultRationale
Test class nameZCL_TEST_<entity_name>Standard convention
Package$TMPFast prototyping
Test scopeAll testable semanticsUser can narrow after seeing the list
Risk levelHARMLESSCDS test doubles don't modify real data
DurationSHORTUnit tests should be fast

Input

The user provides a CDS entity name (e.g., ZI_SALESORDER, ZC_TRAVEL).

Only the CDS entity name is required. If the user provides just an entity name, apply Smart Defaults and proceed immediately.

Optionally, the user may specify:

  • Test class name (default: ZCL_TEST_<entity_name>)
  • Package (default: $TMP)
  • Transport request (only needed for non-$TMP packages)

Step 1: Gather CDS Entity Context

Read the CDS entity, its field structure, and all dependencies in just 3 tool calls.

1a. Read the CDS DDL source

SAPRead(type="DDLS", name="<entity_name>")

1b. Get structured field list

SAPRead(type="DDLS", name="<entity_name>", include="elements")

Returns a formatted listing of all fields with key markers, aliases, association references, and expression types (calculated, case, cast, coalesce). Use this to understand the entity's structure without parsing raw DDL.

1c. Get dependency context (tables, views, associations)

SAPContext(type="DDLS", name="<entity_name>")

Automatically extracts all data sources (FROM, JOIN), associations, compositions, and projection bases from the CDS DDL. For each dependency, fetches the full source with type fallback (DDLS → TABL → STRU). This gives you:

  • Underlying table definitions with field types (needed for correctly-typed test data)
  • Other CDS view sources (needed to understand transitive logic)
  • Association targets

For deeper dependency graphs (e.g., a consumption view → interface view → table), use depth=2:

SAPContext(type="DDLS", name="<entity_name>", depth=2)

1d. (Optional) Read metadata extensions and behavior definition

SAPRead(type="DDLX", name="<entity_name>")
SAPRead(type="BDEF", name="<entity_name>")

These may fail if no DDLX/BDEF exists — that's fine, skip them. Only needed if the entity has UI annotations or RAP behavior.

Step 2: Analyze CDS Semantics and Propose Test Cases

Preferred (SAP_BASIS 8.16+ — ABAP Platform 2025 / S/4HANA 2025): ask SAP directly. SAP analyzes the entity for you and returns the authoritative list of testable semantics — the same CDS Test Double Framework engine behind SAP Joule's CDS unit-test generation:

SAPDiagnose(action="cds_testcases", name="<entity_name>")

Each suggestion carries a ready testMethod name, a semanticType (NONE = whole view, CALCULATION, CAST, JOIN, CASE, …), a description, and — for calculated/cast cases — the calculatedField. Use this as your proposed test-case list for the "Output to User" block below: it is SAP's own analysis, so prefer it over hand-parsing the DDL. Map each semanticType onto the category table and each testMethod onto a FOR TESTING method in Step 4. If the tool returns a "requires SAP_BASIS 8.16+" message (older releases / NW 7.5x don't expose the endpoint), or you want to cross-check coverage, use the manual analysis below.

Fallback / cross-check — analyze the DDL yourself. Analyze the CDS DDL source you read in Step 1 and identify all testable semantics. Group them by category:

Semantic Categories to Look For

CategoryWhat to Look For in DDLExample Test Case
CalculationsArithmetic expressions (field1 * field2, field1 - field2)Insert known values, verify calculated result
CASE expressionscase when ... then ... else ... endOne test per branch
Type castscast(field as abap.dec(15,2)), cast(field as abap.char(10))Insert value, verify cast output
WHERE filterswhere status = 'A' or where amount > 0Insert matching + non-matching rows, verify only matching appear
HAVING clauseshaving sum(amount) > 1000Insert data that triggers and doesn't trigger the filter
JOINsinner join, left outer join, associationInsert matching keys in both tables; test with non-matching keys for outer joins
Aggregationssum(), count(), avg(), min(), max() with group byInsert multiple rows, verify aggregated result
Null handlingcoalesce(field, 'default'), null-safe expressionsInsert row with null field, verify default
Parameterswith parameters p_param : typeCall view with parameter, verify filtering
Currency/Unit conversioncurrency_conversion(), unit_conversion()Insert conversion data, verify result
String operationsconcat(), substring(), length()Insert string values, verify output
Associationsassociation [0..*] to ...Insert data in both sides, verify navigation

Output to User

Present the identified test cases as a numbered list:

Identified test cases for ZI_SALESORDER:

1. [CALCULATION] test_net_amount_calculation — Verify net_amount = gross_amount - discount
2. [CASE] test_status_text_open — Verify status 'O' maps to 'Open'
3. [CASE] test_status_text_closed — Verify status 'C' maps to 'Closed'
4. [JOIN] test_customer_join — Verify customer data is correctly joined
5. [WHERE] test_active_orders_filter — Verify only active orders are returned
6. [NULL] test_description_coalesce — Verify null description gets default value

Ask the user: "Which test cases should I generate? (all / specific numbers / skip any?)"

If the user says "all" or doesn't respond with preferences, generate all.

Step 3: Fetch CDS Test Double Framework Reference

Use mcp-sap-docs to get the latest CDS Test Double Framework patterns. This ensures generated code follows SAP best practices.

search("CDS test double framework cl_cds_test_environment")

Also fetch:

search("ABAP Unit cl_abap_unit_assert")

Use the returned documentation to inform the generated code patterns. Key things to verify:

  • Correct cl_cds_test_environment=>create() signature
  • Correct get_double() / insert() pattern
  • Correct assertion method names

Step 4: Generate the Test Class

Generate a complete ABAP test class following this structure:

Template

"! @testing <CDS_ENTITY_NAME>
CLASS <test_class_name> DEFINITION
  PUBLIC FINAL
  FOR TESTING
  DURATION SHORT
  RISK LEVEL HARMLESS.

  PUBLIC SECTION.
  PROTECTED SECTION.
  PRIVATE SECTION.
    CLASS-DATA environment TYPE REF TO if_cds_test_environment.

    CLASS-METHODS class_setup    RAISING cx_static_check.
    CLASS-METHODS class_teardown.
    METHODS setup.

    "! <description of test case 1>
    METHODS <test_method_1> FOR TESTING RAISING cx_static_check.
    "! <description of test case 2>
    METHODS <test_method_2> FOR TESTING RAISING cx_static_check.
    " ... one method per selected test case
ENDCLASS.

CLASS <test_class_name> IMPLEMENTATION.

  METHOD class_setup.
    environment = cl_cds_test_environment=>create( i_for_entity = '<CDS_ENTITY_NAME>' ).
  ENDMETHOD.

  METHOD class_teardown.
    environment->destroy( ).
  ENDMETHOD.

  METHOD setup.
    environment->clear_doubles( ).
  ENDMETHOD.

  METHOD <test_method_1>.
    " Arrange — prepare test data for underlying tables
    DATA lt_<table> TYPE STANDARD TABLE OF <underlying_table> WITH EMPTY KEY.
    lt_<table> = VALUE #(
      ( <field1> = '<value1>' <field2> = '<value2>' ... )
    ).
    environment->get_double( '<UNDERLYING_TABLE>' )->insert( lt_<table> ).

    " Act — SELECT from the CDS entity under test
    SELECT * FROM <cds_entity> INTO TABLE @DATA(lt_result).

    " Assert — verify expected behavior
    cl_abap_unit_assert=>assert_equals(
      act = lines( lt_result )
      exp = <expected_count>
      msg = |Expected { <expected_count> } rows| ).

    cl_abap_unit_assert=>assert_equals(
      act = lt_result[ 1 ]-<field>
      exp = '<expected_value>'
      msg = '<assertion message>' ).
  ENDMETHOD.

  " ... more test methods

ENDCLASS.

Test Data Generation Rules

Follow these principles when generating test data:

  1. Minimal rows: Use the fewest rows needed to exercise the semantic. Typically 1-3 rows per test.
  2. Obvious values: Choose values where the expected result is trivially verifiable:
    • For gross - discount = net: use 100.00 - 10.00 = 90.00, not 37.83 - 4.27
    • For CASE branches: use exactly the values from the CASE expression
    • For WHERE filters: one row that passes, one that doesn't
  3. Type-correct: Match ABAP types exactly:
    • Use '001' for NUMC fields (string with leading zeros)
    • Use '100.00' for DEC/CURR fields
    • Use '20260101' for DATS fields
    • Use 'EUR' for CUKY fields
  4. Key fields populated: Always fill key fields even if not directly tested
  5. Deterministic: Never use random or date-dependent values
  6. Isolated: Each test method should be self-contained (clear_doubles in setup ensures this)

Naming Conventions

  • Test class: ZCL_TEST_<ENTITY> or ZCL_<ENTITY>_TEST
  • Test methods: test_<semantic>_<detail> (e.g., test_status_case_open, test_net_amount_calc)
  • Use snake_case for method names (ABAP convention for test methods)
  • Keep method names under 30 characters

Step 5: Preview and Confirm

Show the user the complete generated test class source code and ask:

"Here's the generated test class. Should I create it on the SAP system? (yes / edit first / cancel)"

If the user wants edits, incorporate them before proceeding.

Step 6: Create, Activate, and Test

6-pre. Lint-check generated code (optional)

Before writing, validate the generated code against lint rules:

SAPLint(action="lint", source="<generated_source>", name="<test_class_name>")

Fix any lint findings before proceeding. Pre-write lint validation also runs automatically when enabled (default: on).

6a. Create the test class

SAPWrite(action="create", type="CLAS", name="<test_class_name>", source="<generated_source>", package="<package>", transport="<transport>")

6b. Update the source (if create only scaffolds)

SAPWrite(action="update", type="CLAS", name="<test_class_name>", source="<generated_source>", transport="<transport>")

6c. Activate the test class

SAPActivate(type="CLAS", name="<test_class_name>")

Activation returns structured responses with detailed error/warning messages including line numbers. Use these to pinpoint exact issues.

6d. Run the unit tests

SAPDiagnose(action="unittest", type="CLAS", name="<test_class_name>")

6e. Report results

Show the user:

  • Number of tests passed / failed / skipped
  • For any failures: the assertion message and which test method failed
  • Suggested fixes for any failures

If tests fail:

  1. Analyze the failure message
  2. Determine if it's a test data issue, assertion issue, or CDS logic issue
  3. Fix the test method using SAPWrite(action="edit_method", ...)
  4. Re-activate and re-run

Error Handling

Common Issues and Fixes

ErrorCauseFix
CX_CDS_TEST_ENVIRONMENT during class_setupEntity name wrong or not activeVerify entity name, check activation status
Type mismatch in VALUE constructorWrong field type in test dataCheck DD03L or table structure for correct types
GET_DOUBLE fails for a data sourceData source name doesn't matchCheck CDS DDL for exact data source names (case-sensitive!)
Assertion fails with unexpected valuesTest data or expected result wrongRe-check CDS logic, adjust test data or assertion
Activation error: "test relation not found"@testing annotation points to wrong entityFix entity name in "! @testing comment
Class exists alreadyTest class already createdUse SAPWrite(action="update", ...) instead

Notes

BTP vs On-Premise Differences

  • BTP: Only Z*/Y* classes can be created. Standard SAP tables cannot be queried via DD03L. Use released CDS entities for type reference.
  • On-Premise: Full access to DD03L, DD02L for field catalogs. Can query TADIR for object existence checks.

What This Skill Does NOT Do

  • Performance testing: CDS Test Doubles are for logic testing, not performance
  • Authorization testing: DCL/CDS access control testing requires separate patterns
  • Integration testing: This generates isolated unit tests, not end-to-end flows
  • RAP behavior testing: For validations/actions/determinations, use the RAP BO Test Double Framework instead

When to Use This Skill

  • When a CDS entity has non-trivial logic (calculations, CASE, filters, joins)
  • When the user wants basic test coverage as a starting point
  • When refactoring CDS logic and wanting regression tests
  • NOT for trivial projections that just rename fields — if analysis in Step 2 finds no testable semantics (just field renames with no calculations, CASE, WHERE, JOINs, or aggregations), warn the user: "This CDS view is a simple projection with no testable logic. Unit tests would only verify that fields are correctly aliased, which provides minimal value. Consider testing the underlying view instead."

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/arc-mcp/arc-1/generate-cds-unit-test">View generate-cds-unit-test on skillZs</a>