abapgit-agent 1.15.1 → 1.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/abap/CLAUDE.md CHANGED
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  layout: default
3
- title: Claude Code Instructions (Template)
3
+ title: AI Agent Instructions
4
4
  nav_order: 1
5
5
  parent: ABAP Development
6
6
  ---
7
7
 
8
- # Claude Code Instructions - Template
8
+ # AI Agent Instructions
9
9
 
10
10
  This file provides guidelines for **generating ABAP code** in abapGit repositories.
11
11
 
@@ -157,10 +157,11 @@ Anything else (SAP namespace object, or SAP-delivered package)?
157
157
  ```
158
158
 
159
159
  > **Tip for project setup**: Add package rules to `objects.local.md` so Claude never
160
- > needs to ask. See `guidelines/objects.md` for examples.
160
+ > needs to ask. Run: `abapgit-agent ref --topic objects`
161
161
 
162
162
  → For exact XML templates: `abapgit-agent ref --topic abapgit` (CLAS/INTF/PROG/DDLS/DCLS/FUGR) or `abapgit-agent ref --topic abapgit-xml-only` (TABL/STRU/DTEL/TTYP/DOMA/MSAG)
163
163
  → For local helper/test-double class files: `abapgit-agent ref --topic object-creation`
164
+ → For documentation comment format (shorttext, @parameter, CDS): `abapgit-agent ref --topic comments`
164
165
 
165
166
  ---
166
167
 
@@ -213,9 +214,15 @@ abapgit-agent pull --files src/<intf_name>.intf.abap,src/<class_name>.clas.abap
213
214
 
214
215
  ### 5. Local Helper / Test-Double Classes
215
216
 
216
- See `guidelines/object-creation.md` run: `abapgit-agent ref --topic object-creation`
217
+ When a class needs local helper classes or test doubles, create separate include files alongside the main class file:
217
218
 
218
- **XML metadata when adding test classes:**
219
+ ```
220
+ <name>.clas.locals_def.abap ← local type/class definitions
221
+ <name>.clas.locals_imp.abap ← local class implementations
222
+ <name>.clas.testclasses.abap ← unit test classes (FOR TESTING)
223
+ ```
224
+
225
+ **XML metadata when adding these files:**
219
226
 
220
227
  ```
221
228
  Adding .clas.testclasses.abap to an existing class?
@@ -228,6 +235,7 @@ Adding .clas.locals_def.abap (local type definitions)?
228
235
  <CLSCCINCL>X</CLSCCINCL>
229
236
  ```
230
237
 
238
+ → For exact XML flag placement and test double class patterns: `abapgit-agent ref --topic object-creation`
231
239
  → For exact XML flag placement: `abapgit-agent ref --topic abapgit` (search "WITH_UNIT_TESTS")
232
240
 
233
241
  ---
@@ -330,8 +338,11 @@ AI thought process:
330
338
 
331
339
  ### 7. CDS Unit Tests
332
340
 
333
- Use `CL_CDS_TEST_ENVIRONMENT` for unit tests that read CDS views.
334
- → See `guidelines/cds-testing.md` — run: `abapgit-agent ref --topic cds-testing`
341
+ If a class under test reads a CDS view, use `CL_CDS_TEST_ENVIRONMENT` to provide test data — do **not** mock the database layer manually. Without this, test data setup is unreliable and tests may pass locally but fail on other systems.
342
+
343
+ **Trigger**: your class calls `SELECT FROM <cds_view>` directly or via a helper.
344
+
345
+ → For full setup pattern and test double configuration: `abapgit-agent ref --topic cds-testing`
335
346
 
336
347
  ---
337
348
 
@@ -369,10 +380,7 @@ DATA(lo_cut) = NEW zcl_my_class( io_agent = lo_agent ).
369
380
  DATA(ls_actual) = lo_cut->execute( ).
370
381
  ```
371
382
 
372
- Full API reference (EXPORT params, exceptions, inherited methods, common mistakes):
373
- `abapgit-agent ref --topic unit-testable-code`
374
-
375
- → For class design rules (constructor injection, interfaces for dependencies):
383
+ For full API reference (EXPORT params, exceptions, inherited methods, common mistakes) and class design rules (constructor injection, interfaces for dependencies):
376
384
  `abapgit-agent ref --topic unit-testable-code`
377
385
 
378
386
  #### Running tests — use `unit` command
@@ -435,7 +443,7 @@ Never assume — wait for the user's answer before proceeding.
435
443
  | HTTP 500 / runtime crash (ST22) | `dump` | Error already occurred |
436
444
  | Wrong output, no crash | `debug` | Need to trace logic |
437
445
 
438
- See `guidelines/debug-dump.md` — run: `abapgit-agent ref --topic debug-dump`
446
+ → `abapgit-agent ref --topic debug-dump`
439
447
 
440
448
  **Critical rules for `debug` sessions:**
441
449
 
@@ -496,7 +504,7 @@ abapgit-agent debug vars --json
496
504
  abapgit-agent debug step --type continue --json # 4. release
497
505
  ```
498
506
 
499
- See `guidelines/debug-session.md` — run: `abapgit-agent ref --topic debug-session`
507
+ → `abapgit-agent ref --topic debug-session`
500
508
 
501
509
  ---
502
510
 
@@ -546,7 +554,7 @@ Projects can add their own abaplint notes to `guidelines/abaplint-local.md` in t
546
554
  project repository. After running `abapgit-agent ref export`, the `ref` command
547
555
  surfaces both bundled and project-specific guidance together.
548
556
 
549
- See `guidelines/abaplint.md` — run: `abapgit-agent ref --topic abaplint`
557
+ → `abapgit-agent ref --topic abaplint`
550
558
 
551
559
  ---
552
560
 
@@ -600,7 +608,7 @@ git push origin feature/my-change --force-with-lease
600
608
  abapgit-agent pull --files src/<name>.clas.abap --sync-xml
601
609
  ```
602
610
 
603
- See `guidelines/branch-workflow.md` — run: `abapgit-agent ref --topic branch-workflow`
611
+ → `abapgit-agent ref --topic branch-workflow`
604
612
 
605
613
  ### Trunk Workflow (`"mode": "trunk"`)
606
614
 
