Introduction

According
to Martin Fowler Continuous Integration is:

„+a software development practice where
members of a team integrate their work frequently, usually each person
integrates at least daily – leading to multiple integrations per day. Each integration
is verified by an automated build (including test) to detect integration errors
as quickly as possible.+”

A nice

introduction to the topic is available his article here .

In order to support continuous integration a number of software tools are

available. In case you have never seen such a tool the Wikipedia article on Continuous
Integration
contains links to quite some of them. The main feature of these
tools is to perform an automated build, execute all the available tests and
create a report of the results either after each change to the code base or in
predefined intervals. How the automated builds and test are executed depends
heavily on the type of development projects and the used technologies.

For
software development in ABAP in the context of SAP several tools exist to
enabling to ensure code quality. ABAP
Unit
and the SAP
Code Inspector
(SCI) are just two of them. This blog describes how one can
setup a continuous integration server mainly based on SAP Code Inspector.
Furthermore, a brief example is provided how “build results” can be exported
and processed in order to integrate them with existing tools.

Continuous Integration Server

using SAP Code Inspector

image

Execution this
report with the appropriate parameters (cf. following figure) sends an email
containing all results of the inspection to the email address stored in user
data.

image

The Email
created by the delivered template looks similar to this:


Errors occurred

Hello Christian,

during the run of inspection "ZC_LOY_EXT_SFW_INSPECTION"
Version "004"

of codeinspector in *** at 30.12.09 there
occurred the following errors:

Syntax Check - ZC_CL_SFW_DEFAULTBALLOGGER  Line 000004 :   The exception ZCX_SFW_CUTOMIZINGEXP is
neither caught nor is it declared in the RAISING clause of
"GET_INSTANCE".

ABAP Unit - ZC_CL_SFW_DEFAULTBALLOGGER  Line 000226 : 
Critical Assertion Error: 'Test is not implemented yet'

....

The next
thing I did was creating a screen variant with these values. Using SM36 I added an additional step to the
background job to execute RS_CI_EMAIL after each inspection run. To be able to do
this I had to change the status of the exiting background job, add the step and
release the background job again. Now each time an inspection is executed through
the background job the latest inspection results are mailed to my.

Automating Code Inspector

Execution

As setting
up the email notification for inspection results manually is rather cumbersome.
Instead it would be nice to have a report that automatically performs the
required steps for scheduling periodic SCI runs and the result notification via
email. The following code snipplet does exactly this.

TYPE-POOLS: abap.

CONSTANTS: co_job_prefix TYPE string VALUE 'CI_CODEINSP_', "prefix of the created background job
co_package_name TYPE string VALUE 'ZC_LOY_EXT_SFW', "package names
co_check_var_name TYPE sci_chkv VALUE 'MY_DEFAULT_CHECK_VAR'. "name of the used check var

DATA: inspection TYPE REF TO cl_ci_inspection,
object_set TYPE REF TO cl_ci_objectset,
check_variant TYPE REF TO cl_ci_checkvariant,

inspection_name TYPE sci_insp,
object_set_name TYPE sci_objs,
object_set_select_options TYPE scistadir,
object_set_flags TYPE sci_flgl,
job_name TYPE btcjob,
job_count TYPE btcjobcnt.

FIELD-SYMBOLS: TYPE scir_devc.


"Get the reference to the check variant that we want to use
check_variant = cl_ci_checkvariant=>get_ref( p_user = sy-uname
p_name = co_check_var_name ).

"Create an object set
CONCATENATE co_package_name '_OBJECTS' INTO object_set_name.
object_set = cl_ci_objectset=>create( p_user = sy-uname
p_name = object_set_name ).

"The object set includes the packages and its subpakages (by name)
APPEND INITIAL LINE TO object_set_select_options-sodevc ASSIGNING .
-sign = 'I'.
-option = 'CP'.
CONCATENATE co_package_name '*' INTO -low.

"All object types are included
object_set_flags-class = object_set_flags-fugrs = object_set_flags-repos = abap_true.
object_set_flags-wdyns = object_set_flags-ddics = object_set_flags-typps = abap_true.

object_set->save_objectset( p_tadir = object_set_select_options
p_sel_flags = object_set_flags ).

"Create and save the inspection
CONCATENATE co_package_name '_INSPECTION' INTO inspection_name.
inspection = cl_ci_inspection=>create( p_user = sy-uname
p_name = inspection_name ).
inspection->set( p_chkv = check_variant
p_objs = object_set ).
inspection->save( ).

