abapgit-agent 1.15.1 → 1.15.3
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/.github/copilot-instructions.slim.md +35 -4
- package/abap/CLAUDE.md +70 -53
- package/abap/guidelines/abapgit-fugr.md +20 -4
- package/abap/guidelines/abapgit-xml-only.md +69 -13
- package/abap/guidelines/abapgit.md +3 -2
- package/abap/guidelines/abaplint-local.md +1 -1
- package/abap/guidelines/abaplint.md +1 -1
- package/abap/guidelines/branch-workflow.md +1 -1
- package/abap/guidelines/cds-testing.md +233 -11
- package/abap/guidelines/cds.md +1 -1
- package/abap/guidelines/classes.md +1 -1
- package/abap/guidelines/comments.md +249 -0
- package/abap/guidelines/common-errors.md +1 -1
- package/abap/guidelines/debug-dump.md +1 -1
- package/abap/guidelines/debug-session.md +1 -1
- package/abap/guidelines/index.md +2 -0
- package/abap/guidelines/json.md +1 -1
- package/abap/guidelines/naming-limits.md +160 -0
- package/abap/guidelines/object-creation.md +18 -15
- package/abap/guidelines/objects.md +6 -3
- package/abap/guidelines/testing.md +4 -202
- package/abap/guidelines/unit-testable-code.md +1 -1
- package/abap/guidelines/workflow-detailed.md +1 -1
- package/package.json +1 -1
- package/abap/.github/copilot-instructions.md +0 -264
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
title: Naming Length Limits
|
|
4
|
+
nav_order: 6
|
|
5
|
+
parent: ABAP Coding Guidelines
|
|
6
|
+
grand_parent: ABAP Development
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ABAP Naming Length Limits
|
|
10
|
+
|
|
11
|
+
**Searchable keywords**: name length, character limit, 30 characters, 16 characters, 40 characters, too long, truncate, field name, method name, class name, table name, CDS name
|
|
12
|
+
|
|
13
|
+
> **Rule of thumb**: Most ABAP object names → 30 chars. Table/structure **field names** → 16 chars. CDS/DDLS names → 40 chars. Method names (including test methods) → 30 chars.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Quick Reference
|
|
18
|
+
|
|
19
|
+
| Object / Element | Max Length |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Class name (CLAS) | **30** |
|
|
22
|
+
| Interface name (INTF) | **30** |
|
|
23
|
+
| Program name (PROG) | **30** |
|
|
24
|
+
| Function Group name (FUGR) | **26** |
|
|
25
|
+
| Function Module name | **30** |
|
|
26
|
+
| Table name (TABL) | **30** |
|
|
27
|
+
| **Table field name** | **16** |
|
|
28
|
+
| Structure name (STRU) | **30** |
|
|
29
|
+
| **Structure field name** | **16** |
|
|
30
|
+
| Data Element name (DTEL) | **30** |
|
|
31
|
+
| Domain name (DOMA) | **30** |
|
|
32
|
+
| Table Type name (TTYP) | **30** |
|
|
33
|
+
| Package name | **30** |
|
|
34
|
+
| **CDS View Entity name (DDLS)** | **40** |
|
|
35
|
+
| CDS Access Control name (DCLS) | **40** |
|
|
36
|
+
| CDS field alias | **30** |
|
|
37
|
+
| Message Class name (MSAG) | **20** |
|
|
38
|
+
| Class method name | **30** |
|
|
39
|
+
| **Test method name** | **30** |
|
|
40
|
+
| Interface method name | **30** |
|
|
41
|
+
| Class attribute name | **30** |
|
|
42
|
+
| Local variable name | **30** |
|
|
43
|
+
| Local type/class name | **30** |
|
|
44
|
+
| Test class name (local) | **30** |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Critical Differences — Don't Confuse These
|
|
49
|
+
|
|
50
|
+
### Table/Structure Field Names: 16 Characters MAX
|
|
51
|
+
|
|
52
|
+
This is the **most common mistake**. Field names in TABL and STRU are limited to **16 characters**, not 30.
|
|
53
|
+
|
|
54
|
+
```xml
|
|
55
|
+
<!-- WRONG — 17 characters -->
|
|
56
|
+
<FIELDNAME>LAST_MODIFIED_AT</FIELDNAME>
|
|
57
|
+
|
|
58
|
+
<!-- CORRECT — 16 characters or fewer -->
|
|
59
|
+
<FIELDNAME>LAST_MODIFIED</FIELDNAME>
|
|
60
|
+
<FIELDNAME>SYS_CHANGED_AT</FIELDNAME> <!-- 14 chars ✓ -->
|
|
61
|
+
<FIELDNAME>LAST_PULLED_AT</FIELDNAME> <!-- 14 chars ✓ -->
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
When naming table fields, keep names short and descriptive:
|
|
65
|
+
- `CARRID` not `CARRIER_ID_FIELD`
|
|
66
|
+
- `CONNID` not `CONNECTION_IDENTIFIER`
|
|
67
|
+
- `STATUS` not `CURRENT_STATUS_FLAG`
|
|
68
|
+
- `CREATED_AT` not `CREATION_TIMESTAMP`
|
|
69
|
+
|
|
70
|
+
### CDS View Names: 40 Characters MAX
|
|
71
|
+
|
|
72
|
+
CDS View Entity (DDLS) names allow up to **40 characters** — more room than regular ABAP objects.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
ZC_MY_FLIGHT_BOOKING_REVENUE_SUMMARY ← 40 chars (at limit)
|
|
76
|
+
ZC_FLIGHT_REVENUE ← 17 chars (fine)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
However, CDS **field aliases** inside the view are still limited to **30 characters** (ABAP identifier rules).
|
|
80
|
+
|
|
81
|
+
### Function Group Names: 26 Characters MAX
|
|
82
|
+
|
|
83
|
+
Function groups (`FUGR`) have a **26-character limit** because ABAP appends a 4-character suffix internally (e.g. `SAPLZMY_FG` prefix + module name). The safe usable name length is 26 characters.
|
|
84
|
+
|
|
85
|
+
### Test Method Names: 30 Characters MAX — Causes Syntax Error
|
|
86
|
+
|
|
87
|
+
Test methods (`FOR TESTING`) hit the 30-char limit frequently because the `test_` prefix takes 5 chars before the meaningful content starts.
|
|
88
|
+
|
|
89
|
+
```abap
|
|
90
|
+
" WRONG — 34 characters → syntax error at activation
|
|
91
|
+
METHODS test_execute_with_minimal_params FOR TESTING.
|
|
92
|
+
|
|
93
|
+
" CORRECT — abbreviate to stay within 30 chars
|
|
94
|
+
METHODS test_exec_minimal FOR TESTING. " 18 chars ✓
|
|
95
|
+
METHODS test_exec_with_files FOR TESTING. " 24 chars ✓
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Counting test method length**: include the full method name — `test_exec_minimal` is 18 characters.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Counting Characters Before You Name Things
|
|
103
|
+
|
|
104
|
+
Use this mental check before naming any ABAP element:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
# Object name: type prefix + your name ≤ limit
|
|
108
|
+
ZCL_ (4 chars) + name ≤ 30 → name ≤ 26 chars
|
|
109
|
+
ZIF_ (4 chars) + name ≤ 30 → name ≤ 26 chars
|
|
110
|
+
ZC_ (3 chars) + name ≤ 40 → name ≤ 37 chars (CDS)
|
|
111
|
+
Z (1 char) + name ≤ 30 → name ≤ 29 chars (table/program)
|
|
112
|
+
|
|
113
|
+
# Project-specific sub-namespace eats more of the budget — plan ahead
|
|
114
|
+
# Example: project uses ZFICO_ prefix for all objects
|
|
115
|
+
ZCL_FICO_ (9 chars) + name ≤ 30 → name ≤ 21 chars
|
|
116
|
+
ZCL_FICO_PAYMENT_PROPOSAL = 26 chars ✓
|
|
117
|
+
ZCL_FICO_PAYMENT_PROPOSAL_V = 27 chars ✓ (getting tight)
|
|
118
|
+
|
|
119
|
+
# Field name in TABL/STRU: no prefix, just ≤ 16 total
|
|
120
|
+
PAYMENT_METHOD = 14 chars ✓
|
|
121
|
+
PAYMENT_METHOD_CD = 17 chars ✗ → shorten to PAYMENT_METH_CD
|
|
122
|
+
|
|
123
|
+
# Method name: no prefix, just ≤ 30 total
|
|
124
|
+
test_exec_with_files → 24 chars ✓
|
|
125
|
+
test_execute_with_minimal_params → 34 chars ✗
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Common Length Violations and Fixes
|
|
131
|
+
|
|
132
|
+
| Too Long (violates limit) | Fixed Version | Limit |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `ZCL_COMMAND_PULL_WITH_RETRY` (30+ chars) | `ZCL_COMMAND_PULL_RETRY` | 30 |
|
|
135
|
+
| `LAST_SUCCESSFULLY_PULLED_AT` (table field, 28 chars) | `LAST_PULLED_AT` | 16 |
|
|
136
|
+
| `test_execute_command_with_files` (test method, 32 chars) | `test_exec_with_files` | 30 |
|
|
137
|
+
| `ZC_MY_VERY_LONG_CDS_VIEW_NAME_EXCEEDS_40_CHARS` (47 chars) | `ZC_MY_LONG_CDS_VIEW_NAME_TRIMMED` | 40 |
|
|
138
|
+
| `ZBIZ_OBJECT_CREATION_SERVICE_MESSAGE_CLASS` (MSAG, 43 chars) | `ZBIZ_CREATE_MSGS` | 20 |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## SAP Technical Basis for These Limits
|
|
143
|
+
|
|
144
|
+
These limits come from the ABAP Dictionary (DDIC) and ABAP kernel:
|
|
145
|
+
|
|
146
|
+
| Limit Source | Explanation |
|
|
147
|
+
|---|---|
|
|
148
|
+
| 30 chars (most objects) | ABAP uses `RSYN` program name space; objects stored in `TADIR` with `SOBJ_NAME CHAR(40)` but compiler enforces 30 for classes/interfaces/programs |
|
|
149
|
+
| 16 chars (DDIC fields) | Stored in `DD03L.FIELDNAME CHAR(16)` — this is a hard database column width |
|
|
150
|
+
| 40 chars (CDS names) | CDS objects stored in `DD02L.TABNAME CHAR(40)` — intentionally larger for CDS |
|
|
151
|
+
| 20 chars (MSAG) | Message class name stored in `T100A.ARBGB CHAR(20)` |
|
|
152
|
+
| 26 chars (FUGR) | Function group internally prefixed with `SAPL` (4 chars) for the main include |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## See Also
|
|
157
|
+
|
|
158
|
+
- **Naming Conventions** (objects.md) — prefixes per object type
|
|
159
|
+
- **Object Creation** (object-creation.md) — which files to create
|
|
160
|
+
- **Testing** (testing.md) — test method naming (30-char limit detail)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
layout: default
|
|
3
3
|
title: Object Creation
|
|
4
|
-
nav_order:
|
|
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` |
|
|
21
|
-
| Interface | `<name>.intf.abap` | `<name>.intf.xml` |
|
|
22
|
-
| Program | `<name>.prog.abap` | `<name>.prog.xml` |
|
|
23
|
-
|
|
|
24
|
-
| CDS
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
|
|
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>.tabl.xml` ⚠️ NOT `.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**: `
|
|
39
|
-
- **XML
|
|
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:
|
|
4
|
+
nav_order: 5
|
|
5
5
|
parent: ABAP Coding Guidelines
|
|
6
6
|
grand_parent: ABAP Development
|
|
7
7
|
---
|
|
@@ -15,12 +15,13 @@ grand_parent: ABAP Development
|
|
|
15
15
|
| | SAP Namespace | Customer Namespace |
|
|
16
16
|
|---|---|---|
|
|
17
17
|
| **Object prefix** | `CL_*`, `IF_*`, `/NAME/CL_*`, `/NAME/IF_*`, etc. | `Z*`, `Y*` |
|
|
18
|
-
| **Package prefix** | SAP-delivered (e.g. `SFIN`, `CA_*`, `/NAME/*`) | `Z*`, `Y*`, `$*` |
|
|
18
|
+
| **Package prefix** | SAP-delivered (e.g. `SFIN`, `CA_*`, `/NAME/*`) | `Z*`, `Y*`, `$*` (local/non-transportable) |
|
|
19
19
|
| **Ownership** | Delivered and maintained by SAP | Owned by the customer |
|
|
20
20
|
| **In git repo** | Objects from an SAP-delivered package | Custom development objects |
|
|
21
21
|
|
|
22
22
|
> **Rule**: Never add customer-created objects (including PoC/probe classes) into SAP namespace
|
|
23
23
|
> packages. PoC objects always use `Z*`/`Y*` prefix and always go in a `Z*`, `Y*`, or `$*` package
|
|
24
|
+
> (use `$*` only for throwaway probes — non-transportable)
|
|
24
25
|
> — even on a project where production objects use SAP namespace.
|
|
25
26
|
|
|
26
27
|
## How to Determine This Project's Naming Convention
|
|
@@ -43,7 +44,8 @@ Applied when no `objects.local.md` exists:
|
|
|
43
44
|
| Class | `ZCL_` | `ZCL_MY_CLASS` |
|
|
44
45
|
| Interface | `ZIF_` | `ZIF_MY_INTERFACE` |
|
|
45
46
|
| Program | `Z` | `ZMY_PROGRAM` |
|
|
46
|
-
| Package |
|
|
47
|
+
| Package | `Z` or `Y` | `ZMYPROJECT` |
|
|
48
|
+
> **Note**: `$` packages (e.g. `$TMP`) are local/non-transportable — use only for throwaway probe objects, never for real development.
|
|
47
49
|
| Table | `Z` | `ZMY_TABLE` |
|
|
48
50
|
| CDS View Entity | `ZC_` | `ZC_MY_VIEW` |
|
|
49
51
|
| Data Element | `Z` | `ZMY_ELEMENT` |
|
|
@@ -83,3 +85,4 @@ Default package: /MYNAMESPACE/MAIN
|
|
|
83
85
|
|
|
84
86
|
→ For file structure (what files to create): `abapgit-agent ref --topic object-creation`
|
|
85
87
|
→ For XML templates: `abapgit-agent ref --topic abapgit`
|
|
88
|
+
→ For name **length limits** (30/16/40 char rules): `abapgit-agent ref --topic naming-limits`
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
layout: default
|
|
3
3
|
title: Unit Testing
|
|
4
|
-
nav_order:
|
|
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,
|
|
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
|
-
|
|
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
|
|
371
|
-
abapgit-agent ref --topic unit-tests
|
|
173
|
+
abapgit-agent ref --topic cds-testing
|
|
372
174
|
```
|
|
373
175
|
|
|
374
176
|
---
|