@@ -716,47 +724,38 @@ Modified ABAP files?
716
724
  ```
717
725
 
718
726
  → For creating new objects (what files to write): `abapgit-agent ref --topic object-creation`
719
- See `guidelines/workflow-detailed.md` run: `abapgit-agent ref --topic workflow-detailed`
727
+ For full workflow decision tree and error indicators: `abapgit-agent ref --topic workflow-detailed`
720
728
 
721
729
  ---
722
730
 
723
731
  ## Guidelines Index
724
732
 
725
- > **Note:** If the `guidelines/` folder doesn't exist in your repo, the `ref` command
726
- > automatically uses bundled guidelines from the package. Access them with:
727
- > ```bash
728
- > abapgit-agent ref --topic <topic> # e.g. ref --topic sql
729
- > abapgit-agent ref "<pattern>" # e.g. ref "SELECT"
730
- > ```
731
-
732
- Detailed guidelines are available in the `guidelines/` folder:
733
-
734
- | File | Topic |
735
- |------|-------|
736
- | `guidelines/index.md` | Overview and usage |
737
- | `guidelines/sql.md` | ABAP SQL Best Practices |
738
- | `guidelines/exceptions.md` | Exception Handling |
739
- | `guidelines/testing.md` | Unit Testing (including CDS) |
740
- | `guidelines/cds.md` | CDS Views |
741
- | `guidelines/classes.md` | ABAP Classes and Objects |
742
- | `guidelines/objects.md` | Object Naming Conventions (defaults) |
743
- | `guidelines/objects.local.md` | **Project** Naming Conventions — overrides `objects.md` (created by `init`, never overwritten) |
744
- | `guidelines/json.md` | JSON Handling |
745
- | `guidelines/abapgit.md` | abapGit XML Metadata Templates — CLAS, INTF, PROG, DDLS, DCLS, FUGR |
746
- | `guidelines/abapgit-xml-only.md` | abapGit XML Metadata Templates — XML-only objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG) |
747
- | `guidelines/unit-testable-code.md` | Unit Testable Code Guidelines (Dependency Injection) |
748
- | `guidelines/common-errors.md` | Common ABAP Errors - Quick Fixes |
749
- | `guidelines/debug-session.md` | Debug Session Guide |
750
- | `guidelines/debug-dump.md` | Dump Analysis Guide |
751
- | `guidelines/run-probe-classes.md` | run Command — AI Guidelines (probe classes, scratchWorkspace) |
752
- | `guidelines/probe-poc.md` | Probe and PoC — Full Decision Flow |
753
- | `guidelines/branch-workflow.md` | Branch Workflow |
754
- | `guidelines/workflow-detailed.md` | Development Workflow (Detailed) |
755
- | `guidelines/object-creation.md` | Object Creation (XML metadata, local classes) |
756
- | `guidelines/cds-testing.md` | CDS Testing (Test Double Framework) |
757
- | `guidelines/abaplint.md` | abaplint Rule Guidelines (prefer_inline trap, safe patterns) |
758
-
759
- These guidelines are automatically searched by the `ref` command.
733
+ | Command | Topic |
734
+ |---------|-------|
735
+ | `ref --topic sql` | ABAP SQL Best Practices |
736
+ | `ref --topic exceptions` | Exception Handling |
737
+ | `ref --topic classes` | ABAP Classes and Objects |
738
+ | `ref --topic objects` | Object Naming Conventions (defaults) |
739
+ | `ref --topic comments` | Documentation Comments (ABAP DOC, shorttext, @parameter, CDS `//`, program `*&---`) |
740
+ | `ref --topic testing` | Unit Testing |
741
+ | `ref --topic unit-testable-code` | Unit Testable Code (Dependency Injection) |
742
+ | `ref --topic cds` | CDS Views |
743
+ | `ref --topic cds-testing` | CDS Testing (Test Double Framework) |
744
+ | `ref --topic json` | JSON Handling |
745
+ | `ref --topic common-errors` | Common ABAP Errors - Quick Fixes |
746
+ | `ref --topic abapgit` | abapGit XML Metadata — **use for CDS/DDLS XML**, also CLAS, INTF, PROG, DCLS, FUGR |
747
+ | `ref --topic abapgit-xml-only` | abapGit XML Metadata — XML-only objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG) |
748
+ | `ref --topic abapgit-fugr` | abapGit XML Metadata — Function Group (FUGR) details |
749
+ | `ref --topic abaplint` | abaplint Rule Guidelines (prefer_inline trap, safe patterns) |
750
+ | `ref --topic debug-session` | Debug Session Guide |
751
+ | `ref --topic debug-dump` | Dump Analysis Guide |
752
+ | `ref --topic branch-workflow` | Branch Workflow |
753
+ | `ref --topic workflow-detailed` | Development Workflow (Detailed) |
754
+ | `ref --topic object-creation` | Object Creation (XML metadata, local classes) |
755
+ | `ref --topic run-probe-classes` | run Command AI Guidelines (probe classes, scratchWorkspace) |
756
+ | `ref --topic probe-poc` | Probe and PoC Full Decision Flow |
757
+
758
+ > `objects.local.md` — **Project** Naming Conventions (created by `init`, never overwritten). Read directly from `guidelines/objects.local.md` no ref topic.
760
759
 
761
760
  ---
762
761
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: abapGit XML Metadata — Function Group (FUGR)
4
- nav_order: 11
4
+ nav_order: 15
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: abapGit XML Metadata — XML-Only Objects
4
- nav_order: 10
4
+ nav_order: 14
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: abapGit XML Metadata
4
- nav_order: 9
4
+ nav_order: 13
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: abaplint Local Rules
4
- nav_order: 21
4
+ nav_order: 17
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: abaplint Rule Guidelines
4
- nav_order: 20
4
+ nav_order: 16
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Branch Workflow
4
- nav_order: 17
4
+ nav_order: 20
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,28 +1,250 @@
1
1
  ---
2
2
  layout: default
3
3
  title: CDS Testing
4
- nav_order: 22
4
+ nav_order: 10
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
8
8
 
9
9
  # CDS Testing
10
10
 
11
- ### Use CDS Test Double Framework for CDS View Tests
11
+ **Searchable keywords**: CDS test double, CL_CDS_TEST_ENVIRONMENT, IF_CDS_TEST_ENVIRONMENT, insert_test_data, clear_doubles, create_for_multiple_cds, class_setup, class_teardown, aggregation test, CDS unit test
12
12
 
13
- **When creating unit tests for CDS views, use the CDS Test Double Framework (`CL_CDS_TEST_ENVIRONMENT`).**
13
+ ## TOPICS IN THIS FILE
14
+ 1. When to Use CDS Test Doubles - line 22
15
+ 2. Basic Setup Pattern - line 30
16
+ 3. Testing CDS Views with Aggregations - line 100
17
+ 4. Testing CDS Views that Select from Another CDS View - line 130
18
+ 5. Key Classes and Methods - line 170
19
+ 6. Important Usage Notes - line 190
20
+
21
+ ---
22
+
23
+ ## 1. When to Use CDS Test Doubles
14
24
 
15
25
  ```
16
26
  ❌ WRONG: Use regular AUnit test class without test doubles
17
27
  ✅ CORRECT: Use CL_CDS_TEST_ENVIRONMENT to create test doubles for CDS views
18
28
  ```
19
29
 
