From ARC-1 — SAP ABAP for Claude
Generates ABAP Unit test classes for CDS entities using the CDS Test Double Framework. Automatically reads entity structure, dependencies, and produces typed test code with smart defaults.
How this skill is triggered — by the user, by Claude, or both
Slash command
/arc-1:generate-cds-unit-testThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate an ABAP Unit test class for a CDS entity using the CDS Test Double Framework.
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).
| Setting | Default | Rationale |
|---|---|---|
| Test class name | ZCL_TEST_<entity_name> | Standard convention |
| Package | $TMP | Fast prototyping |
| Test scope | All testable semantics | User can narrow after seeing the list |
| Risk level | HARMLESS | CDS test doubles don't modify real data |
| Duration | SHORT | Unit tests should be fast |
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:
ZCL_TEST_<entity_name>)$TMP)$TMP packages)Read the CDS entity, its field structure, and all dependencies in just 3 tool calls.
SAPRead(type="DDLS", name="<entity_name>")
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.
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:
For deeper dependency graphs (e.g., a consumption view → interface view → table), use depth=2:
SAPContext(type="DDLS", name="<entity_name>", depth=2)
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.
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:
| Category | What to Look For in DDL | Example Test Case |
|---|---|---|
| Calculations | Arithmetic expressions (field1 * field2, field1 - field2) | Insert known values, verify calculated result |
| CASE expressions | case when ... then ... else ... end | One test per branch |
| Type casts | cast(field as abap.dec(15,2)), cast(field as abap.char(10)) | Insert value, verify cast output |
| WHERE filters | where status = 'A' or where amount > 0 | Insert matching + non-matching rows, verify only matching appear |
| HAVING clauses | having sum(amount) > 1000 | Insert data that triggers and doesn't trigger the filter |
| JOINs | inner join, left outer join, association | Insert matching keys in both tables; test with non-matching keys for outer joins |
| Aggregations | sum(), count(), avg(), min(), max() with group by | Insert multiple rows, verify aggregated result |
| Null handling | coalesce(field, 'default'), null-safe expressions | Insert row with null field, verify default |
| Parameters | with parameters p_param : type | Call view with parameter, verify filtering |
| Currency/Unit conversion | currency_conversion(), unit_conversion() | Insert conversion data, verify result |
| String operations | concat(), substring(), length() | Insert string values, verify output |
| Associations | association [0..*] to ... | Insert data in both sides, verify navigation |
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.
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:
cl_cds_test_environment=>create() signatureget_double() / insert() patternGenerate a complete ABAP test class following this structure:
"! @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.
Follow these principles when generating test data:
gross - discount = net: use 100.00 - 10.00 = 90.00, not 37.83 - 4.27'001' for NUMC fields (string with leading zeros)'100.00' for DEC/CURR fields'20260101' for DATS fields'EUR' for CUKY fieldsZCL_TEST_<ENTITY> or ZCL_<ENTITY>_TESTtest_<semantic>_<detail> (e.g., test_status_case_open, test_net_amount_calc)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.
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).
SAPWrite(action="create", type="CLAS", name="<test_class_name>", source="<generated_source>", package="<package>", transport="<transport>")
SAPWrite(action="update", type="CLAS", name="<test_class_name>", source="<generated_source>", transport="<transport>")
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.
SAPDiagnose(action="unittest", type="CLAS", name="<test_class_name>")
Show the user:
If tests fail:
SAPWrite(action="edit_method", ...)| Error | Cause | Fix |
|---|---|---|
CX_CDS_TEST_ENVIRONMENT during class_setup | Entity name wrong or not active | Verify entity name, check activation status |
| Type mismatch in VALUE constructor | Wrong field type in test data | Check DD03L or table structure for correct types |
GET_DOUBLE fails for a data source | Data source name doesn't match | Check CDS DDL for exact data source names (case-sensitive!) |
| Assertion fails with unexpected values | Test data or expected result wrong | Re-check CDS logic, adjust test data or assertion |
| Activation error: "test relation not found" | @testing annotation points to wrong entity | Fix entity name in "! @testing comment |
| Class exists already | Test class already created | Use SAPWrite(action="update", ...) instead |
npx claudepluginhub arc-mcp/arc-1 --plugin arc-1Generate ABAP Unit tests for classes with dependency analysis, interface-based test doubles, and method-level surgical insertion.
Guides ABAP Unit test setup: test classes, assertions, test doubles, mocking, dependency injection, CDS/SQL test environments, and RAP BO testing.
Provides SAP ABAP CDS reference for data modeling, views, entities, annotations, associations, parameters, functions, CASE expressions, DCL access control, CURR/QUAN types, troubleshooting, ABAP querying, and SALV IDA. For ABAP 7.4+ to Cloud.