ABAP Development for SAP S4HANA (SAP PRESS) (第14页)

第 398 页 / 共 465 页

11 Continuous Integration

In the test stage, we run the previously developed QUnit unit test and OPA5 integra-

tion test of the project to ensure that we didn’t introduce any regressions with our

new changes and our software works as defined in our tests. In the deploy stage we

store the deployment-ready project as a ZIP file in the JFrog Artifactory cloud version

software repository (https://jfrog.com/artifactory/) 31. Like this, we have at any

time deployable versions of our project for each build, which is also centrally stored.

Additionally, we’ll outline the steps necessary to automatically deploy the SAPUI5

project to the SAP Gateway hub ABAP system on successful build and test stages,

which would enable continuous deployment. To deploy SAPUI5 projects from within

a CI/CD pipeline, the SAP Gateway hub system provides remote function call (RFC)

function modules that can be used to trigger 32 the download of the SAPUI5 project

from a software repository and its deployment 33.

You should already be familiar with developing SAPUI5 applications in the SAP Web

IDE full-stack and managing the source code with a Git SCM system. The focus of this

section will therefore be on setting up the Jenkins automation pipeline. There are a

lot of other alternatives for setting up CI/CD pipelines, for instance, Concourse CI,

Bamboo, or Travis CI, but Jenkins is very widely used and offers a nice new user expe-

rience (UX) called Blue Ocean, which makes setting up pipelines very easy. To auto-

mate the different stages, we’ll use the Grunt JavaScript task runner as SAP provides

best practice Grunt plug-ins for the build and test stages. Another alternative for the

JFrog Artifactory repository for storing the built project, would, for instance, be Sona-

type Nexus.

11.2.1 Setting Up a Local Jenkins Automation Server

Usually a Jenkins automation server runs in a dedicated server or cloud environ-

ment, however, in our case we’ll set it up locally on our (Windows 10) machine for test-

ing purposes. Additionally, we want to run our Jenkins automation sever as well as our

pipeline stages inside Docker containers to have unified runtime environments. To

install Docker on your local machine, refer to the Docker website (www.docker.com).

Blue Ocean is the latest UX for Jenkins and makes building automation pipelines very

easy. The easiest way to try out Jenkins Blue Ocean is to use the jenkinsci/blueocean

(https://hub.docker.com/r/jenkinsci/blueocean/) Docker image, which already con-

tains the Blue Ocean suite of plug-ins. We can run this Docker image as a container on

Windows by entering the docker run command shown in Listing 11.1 into the Win-

dows command prompt.

398

第 399 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

docker run ^

-u root ^

--rm ^

-d ^

-p 8080:8080 ^

-v jenkins-data:/var/jenkins_home ^

-v /var/run/Docker.sock:/var/run/Docker.sock ^

--name jenkins ^

jenkinsci/blueocean

Listing 11.1 Run the Jenkins Blue Ocean Docker Image as a Docker Container on Windows

The docker run command runs a Docker image as an isolated Docker container, which

is essentially an isolated process with its own networking, file system, and process

tree. In addition to the jenkinsci/blueocean argument, which is the image we want to

fetch from Docker Hub and run locally on our machine, we’re providing several flags

and options: The -u root option and argument runs the container with the root user.

The --rm flag makes Docker automatically clean up the container and remove the file

system on exit. The -d flag runs the container in detach mode as a background pro-

cess and outputs the container ID to the command prompt. The -p 8080:8080 option

and argument maps the 8080 port of the host system (your local machine) to the

8080 port of the Docker container. The -v jenkins-data:/var/jenkins_home option

and argument maps the /var/jenkins_home container directory to the Docker volume

with the name jenkins-data to persist the Jenkins settings between container

restarts. The -v /var/run/Docker.sock:/var/run/Docker.sock option and argument

maps the Docker daemon of the Docker container to the Docker daemon running on

your local machine. This is needed as we want to use additional Docker containers as

unified runtime environments inside our pipeline. Finally, the --name jenkins option

and argument defines the name jenkins for our container.

You can then access the locally running Jenkins server on http://localhost:8080. The

initial Jenkins password needed to unlock Jenkins when running it for the first time

is written to the Jenkins console log, which you can display with the docker logs jen-

kins command. After unlocking Jenkins, the installation wizard will guide your

through the rest of the installation steps. Simply accept the suggestions, and create

an admin user.

399

第 400 页 / 共 465 页

11 Continuous Integration

Note

For a more detailed description on how to install and run Jenkins in Docker, refer to

the official Jenkins documentation at https://jenkins.io/doc/book/installing/#docker.

11.2.2 Creating an Initial Jenkinsfile

In Jenkins, pipelines, taking code from a SCM system to end users, are defined using

a declarative Jenkinsfile. The Jenkinsfile must be part of the GitHub-managed

SAPUI5 project and reside in the root folder of the project. Figure 11.5 shows the initial

Jenkinsfile, which we’ll add to the freestyle application developed in Chapter 7 and

push to our GitHub repository to put it under version control. The Jenkinsfile

already contains the three stages we want to implement: build, test, and deploy. We’ll

implement the steps of the respective stages in the following subsections.

Figure 11.5 Initial Jenkinsfile for a SAPUI5 Project Containing Build, Test, and Deploy Stages

400

Note For a more detailed description on how to install and run Jenkins in Docker, refer to
the official Jenkins documentation at https://jenkins.io/doc/book/installing/#docker.

第 401 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

11.2.3 Creating the Continuous Deployment Pipeline

To create a pipeline in our running Jenkins Docker container, we must, as shown in

Figure 11.6, navigate to the http://localhost:8080/blue/pipelines URL 1 and click on

the Create New Pipeline button 2.

Figure 11.6 Starting the Pipeline Creation Process in Jenkins Blue Ocean

On the Create Pipeline page shown in Figure 11.7, we must then first select where we

store our SAPUI5 project code 1, in our case, in a GitHub repository. When running

the pipeline, Jenkins will first clone our project and must therefore authorize itself

with GitHub. To create an access token for GitHub, simply click on the Create an

access token here link 2, which will forward you to your GitHub’s account Settings/

Developer Settings/Personal Access Token area. Leave the selected scopes as they are,

provide a name for the token, generate the token, and paste it into the input field.

Next, you must select your appearing GitHub account for which you’ve created the

access token 3. Finally, select the repository for which you want to create the pipe-

line 4, and click on Create Pipeline 5, as shown in Figure 11.7.

401

第 402 页 / 共 465 页

11 Continuous Integration

Figure 11.7 Creating a Pipeline for a SAPUI5 Project Stored in a GitHub Repository

This will create a Jenkins multibranch pipeline project behind the scenes and imme-

diately run our pipeline definition for each found branch containing a Jenkinsfile. If

you click on the previously created pipeline, you get an overview of all pipeline runs

in the Activity view. As you can see in Figure 11.8, our pipeline was immediately exe-

cuted on our single master branch.

Figure 11.8 Initial Run of Our Pipeline

402

第 403 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

If you click on the respective pipeline run entry, you can display a more detailed view

of the pipeline run, including all the stages and steps (see Figure 11.9).

Figure 11.9 Our Executed Pipeline in the Jenkins Pipeline Run Details View

11.2.4 SAPUI5 Grunt Plug-ins

When you create a new project in the SAP Web IDE full-stack, the project will by

default also generate a Gruntfile.js and a package.json file as the SAP Web IDE full-

stack comes with a Node.js environment as part of the IDE, including the Grunt JavaS-

cript task runner. Using the Grunt task runner, we can automate certain steps

required for making a project ready for delivery or deployment, such as minifying

JavaScript code or executing unit and integration tests. Hence, we’ll use the Grunt

task runner to execute different tasks inside the steps of our different pipeline stages.

Additional Grunt plug-ins can be installed using npm, the Node.js package manager

(npm), and must be declared as development dependencies in the package.json file.

Grunt tasks to be executed must be specified in the Gruntfile.js file.

SAP currently provides two best practice Grunt plug-ins for building and testing a

SAPUI5 project:

(cid:2) @sap/grunt-sapui5-bestpractice-build

(cid:2) @sap/grunt-sapui5-bestpractice-test

Both plug-ins are published on the SAP npm registry https://npm.sap.com. To associ-

ate @sap scoped packages with the SAP registry you must execute the npm config set

@sap:registry https://npm.sap.com command. After the scope has been associated

403

第 404 页 / 共 465 页

11 Continuous Integration

with the registry, every npm install command for a package with the scope (@sap) will

request packages from the associated registry (https://npm.sap.com).

11.2.5 Implementing the Build Stage

To implement the build stage of our pipeline, we can make use of the @sap/grunt-

sapui5-bestpractice-build Grunt plug-in. The plug-in contains tasks for cleaning,

linting, and building the project:

(cid:2) The clean task deletes the dist folder where build results are stored and which con-

tains previous build results.

(cid:2) The lint task executes static code checks on the SAPUI5 project’s code using ESLint

rules defined in an .eslintrc configuration file that must be present in the root

folder of the project. If no .eslintrc file is present, a default check configuration will

be used. The result of the lint task will be written to the di.code-validation.core_

issues.json file inside the dist folder.

(cid:2) The build task creates a new version of the project, which is ready and optimized

for deployment in a productive environment; for instance, it will minify Cascad-

ing Style Sheets (CSS) and JavaScript files and create a Component-preload.js file

bundling all project files (views, controllers) and reducing file sizes and the neces-

sary number of requests to load them. The result of the build step will be stored in

the dist folder.

We’ll add the plug-in to the list of devDependencies inside the package.json file (see

Listing 11.2). It will then be installed as soon as the npm install command is executed

inside the root folder of our project.

{

"name": "PurchaseDocumentsFreestyle",

"version": "0.0.1",

"description": "Purchase Document Freestyle App",

"private": true,

"devDependencies": {

"@sap/grunt-sapui5-bestpractice-build": "1.3.62"

}

}

Listing 11.2 package.json File Containing a Dependency to the @sap/grunt-sapui5-best-

practice-build Grunt Plug-In

404

第 405 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

To make the tasks contained in the build plug-in executable, we must first load the

plug-in inside the Gruntfile.js file (see Listing 11.3). Then, we’ll register a new build-

Project task and add a task list to it containing the clean, lint, and build tasks pro-

vided by the plug-in.

module.exports = function (grunt) {

"use strict";

grunt.loadNpmTasks("@sap/grunt-sapui5-bestpractice-build");

grunt.registerTask("buildProject", [

"clean",

"lint",

"build"

]);

};

Listing 11.3 Gruntfile.js file Loading the @sap/grunt-sapui5-bestpractice-Build Plug-In Con-

taining the Clean, Lint, and Build Tasks and Declaring Them as the buildProject Tasks

As soon as the package.json and Gruntfile.js files are created, the SAP Web IDE full-

stack will also offer a Build option that will execute the Grunt default task locally in

the IDE if defined in the Gruntfile.js file (see Figure 11.10).

Figure 11.10 Building the SAPUI5 Project in the SAP Web IDE Full-Stack

405

第 406 页 / 共 465 页

11 Continuous Integration

If we want to execute the buildProject task in the build stage of our Jenkins pipeline,

we must adapt our Jenkinsfile and package.json file. In the package.json file, we’ll add a

new build script to its scripts property that will execute the buildProject Grunt task

and output as much information as possible (Grunt –verbose option) (see Listing 11.4).

"scripts": {

"build": "grunt buildProject --verbose"

}

Listing 11.4 Add a Build Script Executing the Grunt buildProject Task to the package.json File

In the Jenkinsfile (see Listing 11.5), we must first specify the node Docker image (https://

hub.Docker.com/_/node/) as our unified runtime environment inside the agent sec-

tion. Our build process requires a Node.js environment because we’re using the Grunt

JavaScript task runner and npm for managing our development dependencies. At

runtime of the pipeline, the Docker image will be pulled from the Docker Hub and

run as a container containing our application. In the build stage of the pipeline, we

add three steps: the npm config set @sap:registry https://npm.sap.com command

will enable the installation of @sap scoped packages from the SAP npm registry, the

npm install command will install our dev dependency to the build Grunt plug-in, and

the npm run-script build command will execute the Grunt buildProject task(s) clean,

lint, and build specified in the Gruntfile.js file of our SAPUI5 project.

pipeline {

agent { docker { image 'node:8.11.3' } }

stages {

stage('build') {

steps {

sh 'npm config set @sap:registry https://npm.sap.com'

sh 'npm install'

sh 'npm run-script build'

}

}

…

}

}

Listing 11.5 Jenkinsfile Containing the Build Stage, Which Is Using the node:8.11.3 Docker

Image as the Unified Runtime Environment

To run the newly added build pipeline steps inside our Jenkins container, we must

commit and push the changes to our Git repository.

406

第 407 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

11.2.6 Automatically Triggering Builds on Git Push

In general, there are two ways to make Jenkins automatically execute the pipeline on

a change being pushed to the Git repository:

(cid:2) Make Jenkins periodically poll the Git repository for changes.

(cid:2) Make the Git repository notify Jenkins on each change pushed to Git.

To enable the (less efficient) first approach, we can simply go to the classic configure

Jenkins job view (http://localhost:8080/job/PurchaseDocumentsFresstyle/configure)

and enable the periodic scan of our SCM system under the Scan Repository Triggers

tab with a certain time interval, as shown in Figure 11.11. As soon as Jenkins detects a

change in a Git branch during one of the periodic checks, it will trigger the pipeline

for the branch. This will also work with our local Jenkins Docker container as the Git

repository doesn’t require access to the Jenkins server in this case. The Jenkins server

just periodically checks the publicly accessible GitHub repository for changes.

Figure 11.11 Polling the SCM for Changes Using a 1-Minute Interval

The second approach can be implemented using Git hooks. Git hooks are scripts that

are executed each time a certain event occurs, for instance, when a change is pushed

to the repository. Usually the post-receive server-side hook is used for notifying CI

servers of a new change and to trigger the build. In this case, the Git repository noti-

fies the Jenkins server of a change. The Jenkins server must therefore be reachable by

the Git repository.

Note

For further information concerning the Git hook approach, consult the Git and

GitHub Jenkins plug-in documentation:

(cid:2) https://wiki.jenkins.io/display/JENKINS/Git+Plugin#GitPlugin-Pushnotification-

fromrepository

(cid:2) https://wiki.jenkins.io/display/JENKINS/GitHub+Plugin#GitHubPlugin-GitHub-

hooktriggerforGITScmpolling

407

Note For further information concerning the Git hook approach, consult the Git and GitHub Jenkins plug-in documentation: (cid:2) https://wiki.jenkins.io/display/JENKINS/Git+Plugin#GitPlugin-Pushnotification- fromrepository (cid:2) https://wiki.jenkins.io/display/JENKINS/GitHub+Plugin#GitHubPlugin-GitHub-
hooktriggerforGITScmpolling

第 408 页 / 共 465 页

11 Continuous Integration

11.2.7 Implementing the Test Stage

In the test stage of our pipeline, we want to run the unit (QUnit) and integration

(OPA5) tests contained in the test folder of our SAPUI5 project. We can do this by

either using the @sap/grunt-sapui5-bestpractice-test Grunt plug-in in a similar way

as we used the best practice build Grunt plug-in and load its test task or create our

own custom test configuration instead.

Note

When you create the test structure for a SAPUI5 project inside SAP Web IDE, the

IDE will automatically add and configure the @sap/grunt-sapui5-bestpractice-test

Grunt plug-in and its tasks.

Internally, the @sap/grunt-sapui5-bestpractice-test Grunt plug-in is using Karma

(http://karma-runner.github.io/2.0/index.html), the karma-grunt plug-in (https://

github.com/karma-runner/grunt-karma), and the karma-openui5 adapter (https://

github.com/SAP/karma-openui5) for configuring and running SAPUI5 tests as a Grunt

task. If your test stage requires more flexibility, for instance, different browsers and

test reporters, you can also create a custom test configuration based on the previ-

ously mentioned tools instead of using the prebundled best practice test plug-in. Fig-

ure 11.12 shows the necessary development dependencies in the package.json file for

setting up our custom test stage implementation.

Figure 11.12 Development Dependencies Required in the package.json

File for Creating a Custom Test Stage

408

Note When you create the test structure for a SAPUI5 project inside SAP Web IDE, the IDE will automatically add and configure the @sap/grunt-sapui5-bestpractice-test
Grunt plug-in and its tasks.

第 409 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

Figure 11.13 shows our custom test configuration for the karma grunt task. First, we

must load the grunt-karma plug-in. Next, we add a configuration for the karma task

with an options property holding the common configuration for all targets. We

define the dist folder as the basePath of our configuration, as we want to run the tests

inside the previously built version of our project stored in the dist folder.

Figure 11.13 Custom Karma Configuration inside the Gruntfile.js File

409

第 410 页 / 共 465 页

11 Continuous Integration

The karma-openui5 adapter loads the SAPUI5/OpenUI5 framework from a specified

location in the openui5 property, for instance, a content delivery network (CDN).

Additionally, we must specify where our unit and integration tests are located (tests)

and map the SAPUI5 namespaces to the respective paths relative to the basePath

(base). We want to run the tests inside the Chrome browser, which we can make avail-

able using a custom Docker image or by installing it in the Node.js container before

running the pipeline. To report our test results, we add an additional coverage (cov-

erageReporter) and junit (jUnitReporter) reporter.

In addition to the common options configuration, we add a special ci target for our

CI build, which will use Chrome in headless mode and run our tests in CI mode (sin-

gleRun). Furthermore, we’ll register the karma:ci target as the testProject task inside

the Gruntfile.js file, as shown in Figure 11.14.

Figure 11.14 CI Target inside the Karma Configuration and the Registration of

the karma:ci target as the testProject Task inside the Grunfile.js File

To run the testProject task using npm, we add a test entry to the scripts property of

the package.json file as we did for the buildProject task: "test": "grunt testProject

--verbose".

The test stage inside the Jenkinsfile then must look like that shown in Listing 11.6.

stage('test'){

steps {

sh 'npm run-script test'

}

}

Listing 11.6 Test Stage of Our Pipeline inside the Jenkinsfile

410

第 411 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

Note

For further information on how to set up Karma as a test runner for SAPUI5 unit and

integration tests, also refer to the SAPUI5 SDK test automation documentation at

http://bit.ly/2DsFZ25.

11.2.8 Implementing the Deploy Stage

In the deploy stage of the pipeline, we first want to upload the project to our JFrog

Artifactory cloud account. We’ll therefore install the JFrog Artificatory plug-in for Jen-

kins via localhost:8080 (cid:2) Manage Jenkins (cid:2) Manage Plugins. In the pipeline definition,

we’ll then package our project as a ZIP file and upload it to our generic SAPUI5 artifact

repository inside our JFrog Artifactory cloud version account using a scripted pipe-

line step written in the Groovy language (Figure 11.15).

Figure 11.15 Packaging the dist Folder as a ZIP File and Uploading It

to Our JFrog Artifactory Repository

To add a unique ID to each successfully built SAPUI5 artifact, we use the Jenkins

BUILD_NUMBER environment variable inside the environment directive of the pipeline:

BUILD_ZIP_FILE_NAME = "PurchaseDocumentFreestyleUI5App-0.${env.BUILD_NUMBER}.zip".

Keep in mind that the deploy stage will only be reached if the preceding stages’ steps

were executed successfully; for instance, if there are failures in unit tests due to

regressions, the current state of the project won’t be deployed. Figure 11.16 shows the

411

Note For further information on how to set up Karma as a test runner for SAPUI5 unit and integration tests, also refer to the SAPUI5 SDK test automation documentation at
http://bit.ly/2DsFZ25.

第 412 页 / 共 465 页

11 Continuous Integration

result of successful pipeline executions. The production-ready and tested SAPUI5

projects are uploaded to the SAPUI5 repository in JFrog Artifactory and can be down-

loaded and deployed to the SAP Gateway hub system from there.

Figure 11.16 Uploaded Production-ready SAPUI5 Projects inside the SAPUI5 Artifactory

Repository

Note

For further information concerning Jenkins and JFrog Artifactory, refer to the official

documentation:

(cid:2) www.jfrog.com/confluence/display/RTF/Jenkins+Artifactory+Plug-in

(cid:2) www.jfrog.com/confluence/display/RTF/Working+With+Pipeline+Jobs+in+Jenkins

Until now, our pipeline just implemented a CI process that included build and test

stages as well as a deploy stage uploading the pipeline’s packaged result to a soft-

ware repository. However, this isn’t yet a continuous deployment process as we’re

not yet able to fully automatically deploy the frontend project to our SAP Gateway

hub system. For automated as well as manual deployments of SAPUI5 projects

stored in a software repository to the SAP Gateway hub system, SAP provides the

ABAP function module /UI5/UI5_REPOSITORY_LOAD_HTTP and, since SAP S/4HANA OP

412

Note For further information concerning Jenkins and JFrog Artifactory, refer to the official documentation: (cid:2) www.jfrog.com/confluence/display/RTF/Jenkins+Artifactory+Plug-in (cid:2)
www.jfrog.com/confluence/display/RTF/Working+With+Pipeline+Jobs+in+Jenkins

第 413 页 / 共 465 页

11.2 Setting Up a Continuous Integration Pipeline for SAPUI5 on the ABAP Server

1809, its simplified successor /UI5/REPO_LOAD_FROM_ZIP_URL. Both function modules

are RFC enabled and can therefore be called remotely, for instance, by CI/continu-

ous deployment scripts. In particular, they expect a URL to a ZIP file from where the

project can be downloaded and deployed, for instance, the URL to a SAPUI5 project

artifact stored in a software repository such as JFrog Artifactory. To call SAP RFC-

enabled function modules from within Grunt tasks, you can use the SAP RFC con-

nector for Node.js (https://github.com/SAP/node-rfc). As a prerequisite, you must

install the SAP NetWeaver RFC SDK and make it available in the runtime environ-

ment of your CI/continuous deployment pipeline, in our case, the Docker container

(https://support.sap.com/en/product/connectors/nwrfcsdk.html).

To deploy the project to the SAP Gateway hub system, we can add a custom Grunt

task deployProjectToGateway to our Gruntfile.js (see Listing 11.7). Inside the task, we

could then call the /UI5/UI5_REPOSITORY_LOAD_HTTP function module passing a URL

pointing to the latest version of our project stored in JFrog Artifactory or some other

software repository. This grunt task might use the SAP RFC Connector Node.js library

to upload the SAPUI5 project to the ABAP frontend server.

grunt.registerTask("deployProjectToGateway", function () {

…

});

Listing 11.7 Custom deployProjectToGateway Grunt Task

Like the previous build and test stages, we could add a script entry for the Grunt

deploy task ("deploy": "grunt deployProject --verbose") to the package.json file and

call the script from the deploy stage inside the Jenkinsfile.

Note

If you need to transport the SAPUI5 project in your development landscape, for

instance, from the development system (DEV) to the quality assurance system (QAS),

you can additionally use the RFC-enabled BAPI_CTREQUEST_CREATE and BAPI_CTRE-

QUEST_RELEASE function modules.

For further information concerning CI and continuous deployment, also have a look

at the comprehensive Continuous Integration (CI) Best Practices with SAP guide at

www.sap.com/developer/tutorials/ci-best-practices-intro.html.

413

Note If you need to transport the SAPUI5 project in your development landscape, for instance, from the development system (DEV) to the quality assurance system (QAS), you can additionally use the RFC-enabled BAPI_CTREQUEST_CREATE and BAPI_CTRE- QUEST_RELEASE function modules. For further information concerning CI and continuous deployment, also have a look at the comprehensive Continuous Integration (CI) Best Practices with SAP guide at
www.sap.com/developer/tutorials/ci-best-practices-intro.html.

第 414 页 / 共 465 页

11 Continuous Integration

11.3 Continuous Integration on the ABAP Server

Classic ABAP development relies on the Change and Transport System (CTS) for

transporting development objects between systems in the SAP landscape. This hasn’t

changed for the backend part of SAP S/4HANA applications. The CDS, Business Object

Processing Framework (BOPF), ABAP, and OData backend artifacts required for your

OData service solely make use of the standard ABAP development lifecycle manage-

ment. A classic SAP landscape usually consists of a Development (DEV) 1, Quality

Assurance (QAS) 2, and Production (PROD) 3 system, as shown in Figure 11.17.

ATC checks Manual testing ATC checks

ABAP backend ABAP backend ABAP backend

Development Quality Assurance Production

System (DEV) System (QAS) System (PROD)

Unit and

Unit testing

integration testing

Figure 11.17 Classic ABAP Change and Transport System (CTS) Deployment Pipeline

If we consider the QAS as the main code line of our ABAP backend where new features

developed in the DEV system(s) are integrated, from a CI standpoint, it’s beneficial to

integrate changes frequently by releasing transport requests in the DEV system on a

regular basis, usually daily. As with SAPUI5 frontend projects, this fosters runnable

software, customer feedback, and prevents integration hell. Therefore, the classic

ABAP system landscape can also be considered as a kind of a CI/continuous deploy-

ment pipeline where code from developers is integrated in a QAS system before it’s

deployed to production. Before developers release their transport requests in the DEV

system, they should get feedback about the quality of their development via static

code checks and ABAP unit tests to catch bugs as early as possible in the pipeline.

Subsequently, in the QAS system, we should periodically run automated tests and

checks, for instance, every night to detect integration problems and regressions

because solely integrating the transports into a main code line is not enough to verify

that the software is actually working. This can also be accompanied by manual testing

but should not be required. If the test and checks executed in the QAS system are all

green, we can transport the new features to the PROD system. To prevent the transport

414

第 415 页 / 共 465 页

11.3 Continuous Integration on the ABAP Server

of erroneous objects to the next stage of the pipeline, we might want to establish qual-

ity (Q) gates at transport releases in the DEV and QAS systems. By automating the test-

ing required in the DEV and QAS systems, we might be able to significantly reduce the

time needed for getting features to production and increase quality by reducing

(regression) bugs reaching the PROD system. The main tool that supports the just out-

lined scenario in the ABAP backend is the ABAP Test Cockpit (ATC).

11.3.1 Quality Checking Using the ABAP Test Cockpit

The ATC is based on the SAP Code Inspector (SCI) and is SAP’s standard quality assur-

ance infrastructure for all kind of checks and tests. In the following, you’ll get a high-

level overview of the best practice setup of an ATC test infrastructure usually estab-

lished by a quality manager (QM). Additionally, you’ll learn how to work with ATC

checks locally as a developer in a development system to catch bugs at the earliest

possible stage of the CI/CD pipeline.

ABAP Test Cockpit Best Practice Infrastructure Setup

The best practice recommendation for ATC quality checking introduces ATC checks

at four different levels on the DEV and QAS systems (see also Figure 11.18):

1 Developers continuously run ATC checks from the ABAP development tools in

Eclipse when developing in the DEV system.

2 The development team checks their development objects continuously using

automatic ATC checks in the DEV system.

3 As soon as a developer or development team releases a transport, the contained

objects are checked using ATC checks, which implements a Q gate between the

DEV and QAS systems.

4 In the ATC master system (QAS system), the QM periodically runs mass quality

checks and publishes the results to the ATC satellite DEV system(s) as the active

ATC result. This also serves as a quality gate between the QAS and PROD system.

Usually this test infrastructure is set up by a QM who will define the central code line

or, in ABAP terms, the consolidation or quality system, where mass regression tests

should happen. The QAS can be supplied from several different DEV systems, so it’s

important to continuously check for integration problems and regressions, for

instance, method signature changes where callers weren’t yet updated, missing

dependencies present in not-yet-released other transports, or side effects introduced

with new features that break older functionality.

415

第 416 页 / 共 465 页

11 Continuous Integration

Development System (DEV) Quality Assurance System (QAS)

+

ATC Check Automatic ATC

Recheck during Q Gate 1 check during

development transport release

Mass

Q Gate 2 regression

ATC Work List { list of findings } ATC checks

Distribute ATC

results

Source Code

Source Code

Figure 11.18 Illustration of the ATC Checks Executed in the Different Systems

When setting up the test infrastructure for a SAP landscape, the QM will first define the

ATC master system where central ATC quality checking will take place on a regular

basis, for instance, daily. As already mentioned, this is usually the QAS system of the

landscape. The development or correction systems (DEV) that transport new ABAP

development objects, such as CDS views, ABAP classes, or SAP Gateway artifacts, to the

QAS systems are the ATC satellite systems. In the second step, the ATC master system

and the ATC satellite systems need to be connected via trusted RFC connections so that

the ATC master system can distribute the central ATC results to the ATC satellite sys-

tems. In the third step, the QM will set up and schedule the ATC check locally on the

ATC master system using Transaction ATC, including whether the ATC checks will also

be executed on transport release in the satellite systems. What checks are concretely

executed must be previously defined in the form of a global SCI variant using Trans-

action SCI. This can include static code checks as well as dynamic tests in the form of

ABAP unit tests. Finally, each development ATC satellite system can download the ATC

configuration settings defined in the ATC master system, for instance, the SCI check

variant using Transaction ATC. This ensures that developers can run the same ATC

checks locally as the QM does in the central consolidation system.

Dealing with ABAP Test Cockpit Checks Locally in a Development System

As a developer in the DEV system, you can execute a local (default) ATC check vari-

ant for a currently opened development object in the ABAP development tools in

Eclipse using the shortcut (Ctrl)+(Shift)+(F2) or by choosing Run As (cid:2) ABAP Test

416

第 417 页 / 共 465 页

11.3 Continuous Integration on the ABAP Server

Cockpit from the context menu of the development object in the Project Explorer

view. The ATC work list will then be displayed in the ATC Problems view (see Figure

11.19). If the view isn’t visible, you can select it via Window (cid:2) Show View (cid:2) Other (cid:2) ATC

Problems.

Figure 11.19 The Result of a Local ATC Check in the ATC Problems View

To run a different check variant, for instance, a locally defined stricter check variant

than the default check variant from the ATC master system, you can open the context

menu of a development object in the Project Explorer and choose Run As (cid:2) ABAP Test

Cockpit With.

To display the ATC check result distributed by a central ATC master system, you must

open the ATC Result Browser view (see Figure 11.20). You can do this by choosing Win-

dow (cid:2) Show View (cid:2) Other (cid:2) ATC Result Browser.

Figure 11.20 Active ATC Result Distributed by the ATC Master System

417

第 418 页 / 共 465 页

11 Continuous Integration

You can also create a feed for the currently active ATC result and receive notification

messages for findings by first displaying the Feed Reader view (Window (cid:2) Show View (cid:2)

Other (cid:2) Feed Reader) and then choosing Add Feed Query (cid:2) ATC Findings from the con-

text menu of the system. This will open the new feed query dialog where you can

then configure the exact ATC results you want to receive notifications for, for

instance ATC errors for your object with priority 1 or 2 (Figure 11.21).

Figure 11.21 Creating a Feed That Includes Notifications for the Currently

Active ATC Result Filtered by Your SAP User ID

11.3.2 Scheduling ABAP Unit Tests Using the ABAP Unit Runner

Lightweight regression testing in a development or quality system can also be done

using the ABAP Unit Runner (program RS_AUCV_RUNNER). Compared to setting

up the ATC infrastructure, setting up a periodically running ABAP Unit Runner job

is simple and might be done without involving the SAP Basis team. It could there-

fore be the first step to continuous regression and integration testing. With the

ABAP Unit Runner, you can run unit tests by packages 1 and notify certain people

(usually the QM or developer) of the test results either always or only in case of errors

2 (Figure 11.22).

418

第 419 页 / 共 465 页

11.3 Continuous Integration on the ABAP Server

Figure 11.22 Running ABAP Unit Tests by Packages and Notifying Responsible Developers by

Email in Case of Errors

To periodically schedule unit tests as a background job, you must first save the previ-

ously selected packages and entered email recipients as a variant of the report by

clicking the Save button or by choosing Menu (cid:2) Go To (cid:2) Variants (cid:2) Save as Variant.

We’ll call our variant Z_UNIT_TESTS.

To define a background job for our unit test variant, we have to go to Transaction

SM36 (Figure 11.23). We first must provide a name for our job 1, then what our job will

run by clicking the Step button 2, and finally when our job will run via the Start con-

dition button 3.

419

第 420 页 / 共 465 页

11 Continuous Integration

Figure 11.23 Define a Background Job in Transaction SM36 for Running the ABAP Unit Tests

periodically

Figure 11.24 shows the configuration we enter inside the Create Step 1 dialog: the

ABAP Unit Runner report RS_AUCV_RUNNER and our Z_UNIT_TESTS variant contain-

ing our packages and email recipients.

Figure 11.24 Adding the ABAP Unit Runner and Our Previosuly Saved Variant

to the Job Definition

420

第 421 页 / 共 465 页

11.4 Summary

In the Start Time dialog (Figure 11.25), opened by the Start Condition button, we must

enter the start date and time of our job 1 and the Period Values 3, for instance, daily

if we want to run the job every day at the time specified in the Scheduled Start Time

field. The Period Values dialog can be opened by clicking the Period Values button 2.

Don’t forget to save everything.

Figure 11.25 Scheduling the Background Job Daily Starting from a Certain Date

To display and check the service, you can use Transaction SM37.

11.4 Summary

This chapter provided an overview of CI practices you might want to establish when

developing applications for SAP S/4HANA in the SAPUI5 frontend as well as in the

ABAP backend. The presented tools and approaches will support you in reducing

release cycles, (regression) bugs, and risks, which in turn foster faster customer feed-

back and satisfaction. We could only scratch the surface of the topic here as the topic

421

第 422 页 / 共 465 页

11 Continuous Integration

itself is worth a whole book, but we hope that we at least gave you a first idea of a

SAPUI5 Jenkins pipeline and the benefits of integration, test, and deployment auto-

mation. You might want to extend the pipeline further, for instance, with a code

review process based on a protected master branch and the GitHub workflow (pull

requests) or an additional end-to-end (E2E) stage. Additionally, we also introduced

the ATC infrastructure best practice setup for the ABAP backend, how to carry out

ATC checks locally as a developer in the development system, and the ABAP Unit

Runner as a lightweight alternative for running unit tests. With this chapter we

have now covered the whole development process for SAP S/4HANA applications

starting from the design over the actual implementation to continuous integration

and testing.

422

第 423 页 / 共 465 页

Appendix A

Developing Applications on the

SAP Cloud Platform

This appendix provides information on another option for developing cloud applica-

tions for SAP S/4HANA: side-by-side extensibility with the SAP Cloud Platform. You’ll

get an overview of developing and deploying a sample application using the SAP

Cloud Platform programming model.

A.1 Introduction to SAP Cloud Platform

The SAP Cloud Platform is an enterprise platform-as-a-service (PaaS) that gives end

users the ability to build, extend, and integrate their business applications. The SAP

Cloud Platform acts as a development platform by providing various cloud-based

services and technologies such as Internet of Things (IoT), machine learning, artificial

intelligence, ready-to-use application programming interfaces (APIs), and so on.

Unlike SAP S/4HANA, SAP S/4HANA Cloud relies on ready-to-use services and key-

user tools for Customizing the standard delivered apps. SAP S/4HANA Cloud doesn’t

give access to the SAP NetWeaver backend to ensure seamless upgrades of the system

without getting interrupted with incompatible changes that sometimes occur with

SAP S/4HANA where the customers can add custom changes to the backend system.

The access to the SAP S/4HANA Cloud is based on SAP Fiori launchpad and via the

applications in the launchpad that are provided as tiles. The standard delivered apps

can be customized and extended via key-user tools (in app extensibility), and the cus-

tom applications can be deployed into the cloud platform (known as side-by-side

extensibility).

Now let’s consider a small example where we can develop and deploy a custom appli-

cation by using the concept of side-by-side extensibility. To achieve this, SAP pro-

vides the SAP Cloud Platform application programming model.

423

第 424 页 / 共 465 页

A Developing Applications on the SAP Cloud Platform

A.2 SAP Cloud Platform Application Programming Model

The SAP Cloud Platform application programming model gives developers the ability

to create enterprise applications with ease. It contains development tools, libraries,

and ready-to-use APIs to help them with delivering these applications. Although the

new SAP Cloud Platform application programming model is compatible with multi-

ple development environments, for this example, we’ll be using the SAP Web IDE full-

stack. Figure A.1 shows the overview of the SAP Cloud Platform application program-

ming model.

User Interface Layer

Development Platform

Service Layer

Tools Services

Data Layer

SAP Cloud Platform

Modelling:CDS

SAP Fiori

BI Client UI Custom UI

Element UI

aso edmx/

Analytics MD files Domains UI Annotations csn

Adapter files OData Service Custom

Provider Logic

Service Defs

Runtime: Java, Node.Js, etc.

hdbcds

files Databases:

Data Models Database

SAP HANA, etc.

Figure A.1 Overview of the SAP Cloud Platform Application Programming Model

The new SAP Cloud Platform application programming model offers multiple fea-

tures:

(cid:2) Data and service models

Supports various data models and services, such as JSON, YAML, and Core Data Ser-

vices (CDS).

424

第 425 页 / 共 465 页

A.2 SAP Cloud Platform Application Programming Model

(cid:2) Database support

Supports different databases, including SAP HANA, standard SQL databases

(MySQL, Oracle, etc.), and Java Persistence API Model generation to take advantage

of JPA support from other databases. It also supports custom mappings to certain

databases.

(cid:2) SAP Fiori markup

Native SAPUI5 support and uses SAP Fiori elements for generating the user inter-

face (UI) and OData for the data services. The SAP Fiori elements UI are generated

directly from the CDS-based UI annotations via the OData service, which provides

the metadata definitions to generate the SAP Fiori elements-based app.

(cid:2) Generic service providers

Supports a set of libraries to handle a wide variety of service providers automati-

cally, such as the following:

– Connection management

– Locale and principle management

– Protocol conversion from various channels, including OData, to ensure com-

patibility with other sources

– Incoming requests and rerouting them to the respective request handlers

(cid:2) Generic handlers

Supports generic handlers for metadata; create, read, update, and delete (CRUD)

operations; batch requests, DRAFT feature support, and so on.

(cid:2) Custom handler APIs

In addition to a list of ready-to-use APIs, developers will have to option to add cus-

tom handlers on the OData service level for the CDS views such as the following:

– this: Gives the current instance of a service.

– phase: Gives access to the different phases of a request such as before, after,

and on.

– event: Gives access to the events such as CRUD, COMMIT, and custom definitions

based on an action or function on an entity.

– entity: Gives access to entities exposed by the service to place custom handlers.

– handler: This is the actual function that is being implemented; it’s represented

by the syntax “(cds)=>{}”. For example:

cds.serve(‘name-service’).with (function(){

this.before(‘READ’,()=> {}))

})

425

返回ABAP参考资料列表