20
- **Why**: CDS views read from database tables. Using test doubles allows:
21
- - Injecting test data without affecting production data
22
- - Testing specific scenarios that may not exist in production
23
- - Fast, isolated tests that don't depend on database state
30
+ Use the CDS Test Double Framework (`CL_CDS_TEST_ENVIRONMENT`) whenever:
31
+ - A class under test calls `SELECT FROM <cds_view>` directly or via a helper
32
+ - You need controlled test data (not production data)
33
+ - You need to test CDS view logic with specific scenarios
34
+
35
+ **Why**: CDS views read from database tables. Using test doubles allows injecting test data
36
+ without affecting production data, and keeps tests fast and isolated.
37
+
38
+ ---
39
+
40
+ ## 2. Basic Setup Pattern
41
+
42
+ The test class lives in `<classname>.clas.testclasses.abap`. The CDS view itself has no
43
+ `.testclasses` file — test it through a regular ABAP class that reads it.
44
+
45
+ ```abap
46
+ "-------------------------
47
+ " CLASS DEFINITION
48
+ "-------------------------
49
+ CLASS ltcl_cds_test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
50
+
51
+ PRIVATE SECTION.
52
+ " IMPORTANT: Use interface type, not class type!
53
+ DATA mo_cds_env TYPE REF TO if_cds_test_environment.
54
+
55
+ " IMPORTANT: class_setup/teardown must be CLASS-METHODS (static)!
56
+ CLASS-DATA mo_cds_env_static TYPE REF TO if_cds_test_environment.
57
+
58
+ METHODS setup.
59
+ METHODS test_cds_with_doubles FOR TESTING.
60
+
61
+ CLASS-METHODS: class_setup,
62
+ class_teardown.
63
+
64
+ ENDCLASS.
65
+
66
+ "-------------------------
67
+ " CLASS IMPLEMENTATION
68
+ "-------------------------
69
+ CLASS ltcl_cds_test IMPLEMENTATION.
70
+
71
+ METHOD class_setup.
72
+ " Create CDS test environment — framework auto-creates doubles for dependencies
73
+ mo_cds_env_static = cl_cds_test_environment=>create(
74
+ i_for_entity = 'ZC_MY_CDS_VIEW' ).
75
+ ENDMETHOD.
76
+
77
+ METHOD class_teardown.
78
+ " Clean up test environment
79
+ mo_cds_env_static->destroy( ).
80
+ ENDMETHOD.
81
+
82
+ METHOD setup.
83
+ " IMPORTANT: Assign static env to instance and clear doubles before each test
84
+ mo_cds_env = mo_cds_env_static.
85
+ mo_cds_env->clear_doubles( ).
86
+ ENDMETHOD.
87
+
88
+ METHOD test_cds_with_doubles.
89
+ " IMPORTANT: Must declare table type first — cannot inline in VALUE #()!
90
+ DATA lt_test_data TYPE TABLE OF zc_my_cds_view WITH EMPTY KEY.
91
+ lt_test_data = VALUE #(
92
+ ( field1 = 'A' field2 = 100 )
93
+ ( field1 = 'B' field2 = 200 ) ).
94
+
95
+ " Insert test data using named parameter
96
+ mo_cds_env->insert_test_data( i_data = lt_test_data ).
97
+
98
+ " Select from CDS view
99
+ SELECT * FROM zc_my_cds_view INTO TABLE @DATA(lt_result).
100
+
101
+ " Verify results
102
+ cl_abap_unit_assert=>assert_not_initial(
103
+ act = lt_result
104
+ msg = 'Result should not be empty' ).
105
+
106
+ cl_abap_unit_assert=>assert_equals(
107
+ act = lines( lt_result )
108
+ exp = 2
109
+ msg = 'Expected 2 rows' ).
110
+ ENDMETHOD.
111
+
112
+ ENDCLASS.
113
+ ```
114
+
115
+ ---
116
+
117
+ ## 3. Testing CDS Views with Aggregations (SUM, COUNT, GROUP BY)
118
+
119
+ For CDS views with aggregations, insert test data into the **base tables** (SFLIGHT, SCARR,
120
+ SBOOK, etc.), not directly into the CDS view. The framework routes the inserts through the
121
+ aggregation pipeline.
122
+
123
+ ```abap
124
+ METHOD test_aggregation.
125
+ " Insert data into base tables via CDS test doubles
126
+ DATA lt_scarr TYPE TABLE OF scarr WITH EMPTY KEY.
127
+ lt_scarr = VALUE #( ( carrid = 'LH' carrname = 'Lufthansa' currcode = 'EUR' ) ).
128
+ mo_cds_env->insert_test_data( i_data = lt_scarr ).
129
+
130
+ DATA lt_sflight TYPE TABLE OF sflight WITH EMPTY KEY.
131
+ lt_sflight = VALUE #( ( carrid = 'LH' connid = '0400' fldate = '20240115'
132
+ seatsmax = 200 seatsocc = 100 ) ).
133
+ mo_cds_env->insert_test_data( i_data = lt_sflight ).
134
+
135
+ DATA lt_sbook TYPE TABLE OF sbook WITH EMPTY KEY.
136
+ lt_sbook = VALUE #(
137
+ ( carrid = 'LH' connid = '0400' fldate = '20240115' bookid = '0001' forcuram = 1000 )
138
+ ( carrid = 'LH' connid = '0400' fldate = '20240115' bookid = '0002' forcuram = 2000 )
139
+ ( carrid = 'LH' connid = '0400' fldate = '20240115' bookid = '0003' forcuram = 3000 ) ).
140
+ mo_cds_env->insert_test_data( i_data = lt_sbook ).
141
+
142
+ " Select from CDS view — aggregations will use test double data
143
+ SELECT * FROM zc_flight_revenue INTO TABLE @DATA(lt_result).
144
+
145
+ cl_abap_unit_assert=>assert_equals(
146
+ exp = 3
147
+ act = lt_result[ 1 ]-numberofbookings
148
+ msg = 'Should have 3 bookings' ).
149
+
150
+ cl_abap_unit_assert=>assert_equals(
151
+ exp = '6000.00'
152
+ act = lt_result[ 1 ]-totalrevenue
153
+ msg = 'Total revenue should be 6000.00' ).
154
+ ENDMETHOD.
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 4. Testing CDS Views that Select from Another CDS View
160
+
161
+ > **Note:** This pattern applies when your design **already has** a CDS view that selects from
162
+ > another CDS view. It does NOT mean you should split a single view into two — use a single
163
+ > CDS view with GROUP BY / JOIN when the business logic fits.
164
+
165
+ When your CDS view selects from **another CDS view** (not a base table), `create` raises
166
+ `CX_CDS_FAILURE`. Use `create_for_multiple_cds` instead and list all CDS entities in the
167
+ dependency chain.
168
+
169
+ ```abap
170
+ METHOD class_setup.
171
+ " ZC_TopView selects from ZC_IntermediateView (another CDS view entity)
172
+ " → must use create_for_multiple_cds and list all CDS entities
173
+ mo_cds_env_static = cl_cds_test_environment=>create_for_multiple_cds(
174
+ i_for_entities = VALUE #(
175
+ ( 'ZC_TOPVIEW' ) " the view under test
176
+ ( 'ZC_INTERMEDIATEVIEW' ) " the CDS view it selects from
177
+ ) ).
178
+ ENDMETHOD.
179
+ ```
180
+
181
+ Insert test data into the **intermediate CDS view** (not the base tables), because that is
182
+ what the top-level view reads:
183
+
184
+ ```abap
185
+ METHOD test_read.
186
+ DATA lt_source TYPE TABLE OF zc_intermediateview WITH EMPTY KEY.
187
+ lt_source = VALUE #(
188
+ ( field1 = 'A' field2 = 100 )
189
+ ( field1 = 'B' field2 = 200 ) ).
190
+ mo_cds_env->insert_test_data( i_data = lt_source ).
191
+
192
+ SELECT * FROM zc_topview INTO TABLE @DATA(lt_result).
193
+
194
+ cl_abap_unit_assert=>assert_equals(
195
+ exp = 2 act = lines( lt_result ) msg = 'Expected 2 rows' ).
196
+ ENDMETHOD.
197
+ ```
198
+
199
+ **Rules:**
200
+ - List the view under test **and all CDS views it depends on** in `i_for_entities`
201
+ - Insert data into the **direct source** of the top-level view (the intermediate CDS view)
202
+ - Order in `i_for_entities` does not matter
203
+ - If `create` raises `CX_CDS_FAILURE`, switch to `create_for_multiple_cds`
204
+
205
+ ---
206
+
207
+ ## 5. Key Classes and Methods
208
+
209
+ | Item | Type / Usage |
210
+ |------|-------------|
211
+ | `CL_CDS_TEST_ENVIRONMENT` | Class — entry point, use its `CREATE` / `CREATE_FOR_MULTIPLE_CDS` methods |
212
+ | `IF_CDS_TEST_ENVIRONMENT` | Interface — declare your variable with this type |
213
+ | `CLASS-METHODS class_setup` | Must be static (`CLASS-METHODS`, not `METHODS`) |
214
+ | `CL_ABAP_UNIT_ASSERT` | Standard AUnit assertion class |
215
+
216
+ | Method | Purpose |
217
+ |--------|---------|
218
+ | `CL_CDS_TEST_ENVIRONMENT=>create( i_for_entity = ... )` | Environment for a CDS view over base tables |
219
+ | `CL_CDS_TEST_ENVIRONMENT=>create_for_multiple_cds( i_for_entities = ... )` | Environment when CDS view selects from another CDS view |
220
+ | `insert_test_data( i_data = ... )` | Inject test rows into a test double |
221
+ | `clear_doubles( )` | Remove all test rows — call in `setup` before each test |
222
+ | `destroy( )` | Tear down the environment — call in `class_teardown` |
223
+
224
+ ---
225
+
226
+ ## 6. Important Usage Notes
227
+
228
+ 1. **Declare with interface type**: `DATA mo_cds_env TYPE REF TO if_cds_test_environment` —
229
+ `create` returns an interface reference, not a class reference.
230
+
231
+ 2. **Static lifecycle methods**: `class_setup` and `class_teardown` must be `CLASS-METHODS`
232
+ (not `METHODS`). The environment is expensive to create — build it once per class run.
233
+
234
+ 3. **Table type before VALUE #()**: Must declare `DATA lt_tab TYPE TABLE OF <type> WITH EMPTY KEY`
235
+ before using `VALUE #()` — inline declaration inside `VALUE #()` is not supported here.
236
+
237
+ 4. **Auto-created dependencies**: When the CDS view selects only from base tables, the framework
238
+ auto-creates test doubles — do not specify an `i_dependency_list`. When the CDS view selects
239
+ from another CDS view, use `create_for_multiple_cds` (see section 4).
240
+
241
+ 5. **Aggregations**: For CDS views with SUM/COUNT/GROUP BY, insert test data into the base tables
242
+ (SFLIGHT, SCARR, etc.), not the CDS view itself.
243
+
244
+ 6. **Clear doubles**: Always call `clear_doubles` in `setup` to ensure test isolation.
245
+
246
+ 7. **Enable associations**: Set `test_associations = 'X'` in `create` only when explicitly
247
+ testing CDS association navigation.
24
248
 
