Lesson 3 of 6
CAP and UI5 gates
8 min
Listen to this lesson
On SAP BTP, generated code comes fast: SAP's own tools generate CAP services and Fiori elements apps, and general coding agents write JavaScript and CDS fluently. The gates here are the same in spirit as for ABAP (static checks, tests, review) but the tools are the Node.js ecosystem's. Contoso's example is cmc-core-returns, a CAP service the BTP team is building in cmc-ext-dev so fleet customers can see their core return agreements, with a UI5 app on top.
CAP: lint, then test
The CAP documentation describes CDS Lint, based on ESLint with the @sap/eslint-plugin-cds plugin. Running cds add lint installs ESLint and the plugin and adds configuration; cds lint in the project root runs it and prints nothing when there are no findings. Rules such as @sap/cds/valid-csv-header check CDS models and sample data, so they catch an agent's typos in entity names and broken CSV seed files before anything runs.
For behavior, CAP provides cds.test in the @cap-js/cds-test package (install it as a dev dependency). Calling cds.test() at the top of a test file starts a CAP server for the project and returns request helpers such as GET, POST and PUT, plus a Chai-style expect. It works with Node's built-in runner, Vitest, Jest and Mocha, and cds test wraps the built-in runner.
| Gate | Check | Rule for AI-generated CAP code |
|---|---|---|
| Lint | cds lint | No errors; warnings reviewed |
| Unit and service tests | cds.test with GET, POST and expect | Every new entity, action and handler has a test; tests check content, not just status codes |
| Authorization tests | Requests as different mocked users | Each @requires or @restrict rule tested with an allowed and a denied user |
| Dependency check | Lock file diff | No new dependencies without review |
| Review | Diff | Authorization annotations, side effects in handlers, hard-coded destinations |
Authorization deserves its own tests because it is what generated code most often leaves out. If cmc-core-returns restricts agreements so a customer user sees only its own, write a test that reads as Great Lakes Fleet Services and expects only its agreements, and a second that reads as another customer and expects none of them. An agent can generate those tests too, but a person decides what the rules are.
UI5: the linter as a gate
For UI5 apps, SAP's @ui5/linter runs as ui5lint in the project root. It reports usage of deprecated UI5 libraries and framework APIs, global variables, possible Content Security Policy violations, and deprecated component and manifest configurations, aimed at UI5 2.x readiness. Its --fix option can correct some findings, such as replacing globals with module imports, and --format json gives machine-readable output a pipeline or an agent can parse. Models trained on years of older UI5 code reach for deprecated APIs and globals, so this gate catches a lot of generated code.
| Pattern in generated UI5 code | Why models produce it | What the review or linter expects instead |
|---|---|---|
jQuery.sap.* utilities, such as jQuery.sap.log | Years of older UI5 samples in training data | The modular replacements loaded with sap.ui.define, such as sap/base/Log |
Global names, such as sap.m.MessageBox.show(...) without an import | Older tutorials used globals | Declare the dependency in sap.ui.define and use the imported module |
sap.ui.getCore() calls | Common in older controllers and component code | The APIs the linter suggests for your UI5 version; check the deprecation notes |
Synchronous loading, such as sap.ui.requireSync | Simpler code in old examples | Asynchronous loading with sap.ui.require or sap.ui.define |
| Manifest settings marked deprecated | Copied from older app templates | The current manifest structure the linter reports |
Typical findings in AI-generated UI5 code. Run ui5lint for the authoritative list for your UI5 version.
For UI5 behavior, SAPUI5 ships its own test frameworks: QUnit for unit tests and OPA5 for integration tests, described in the SAPUI5 documentation. Hold generated OPA5 tests to the same meaning standard as ABAP Unit: they should fail when the screen shows the wrong agreement or status, not just pass when the page loads.
What would you do?
An agent adds a new action to cmc-core-returns that closes a core agreement. Lint and the agent's five new tests pass. The tests all call the action as an administrator. What should the reviewer ask for?
- CAP gates: cds lint with @sap/eslint-plugin-cds, then cds.test service tests from @cap-js/cds-test.
- Test every authorization rule with an allowed and a denied user; generated tests default to the easiest user.
- Run ui5lint (with --format json in pipelines) to catch deprecated APIs, globals and CSP issues common in generated UI5 code.
- Review new dependencies explicitly; agents add packages freely.
Check your understanding · not graded
Lesson check
1. Which command adds CDS Lint to a CAP project?
2. Which package provides cds.test for CAP service tests?
3. What does the UI5 linter report?
4. Why must authorization rules in generated CAP code be tested with a denied user?