"Create the background job....
CONCATENATE co_job_prefix co_package_name INTO job_name.

"First open a new job
CALL FUNCTION 'JOB_OPEN'
EXPORTING
jobname = job_name
IMPORTING
jobcount = job_count
EXCEPTIONS
OTHERS = 1.

IF sy-subrc <> 0.
MESSAGE ID 'SCI' TYPE 'E' NUMBER '146' WITH job_name.
ENDIF.

"Add the execution of the inspection
SUBMIT rs_ci_parallel VIA JOB job_name
NUMBER job_count
WITH rfcgroup = 'code_inspector'
WITH id = inspection->inspecinf-inspecid
WITH user = inspection->inspecinf-ciuser
WITH vers = inspection->inspecinf-inspecvers
AND RETURN.

"Add sending the inspection results via email
SUBMIT rs_ci_email VIA JOB job_name
NUMBER job_count
WITH user = inspection->inspecinf-ciuser
WITH inspect = inspection_name
WITH lastvers = abap_true
WITH all2me = abap_true
WITH vorlage = 'RS_CI_EMAILTEMPLATE'
AND RETURN.

"Release the job
CALL FUNCTION 'JOB_CLOSE'
EXPORTING
jobcount = job_count
jobname = job_name
prdmins = 5
strtimmed = abap_true
EXCEPTIONS
OTHERS = 1.

IF sy-subrc <> 0.
MESSAGE ID 'SCI' TYPE 'E' NUMBER '146'
WITH job_name.
ENDIF.

The code above assumes the existence of a check variant named MY_DEFAULT_CHECK_VAR. It creates an object set for the inspection that contains
all objects in packages starting with the string ZC_LOY_EXT_SFW. Using the create
object set and the check variant an inspection is create. Finally a background
job executing the created inspection as well as the email notification is created.
In this example the background job is setup to run every 5 minutes. So be
careful not to flood your inbox 😉

Integration with existing

Tools

Another
thing, besides the email notification, that might be required is the
integration of the inspection results into existing tools. For example, in a
larger project the inspection results from SCI could need to be integrated with
the reports generated by other tools. An integration of SCI with existing tools
can also be achieved. As an example the following code exports the inspection
results as XML using simple transformations:

CONSTANTS: co_user_name LIKE sy-uname VALUE 'DRUMM',
co_inspection_name TYPE sci_insp VALUE 'ZC_LOY_EXT_SFW_INSPECTION'.

DATA: inspection TYPE REF TO cl_ci_inspection,
xml_writer TYPE REF TO cl_fx_writer,
result_list TYPE scit_alvlist,
result_xml TYPE string,
result_table TYPE TABLE OF string.

inspection = cl_ci_inspection=>get_ref( p_user = co_user_name
p_name = co_inspection_name ).

inspection->plain_list( IMPORTING p_list = result_list ).

CALL TRANSFORMATION id_par OPTIONS xml_header = 'no'
SOURCE results = result_list RESULT XML result_xml.

APPEND result_xml TO result_table.

cl_gui_frontend_services=>gui_download(
EXPORTING
filename = 'C:/tmp/results.xml'
replacement = ''
CHANGING
data_tab = result_table
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
not_supported_by_gui = 22
error_no_gui = 23
OTHERS = 24
).
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

 

The exported file could now be used to integrate the inspection results with exisitng tools. As an example I created a ruby script that converts the exported file into a simple HTML report. The
resulting HTML report looks something like this.

!https://weblogs.sdn.sap.com/weblogs/images/251931359/Fig4_report.png|alt=image|width=500|src=https://weblogs.sdn.sap.com/weblogs/images/251931359/Fig4_report.png|border=0!

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. sasmito handoko
    is the program RS_CI_EMAIL exist in all version of SAP ? or only at version ECC 6.0 ?
    im using ECC 5 and didnt find that program inside the package S_CODE_INSPECTOR
    (0) 
    1. Christian Dr. Drumm Post author
      Hi Sasmito,

      good question. I did my experiments in systems based on NW 7.0 and NW 2004s. The report was present in both of them.

      However, if the report is not present in your system it is fairly easy to write a similar report manually. All RS_CI_EMAIL does is to read the inspection results as a plain list (cf. the second listing in my blog), create a email consisting of some initial text and the inspection results and send this email using CL_BCS.

      Hope this helps.

      Christian

      (0) 

Leave a Reply