25
- See `abapgit-agent ref --topic testing` for full code examples including:
26
- - Basic CDS test double setup
27
- - Testing CDS views with aggregations (insert into base tables)
28
- - Testing CDS views that select from another CDS view (`create_for_multiple_cds`)
249
+ 8. **Exception handling**: Declare test methods with `RAISING cx_static_check` if the code
250
+ under test raises checked exceptions.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: CDS Views
4
- nav_order: 5
4
+ nav_order: 9
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Classes & Objects
4
- nav_order: 6
4
+ nav_order: 4
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -0,0 +1,249 @@
1
+ ---
2
+ layout: default
3
+ title: Documentation Comments
4
+ nav_order: 6
5
+ parent: ABAP Coding Guidelines
6
+ grand_parent: ABAP Development
7
+ ---
8
+
9
+ # ABAP Documentation Comments
10
+
11
+ **Searchable keywords**: ABAP DOC, "! comment, shorttext synchronized, @parameter, @raising, inline comment, CDS comment, // comment, program header, *&---, documentation comment
12
+
13
+ ## TOPICS IN THIS FILE
14
+ 1. Two Types of Comments - line 18
15
+ 2. OO Class Documentation (CLAS) - line 37
16
+ 3. Interface Documentation (INTF) - line 101
17
+ 4. Program Header (PROG) - line 120
18
+ 5. CDS View Comments (DDLS) - line 137
19
+ 6. When NOT to Comment - line 161
20
+ 7. Quick Decision Table - line 182
21
+
22
+ ---
23
+
24
+ ## 1. Two Types of Comments
25
+
26
+ ABAP has two distinct comment styles with different purposes:
27
+
28
+ **`"!` (ABAP DOC)** — parsed by the ABAP system; surfaced in ADT and SE24 as F2 help.
29
+ Use for API-level documentation: class declarations, interface declarations, and method signatures.
30
+ This is the equivalent of Javadoc. The system reads it — it is metadata, not decoration.
31
+
32
+ **`"!` is only valid immediately before these statements:**
33
+ `CLASS ... DEFINITION`, `INTERFACE`, `METHODS`, `CLASS-METHODS`, `EVENTS`, `DATA`, `CLASS-DATA`, `CONSTANTS`.
34
+
35
+ **`"!` before `TYPES` is a syntax error** — the Code Inspector reports "ABAP Doc comment is in the wrong position."
36
+ Use a regular `"` comment to describe type structures instead.
37
+
38
+ **`"` (regular inline comment)** — source-only; not parsed by the ABAP system.
39
+ Use inside method bodies to explain non-obvious logic, and to label `TYPES` blocks.
40
+ Never use `"!` inside method implementations — it has no effect there.
41
+
42
+ **Default behaviour (when to add automatically vs. only on request):**
43
+
44
+ | Comment Type | Default Behaviour |
45
+ |---|---|
46
+ | `"! <p class="shorttext synchronized">` on CLASS/INTF | **Always auto-add** — synced to XML `<DESCRIPT>`; it IS object metadata |
47
+ | `@EndUserText.label` on CDS view | **Always auto-add** — same: it IS the CDS description |
48
+ | `"!` + `@parameter` on INTF public methods | **Always auto-add** — interfaces are the contract; self-documenting |
49
+ | `"!` + `@parameter` on CLAS public methods | **Auto-add** when creating a new class from scratch |
50
+ | `"!` on existing CLAS private/protected methods | **Only if requested** — adding to existing code is refactoring |
51
+ | `"` inline comments inside method bodies | **Only when non-obvious** — never add redundant comments |
52
+ | `*&---` program header | **Always auto-add** — standard for every PROG |
53
+
54
+ ---
55
+
56
+ ## 2. OO Class Documentation (CLAS)
57
+
58
+ ### Class-level shorttext
59
+
60
+ Place the `"!` shorttext immediately before `CLASS ... DEFINITION`:
61
+
62
+ ```abap
63
+ "! <p class="shorttext synchronized">Pull ABAP objects from a remote git repository</p>
64
+ CLASS zcl_abgagt_agent DEFINITION PUBLIC FINAL CREATE PUBLIC.
65
+ ```
66
+
67
+ This shorttext is **synced to the XML `<DESCRIPT>` field** by abapGit. Creating a class without
68
+ it means the XML description is blank and the object cannot be searched by description in SE24/SE80.
69
+ **Always add it** when creating any new class.
70
+
71
+ **Note on `*"*` auto-header:** When a class has local definitions or inherits from another class,
72
+ abapGit writes a 3-line `*"*"` block at the top of the `.clas.abap` file:
73
+
74
+ ```abap
75
+ *"* use this source file for the definition and implementation of
76
+ *"* local helper classes, interface definitions and type
77
+ *"* temporary on-the-fly implementation
78
+ ```
79
+
80
+ In that case, the `"!` shorttext goes on line 4 (after the block), not line 1.
81
+
82
+ ### Method documentation
83
+
84
+ Place `"!` documentation in the DEFINITION section, PUBLIC SECTION only, immediately before the
85
+ `METHODS` statement:
86
+
87
+ ```abap
88
+ "! Pull files from remote and activate them
89
+ "! @parameter it_files | List of files to activate (relative paths)
90
+ "! @parameter rv_success | True if all objects activated successfully
91
+ "! @raising zcx_abapgit_exception | If pull or activation fails
92
+ METHODS pull_files
93
+ IMPORTING it_files TYPE string_table
94
+ RETURNING VALUE(rv_success) TYPE abap_bool
95
+ RAISING zcx_abapgit_exception.
96
+ ```
97
+
98
+ **Rules:**
99
+
100
+ - **ALWAYS add** `"! <p class="shorttext synchronized">` when creating any new CLASS — no exceptions.
101
+ - **ALWAYS add** `"!` + `@parameter` for all PUBLIC methods when creating a new class from scratch.
102
+ - When **modifying existing** code, only add or update comments if explicitly asked.
103
+ - `@parameter <name> | <description>` — one line per IMPORTING/EXPORTING/RETURNING/CHANGING param.
104
+ - `@raising <exception> | <reason>` — one line per RAISING exception.
105
+ - PRIVATE and PROTECTED methods: optional; add only if the purpose is non-obvious.
106
+ - Place ONLY in the DEFINITION section — do NOT repeat `"!` in the IMPLEMENTATION section.
107
+
108
+ **Full example:**
109
+
110
+ ```abap
111
+ "! <p class="shorttext synchronized">Syntax checker for ABAP class source</p>
112
+ CLASS zcl_abgagt_syntax_chk_clas DEFINITION PUBLIC FINAL CREATE PUBLIC.
113
+ PUBLIC SECTION.
114
+ INTERFACES zif_abgagt_syntax_checker.
115
+
116
+ "! Create a new syntax checker instance
117
+ "! @parameter ii_agent | Agent used for HTTP communication
118
+ CLASS-METHODS create
119
+ IMPORTING ii_agent TYPE REF TO zif_abgagt_agent
120
+ RETURNING VALUE(ro_check) TYPE REF TO zif_abgagt_syntax_checker.
121
+
122
+ PRIVATE SECTION.
123
+ DATA mi_agent TYPE REF TO zif_abgagt_agent.
124
+ ENDCLASS.
125
+ ```
126
+
127
+ ---
128
+
129
+ ## 3. Interface Documentation (INTF)
130
+
131
+ Interfaces follow the same `"!` pattern as classes. The shorttext goes immediately before
132
+ `INTERFACE ... PUBLIC`, and every method gets `"!` + `@parameter`.
133
+
134
+ ```abap
135
+ "! <p class="shorttext synchronized">Contract for all syntax checker implementations</p>
136
+ INTERFACE zif_abgagt_syntax_checker PUBLIC.
137
+
138
+ "! Check the syntax of ABAP source code
139
+ "! @parameter iv_source | Full ABAP source text to check
140
+ "! @parameter rv_result | JSON-encoded result with errors list
141
+ "! @raising zcx_abapgit_exception | On communication failure
142
+ METHODS check_syntax
143
+ IMPORTING iv_source TYPE string
144
+ RETURNING VALUE(rv_result) TYPE string
145
+ RAISING zcx_abapgit_exception.
146
+
147
+ ENDINTERFACE.
148
+ ```
149
+
150
+ **Canonical example:** `zif_abgagt_syntax_checker.intf.abap` in this repository.
151
+
152
+ **Rules:**
153
+ - **ALWAYS add** `"! <p class="shorttext synchronized">` for every new interface.
154
+ - **ALWAYS add** `"!` + `@parameter` for every method — interfaces are the published contract.
155
+ - No exceptions for "obvious" method names — document them anyway.
156
+
157
+ ---
158
+
159
+ ## 4. Program Header (PROG)
160
+
161
+ Programs use the traditional `*&---` block, NOT ABAP DOC. Place it before the `REPORT` statement:
162
+
163
+ ```abap
164
+ *&---------------------------------------------------------------------*
165
+ *& Report Z_MY_PROGRAM
166
+ *&---------------------------------------------------------------------*
167
+ *& Brief description of what the program does
168
+ *&---------------------------------------------------------------------*
169
+ REPORT z_my_program.
170
+ ```
171
+
172
+ **Rules:**
173
+ - **ALWAYS add** this header block when creating any new program.
174
+ - Do NOT add `"! <p class="shorttext synchronized">` before `REPORT` — it is not parsed there.
175
+ - Inline comments inside `START-OF-SELECTION` and other events use the regular `"` style.
176
+
177
+ ---
178
+
179
+ ## 5. CDS View Comments (DDLS)
180
+
181
+ CDS DDL source (`.ddls.asddls`) uses a completely different comment syntax from ABAP:
182
+
183
+ - Line comment: `// text`
184
+ - Block comment: `/* text */`
185
+
186
+ **Never use ABAP-style `"` inside CDS source** — it causes a CDS syntax error.
187
+
188
+ ### `@EndUserText.label` — the CDS equivalent of shorttext
189
+
190
+ This annotation IS the object description. Always include it before the view entity definition:
191
+
192
+ ```cds
193
+ @EndUserText.label: 'Revenue summary by carrier'
194
+ define view entity ZC_FlightRevenue
195
+ as select from sflight
196
+ {
197
+ key carrid, // IATA carrier code
198
+ key connid, // Connection number
199
+ sum( price ) as TotalRevenue
200
+ }
201
+ ```
202
+
203
+ **Rules:**
204
+ - **ALWAYS add** `@EndUserText.label` when creating any new CDS view entity.
205
+ - Add `// text` line comments after non-obvious field names.
206
+ - Use `/* ... */` for multi-line block comments if needed (e.g., explaining a complex join).
207
+ - No `"!` or `"` comments anywhere in `.ddls.asddls` files.
208
+
209
+ ---
210
+
211
+ ## 6. When NOT to Comment
212
+
213
+ The guiding principle: **comments explain *why*, not *what***.
214
+
215
+ ```abap
216
+ " BAD — repeats the code, adds no value
217
+ ls_params-mode = 'abort'. " Set mode to abort
218
+
219
+ " GOOD — explains a non-obvious rule
220
+ ls_params-mode = 'abort'. " INITIAL means abort (caller omitting the field = abort semantics)
221
+ ```
222
+
223
+ **Do NOT add comments when:**
224
+ - The comment would just restate the variable name or method call.
225
+ - A private helper method simply delegates to an interface method (the name is self-explanatory).
226
+ - `@parameter` description would be identical to the parameter name (e.g., `"! @parameter iv_name | Name`).
227
+ - You are modifying existing code and the task did not ask for documentation changes.
228
+
229
+ **DO add comments when:**
230
+ - The logic involves a non-obvious ABAP-specific behaviour or workaround.
231
+ - There is a caller precondition that cannot be expressed in the method signature.
232
+ - A COND/SWITCH mapping table needs to explain the business rule behind each branch.
233
+ - A loop exit or CONTINUE has a non-obvious condition.
234
+
235
+ ---
236
+
237
+ ## 7. Quick Decision Table
238
+
239
+ | Object | Where | Style | Required? |
240
+ |--------|-------|-------|-----------|
241
+ | CLAS (global) | Before `CLASS DEFINITION` | `"! <p class="shorttext synchronized">` | **Always** |
242
+ | CLAS public method | Before `METHODS` in DEFINITION | `"! desc` + `"! @parameter` | Yes (new objects) |
243
+ | CLAS private/protected method | Before `METHODS` in DEFINITION | `"! desc` | Only if non-obvious |
244
+ | INTF method | Before `METHODS` in interface | `"! desc` + `"! @parameter` | **Always** |
245
+ | PROG | First lines before `REPORT` | `*&---` block | **Always** |
246
+ | DDLS view entity | Before `define view entity` | `@EndUserText.label` annotation | **Always** |
247
+ | DDLS field | After field name | `// text` | For non-obvious fields |
248
+ | Method body | Inside `METHOD...ENDMETHOD` | `" text` | Only for non-obvious logic |
249
+ | TYPES block | Before `TYPES:` in interface/class | `" text` | Optional — `"!` is invalid here |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Common ABAP Errors
4
- nav_order: 14
4
+ nav_order: 12
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Dump Analysis Guide
4
- nav_order: 16
4
+ nav_order: 19
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Debug Session Guide
4
- nav_order: 15
4
+ nav_order: 18
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -31,6 +31,7 @@ This folder contains detailed ABAP coding guidelines that can be searched using
31
31
  | `object-creation.md` | Object Creation (XML metadata, local classes) |
32
32
  | `cds-testing.md` | CDS Testing (Test Double Framework) |
33
33
  | `abaplint.md` | abaplint Rule Guidelines (prefer_inline trap, safe patterns) |
34
+ | `comments.md` | Documentation Comments (ABAP DOC, shorttext, @parameter, CDS //) |
34
35
 
35
36
  ## Usage
36
37
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: JSON Handling
4
- nav_order: 8
4
+ nav_order: 11
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Object Creation
4
- nav_order: 19
4
+ nav_order: 22
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -17,26 +17,29 @@ Replace `<name>` with the actual object name from this project's naming conventi
17
17
 
18
18
  | Object Type | ABAP Source File | XML File | Details |
19
19
  |-------------|-----------------|----------|---------|
20
- | Class | `<name>.clas.abap` | `<name>.clas.xml` | See `guidelines/abapgit.md` |
21
- | Interface | `<name>.intf.abap` | `<name>.intf.xml` | See `guidelines/abapgit.md` |
22
- | Program | `<name>.prog.abap` | `<name>.prog.xml` | See `guidelines/abapgit.md` |
23
- | **CDS View Entity** | `<name>.ddls.asddls` | `<name>.ddls.xml` | **Use by default** - See `guidelines/cds.md` |
24
- | CDS View (legacy) | `<name>.ddls.asddls` | `<name>.ddls.xml` | Only if explicitly requested - See `guidelines/cds.md` |
25
- | Table (TABL) | *(none XML-only)* | `<name>.tabl.xml` | See `guidelines/abapgit.md` |
26
- | Structure (STRU) | *(none — XML-only)* | `<name>.stru.xml` | See `guidelines/abapgit.md` |
27
- | Data Element (DTEL) | *(none — XML-only)* | `<name>.dtel.xml` | See `guidelines/abapgit.md` |
28
- | Table Type (TTYP) | *(none — XML-only)* | `<name>.ttyp.xml` | See `guidelines/abapgit.md` |
29
-
30
- > **XML-only objects (TABL, STRU, DTEL, TTYP)**: create only the `.xml` file there is no `.abap` source file.
20
+ | Class (CLAS) | `<name>.clas.abap` | `<name>.clas.xml` | `ref --topic abapgit` |
21
+ | Interface (INTF) | `<name>.intf.abap` | `<name>.intf.xml` | `ref --topic abapgit` |
22
+ | Program (PROG) | `<name>.prog.abap` | `<name>.prog.xml` | `ref --topic abapgit` |
23
+ | CDS View Entity (DDLS) | `<name>.ddls.asddls` | `<name>.ddls.xml` | **Use by default** `ref --topic abapgit` |
24
+ | CDS Access Control (DCLS) | `<name>.dcls.asdcls` | `<name>.dcls.xml` | `ref --topic abapgit` |
25
+ | Function Group (FUGR) | `<name>.fugr.abap` + includes | `<name>.fugr.xml` | `ref --topic abapgit` |
26
+ | Table (TABL) | *(none — XML-only)* | `<name>.tabl.xml` | `ref --topic abapgit-xml-only` |
27
+ | Structure (STRU) | *(none — XML-only)* | `<name>.stru.xml` | `ref --topic abapgit-xml-only` |
28
+ | Data Element (DTEL) | *(none — XML-only)* | `<name>.dtel.xml` | `ref --topic abapgit-xml-only` |
29
+ | Table Type (TTYP) | *(none — XML-only)* | `<name>.ttyp.xml` | `ref --topic abapgit-xml-only` |
30
+ | Domain (DOMA) | *(none XML-only)* | `<name>.doma.xml` | `ref --topic abapgit-xml-only` |
31
+ | Message Class (MSAG) | *(none — XML-only)* | `<name>.msag.xml` | `ref --topic abapgit-xml-only` |
32
+
33
+ > **XML-only objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG)**: create only the `.xml` file — there is no `.abap` source file.
31
34
  > After committing and pushing, pull with: `pull --files <folder>/<name>.tabl.xml --sync-xml`
32
35
 
33
- **IMPORTANT: When user says "create CDS view", create CDS View Entity by default.**
36
+ **IMPORTANT: When user says "create CDS view", create CDS View Entity (DDLS) by default.**
34
37
 
35
38
  **Why:** Modern S/4HANA standard, simpler (no SQL view), no namespace conflicts.
36
39
 
37
40
  **For complete XML templates, DDL examples, and detailed comparison:**
38
- - **CDS Views**: `guidelines/cds.md`
39
- - **XML templates**: `guidelines/abapgit.md`
41
+ - **CDS Views + DCLS + FUGR**: `abapgit-agent ref --topic abapgit`
42
+ - **XML-only objects**: `abapgit-agent ref --topic abapgit-xml-only`
40
43
 
41
44
  ---
42
45
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Naming Conventions
4
- nav_order: 7
4
+ nav_order: 5
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Unit Testing
4
- nav_order: 4
4
+ nav_order: 7
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
8
8
 
9
9
  # Unit Testing
10
10
 
11
- **Searchable keywords**: unit test, AUnit, test class, cl_abap_unit_assert, FOR TESTING, setup, teardown, RISK LEVEL, DURATION, CDS test double, CL_CDS_TEST_ENVIRONMENT
11
+ **Searchable keywords**: unit test, AUnit, test class, cl_abap_unit_assert, FOR TESTING, setup, teardown, RISK LEVEL, DURATION, WITH_UNIT_TESTS, testclasses
12
12
 
13
13
  ## TOPICS IN THIS FILE
14
14
  1. Local Test Classes - line 22
@@ -16,8 +16,6 @@ grand_parent: ABAP Development
16
16
  3. Required Elements - line 35
17
17
  4. Naming Conventions - line 67
18
18
  5. Common Mistake: DDLS Testing - line 133
19
- 6. CDS Test Doubles - line 163
20
- 7. CDS with Aggregations - line 247
21
19
 
22
20
  ## Unit Testing with Local Test Classes
23
21
 
@@ -169,206 +167,10 @@ Or via abapGit: Pull the files and run tests in the ABAP system.
169
167
 
170
168
  ## Unit Testing CDS Views
171
169
 
172
- When testing code that uses CDS view entities, you can use the **CDS Test Double Framework** (`CL_CDS_TEST_ENVIRONMENT`) to create test doubles for CDS views. This allows you to inject test data without affecting production data.
173
-
174
- ### When to Use CDS Test Doubles
175
-
176
- - Testing code that reads from CDS views
177
- - Need controlled test data (not production data)
178
- - Testing CDS view logic with specific scenarios
179
-
180
- ### CDS Test Double Framework
181
-
182
- Use `CL_CDS_TEST_ENVIRONMENT` for controlled test data:
183
-
184
- ```abap
185
- "-------------------------
186
- " CLASS DEFINITION
187
- "-------------------------
188
- CLASS ltcl_cds_test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
189
-
190
- PRIVATE SECTION.
191
- " IMPORTANT: Use interface type, not class type!
192
- DATA mo_cds_env TYPE REF TO if_cds_test_environment.
193
-
194
- " IMPORTANT: class_setup/teardown must be CLASS-METHODS (static)!
195
- CLASS-DATA mo_cds_env_static TYPE REF TO if_cds_test_environment.
196
-
197
- METHODS setup.
198
- METHODS test_cds_with_doubles FOR TESTING.
199
-
200
- CLASS-METHODS: class_setup,
201
- class_teardown.
202
-
203
- ENDCLASS.
204
-
205
- "-------------------------
206
- " CLASS IMPLEMENTATION
207
- "-------------------------
208
- CLASS ltcl_cds_test IMPLEMENTATION.
209
-
210
- METHOD class_setup.
211
- " Create CDS test environment - framework auto-creates doubles for dependencies
212
- mo_cds_env_static = cl_cds_test_environment=>create(
213
- i_for_entity = 'ZC_MY_CDS_VIEW' ).
214
- ENDMETHOD.
215
-
216
- METHOD class_teardown.
217
- " Clean up test environment
218
- mo_cds_env_static->destroy( ).
219
- ENDMETHOD.
220
-
221
- METHOD setup.
222
- " IMPORTANT: Assign static env to instance and clear doubles
223
- mo_cds_env = mo_cds_env_static.
224
- mo_cds_env->clear_doubles( ).
225
- ENDMETHOD.
226
-
227
- METHOD test_cds_with_doubles.
228
- " IMPORTANT: Must declare table type first, cannot inline in VALUE!
229
- DATA lt_test_data TYPE TABLE OF zc_my_cds_view WITH EMPTY KEY.
230
- lt_test_data = VALUE #(
231
- ( field1 = 'A' field2 = 100 )
232
- ( field1 = 'B' field2 = 200 ) ).
233
-
234
- " Insert test data using named parameter
235
- mo_cds_env->insert_test_data( i_data = lt_test_data ).
236
-
237
- " Select from CDS view
238
- SELECT * FROM zc_my_cds_view INTO TABLE @DATA(lt_result).
239
-
240
- " Verify results
241
- cl_abap_unit_assert=>assert_not_initial(
242
- act = lt_result
243
- msg = 'Result should not be empty' ).
244
-
245
- cl_abap_unit_assert=>assert_equals(
246
- act = lines( lt_result )
247
- exp = 2
248
- msg = 'Expected 2 rows' ).
249
- ENDMETHOD.
250
-
251
- ENDCLASS.
252
- ```
253
-
254
- ### Testing CDS Views with Aggregations (SUM, COUNT, GROUP BY)
255
-
256
- For CDS views with aggregations, insert test data into the **base tables** (SFLIGHT, SCARR, SBOOK), not directly into the CDS view:
257
-
258
- ```abap
259
- METHOD test_aggregation.
260
- " Insert data into base tables via CDS test doubles
261
- DATA lt_scarr TYPE TABLE OF scarr WITH EMPTY KEY.
262
- lt_scarr = VALUE #( ( carrid = 'LH' carrname = 'Lufthansa' currcode = 'EUR' ) ).
263
- mo_cds_env->insert_test_data( i_data = lt_scarr ).
264
-
265
- DATA lt_sflight TYPE TABLE OF sflight WITH EMPTY KEY.
266
- lt_sflight = VALUE #( ( carrid = 'LH' connid = '0400' fldate = '20240115'
267
- seatsmax = 200 seatsocc = 100 ) ).
268
- mo_cds_env->insert_test_data( i_data = lt_sflight ).
269
-
270
- DATA lt_sbook TYPE TABLE OF sbook WITH EMPTY KEY.
271
- lt_sbook = VALUE #(
272
- ( carrid = 'LH' connid = '0400' fldate = '20240115' bookid = '0001' forcuram = 1000 )
273
- ( carrid = 'LH' connid = '0400' fldate = '20240115' bookid = '0002' forcuram = 2000 )
274
- ( carrid = 'LH' connid = '0400' fldate = '20240115' bookid = '0003' forcuram = 3000 ) ).
275
- mo_cds_env->insert_test_data( i_data = lt_sbook ).
276
-
277
- " Select from CDS view - aggregations will use test double data
278
- SELECT * FROM zc_flight_revenue INTO TABLE @DATA(lt_result).
279
-
280
- " Verify aggregations
281
- cl_abap_unit_assert=>assert_equals(
282
- exp = 3
283
- act = lt_result[ 1 ]-numberofbookings
284
- msg = 'Should have 3 bookings' ).
285
-
286
- cl_abap_unit_assert=>assert_equals(
287
- exp = '6000.00'
288
- act = lt_result[ 1 ]-totalrevenue
289
- msg = 'Total revenue should be 6000.00' ).
290
- ENDMETHOD.
291
- ```
292
-
293
- ### Testing CDS Views that Select from Another CDS View
294
-
295
- > **Note:** This pattern applies when your design **already has** a CDS view that selects from another CDS view. It does NOT mean you should split a single view into two — use a single CDS view with GROUP BY / JOIN when the business logic fits.
296
-
297
- When your CDS view selects from **another CDS view** (not a base table), `create` will raise `CX_CDS_FAILURE`. Use `create_for_multiple_cds` instead and list all CDS entities in the dependency chain.
298
-
299
- ```abap
300
- METHOD class_setup.
301
- " ZC_TopView selects from ZC_IntermediateView (another CDS view entity)
302
- " → must use create_for_multiple_cds and list all CDS entities
303
- mo_cds_env_static = cl_cds_test_environment=>create_for_multiple_cds(
304
- i_for_entities = VALUE #(
305
- ( 'ZC_TOPVIEW' ) " the view under test
306
- ( 'ZC_INTERMEDIATEVIEW' ) " the CDS view it selects from
307
- ) ).
308
- ENDMETHOD.
309
- ```
310
-
311
- Insert test data into the intermediate CDS view (not the base tables), since that is what the top-level view reads:
312
-
313
- ```abap
314
- METHOD test_read.
315
- DATA lt_source TYPE TABLE OF zc_intermediateview WITH EMPTY KEY.
316
- lt_source = VALUE #(
317
- ( field1 = 'A' field2 = 100 )
318
- ( field1 = 'B' field2 = 200 ) ).
319
- mo_cds_env->insert_test_data( i_data = lt_source ).
320
-
321
- SELECT * FROM zc_topview INTO TABLE @DATA(lt_result).
322
-
323
- cl_abap_unit_assert=>assert_equals(
324
- exp = 2 act = lines( lt_result ) msg = 'Expected 2 rows' ).
325
- ENDMETHOD.
326
- ```
327
-
328
- **Rules:**
329
- - List the view under test **and all CDS views it depends on** in `i_for_entities`
330
- - Insert data into the **direct source** of the top-level view (the intermediate CDS view)
331
- - Order in `i_for_entities` does not matter
332
- - If you get `CX_CDS_FAILURE` when using `create`, switch to `create_for_multiple_cds`
333
-
334
- ---
335
-
336
- ### Key Classes for CDS Testing
337
-
338
- | Item | Type/Usage |
339
- |------|------------|
340
- | `CL_CDS_TEST_ENVIRONMENT` | Class with `CREATE` method |
341
- | `IF_CDS_TEST_ENVIRONMENT` | Interface (CREATE returns this type) |
342
- | `CLASS-METHODS` | `class_setup` and `class_teardown` must be static methods |
343
- | `CL_OSQL_TEST_ENVIRONMENT` | Test doubles for database tables (use for aggregations) |
344
- | `CL_ABAP_UNIT_ASSERT` | Assertions |
345
-
346
- ### Key Methods
347
-
348
- | Method | Purpose |
349
- |--------|---------|
350
- | `CL_CDS_TEST_ENVIRONMENT=>create( i_for_entity = ... )` | Create test environment for a CDS view over base tables |
351
- | `CL_CDS_TEST_ENVIRONMENT=>create_for_multiple_cds( i_for_entities = ... )` | Create test environment when the CDS view selects from another CDS view |
352
- | `insert_test_data( i_data = ... )` | Insert test data into test doubles |
353
- | `clear_doubles` | Clear test data before each test method |
354
- | `destroy` | Clean up after test class |
355
-
356
- ### Important Usage Notes
357
-
358
- 1. **Use interface type**: `DATA mo_cds_env TYPE REF TO if_cds_test_environment` - the CREATE method returns an interface reference
359
- 2. **CLASS-METHODS required**: `class_setup` and `class_teardown` must be declared with `CLASS-METHODS` (not `METHODS`)
360
- 3. **Table type declaration**: Must declare `DATA lt_tab TYPE TABLE OF <type> WITH EMPTY KEY` before using `VALUE #()`
361
- 4. **Auto-created dependencies**: When the CDS view selects only from **base tables**, the framework auto-creates test doubles — do not specify `i_dependency_list`. When the CDS view selects from **another CDS view**, use `create_for_multiple_cds` instead (see section below).
362
- 5. **Aggregations**: For CDS views with SUM/COUNT/GROUP BY, insert test data into base tables (SFLIGHT, SCARR, etc.)
363
- 6. **Clear doubles**: Call `clear_doubles` in `setup` method before each test
364
- 7. **Enable associations**: Set `test_associations = 'X'` only if testing CDS associations
365
- 8. **Exception handling**: Declare test methods with `RAISING cx_static_check` for proper exception handling
366
-
367
- ### Search Reference for More Details
170
+ For full CDS test double patterns (basic setup, aggregations, CDS-on-CDS), see:
368
171
 
369
172
  ```bash
370
- abapgit-agent ref "cl_cds_test_environment"
371
- abapgit-agent ref --topic unit-tests
173
+ abapgit-agent ref --topic cds-testing
372
174
  ```
373
175
 
374
176
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Unit Testable Code
4
- nav_order: 13
4
+ nav_order: 8
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Development Workflow (Detailed)
4
- nav_order: 18
4
+ nav_order: 21
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abapgit-agent",
3
- "version": "1.15.1",
3
+ "version": "1.15.2",
4
4
  "description": "ABAP Git Agent - Pull and activate ABAP code via abapGit from any git repository",
5
5
  "files": [
6
6
  "bin/",