Skip to Content

The ABAP Test Cockpit (ATC) can easily be configured to check every transport request that is released.

But in case you are using transport of copies to import into the quality/test system (for example if you use SAP ChaRM for transport management), it is not possible in the standard to perform the ATC checks automatically when transporting from development to quality/test system.

On the other hand, in various places, for example the SAP Code Inspector book by Randolf Eilenberger and others, it is described how to trigger a Code Inspector test for every transport task release.

I have not yet found a description how to call the ATC automatically, when a transport task is released.

If this is what you want in your development system, you only have to implement one method in an implementation of BAdI CTS_REQUEST_CHECK:

METHOD if_ex_cts_request_check~check_before_release.

  DATA is_ok TYPE abap_bool VALUE abap_true.

  SELECT SINGLE trfunction, strkorr FROM e070 WHERE trkorr = @request

                              INTO (@DATA(trfunction), @DATA(strkorr)).

  ASSERT sysubrc = 0.

  ” only process release of transport tasks,

  ” not transport requests.

  ” And only customer code (not repairs, not customizing).

  CHECK strkorr IS NOT INITIAL AND trfunction = ‘S’.

  TRY.

      DATA(or_factory) = NEW cl_satc_api_factory( ).

      DATA(it_objects) = cl_satc_object_set_factory=>create_for_transport( request

                                                             )->if_satc_object_set~get_object_keys( ).

      DATA(or_objects) = cl_satc_object_set_factory=>create_for_object_keys( it_objects ).

      DATA(or_variant) = NEW cl_satc_ci_check_variant( ).

      or_variant->set_name( ‘Z_STANDARD’ ).  ” replace with your check variant

      DATA(or_run_config) = or_factory->create_run_config_with_chk_var( EXPORTING i_object_set = or_objects

                                                                                                                  i_check_variant = or_variant

                                                                                                                  i_description = |Transport release { request } | ).

      DATA(or_run_controller) = or_factory->create_run_controller( or_run_config ).

      or_run_controller->run( IMPORTING e_result_access = DATA(or_result_access) ).

      or_result_access->get_findings( IMPORTING e_findings = DATA(it_f) ).

      LOOP AT it_f ASSIGNING FIELD-SYMBOL(<wa_f>) WHERE ( kind = ‘E’ OR kind = ‘W’ ) ” errors/warnings

                                                    AND exceptn <> ‘P’. ” pseudo comments and pragmas

        is_ok = abap_false.

        EXIT.

      ENDLOOP.

    CATCH cx_satc_failure cx_satc_not_found INTO DATA(cx).

      DATA(exc_text) = cx->get_text( ).

      MESSAGE exc_text TYPE ‘E’.

      is_ok = abap_false.

    CATCH cx_satc_empty_object_set cx_satc_invalid_argument INTO cx” ok, if transport is empty or contains only non-checkable objects

  ENDTRY.

  IF is_ok = abap_true.

    MESSAGE s007(zs_dev_tools_local).  ” success message – create your own message

  ELSE.

    MESSAGE s008(zs_dev_tools_local).  ” failure message – create your own message

    ” we only get the execution ID with this “dirty” cast:

    DATA(or_result_access_int) = CAST cl_satc_result_access( or_result_access ).

    CALL FUNCTION ‘SATC_AC_DISPL_RESULT_BY_EXEC’

      EXPORTING i_execution_id = or_result_access_int->if_satc_result_access~result_id

      EXCEPTIONS

        xpt_no_results     = 1

        xpt_not_authorized = 2

        xpt_display_used   = 3

        OTHERS             = 4.

    ASSERT sysubrc = 0.

    RAISE cancel.

  ENDIF.

ENDMETHOD.

(This coding uses some of the new 7.40 SP08 language features, so you may have to adapt it.)

That’s it, basically.

I noted however, that include programs are not tested when transported on their own, because the ATC methods that I call only test frame programs (type 1 reports, classes, function groups). I did not find an easy way to overcome this using standard ATC framework functions, so I programmed it in a local class with the following methods:

  CLASS-METHODS:

      enrich_main_programs

        CHANGING c_it_keys                  TYPE if_satc_object_set=>ty_object_keys,

      is_include_program

        IMPORTING i_object                    TYPE if_satc_object_set=>ty_object_key

        RETURNING VALUE(r_is_include_program) TYPE abap_bool,

      get_main_programs_for_include

        IMPORTING i_object    TYPE if_satc_object_set=>ty_object_key

        RETURNING VALUE(r_it) TYPE if_satc_object_set=>ty_object_keys,

      is_mainprog_included

        IMPORTING

                  i_it_mainprogs    TYPE if_satc_object_set=>ty_object_keys

                  i_it_current_keys TYPE if_satc_object_set=>ty_object_keys

        RETURNING VALUE(r) TYPE abap_bool,

  METHOD enrich_main_programs.

    LOOP AT c_it_keys ASSIGNING FIELD-SYMBOL(<wa>).

      IF is_include_program( <wa> ).

        DATA(it_main_programs) = get_main_programs_for_include( <wa> ).

        IF it_main_programs IS NOT INITIAL

           AND NOT is_mainprog_included( EXPORTING i_it_mainprogs = it_main_programs

                                                   i_it_current_keys  = c_it_keys ).

          INSERT it_main_programs[ 1 ] INTO TABLE c_it_keys.

        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDMETHOD.

  METHOD is_include_program.

    r_is_include_program = abap_false.

    CHECK i_objectobj_type = ‘PROG’.

    SELECT SINGLE subc FROM reposrc WHERE progname = @i_objectobj_name AND subc = ‘I’

                                           INTO @DATA(subc) ##warn_ok ##needed.

    IF sysubrc = 0.

      r_is_include_program = abap_true.

    ENDIF.

  ENDMETHOD.

  METHOD get_main_programs_for_include.

    DATA it_mainprogs LIKE STANDARD TABLE OF i_objectobj_name.

    DATA wa LIKE LINE OF r_it.

    CLEAR r_it. ” if there are no main programs, return initial

    CALL FUNCTION ‘RS_GET_MAINPROGRAMS’

      EXPORTING

        name         = i_objectobj_name

      TABLES

        mainprograms = it_mainprogs

      EXCEPTIONS

        cancelled    = 1

        OTHERS       = 2.

    ASSERT sysubrc = 0.

    waobj_type = ‘PROG’.

    LOOP AT it_mainprogs ASSIGNING FIELD-SYMBOL(<wa>).

      waobj_name = <wa>.

      INSERT wa INTO TABLE r_it.

    ENDLOOP.

  ENDMETHOD.

  METHOD is_mainprog_included.

    r = abap_false.

    LOOP AT i_it_mainprogs ASSIGNING FIELD-SYMBOL(<wa>).

      READ TABLE i_it_current_keys WITH KEY obj_type = <wa>-obj_type obj_name = <wa>-obj_name

                                  TRANSPORTING NO FIELDS.

      IF sysubrc = 0.

        r = abap_true.

        RETURN.

      ENDIF.

    ENDLOOP.

  ENDMETHOD.

Now, enrich_main_programs() needs to be called to change it_objects after the statement that is creating it_objects.

Edit 25.04.2016: exception handling for cx_satc_invalid_argument added.

To report this post you need to login first.

2 Comments

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

  1. Rayudu Vallabhaneni

    Hi, thanks for your document. This BADI implementation will helps to handle the task level ATC checks.  Could you please help me to understand the below scenarios.

    If same program existing in two different tasks, during first task releasing time some of the errors are APPROVED by QA reviewer.

    So, whether these errors will be repeated during second task releasing time??

    After both the tasks and respective transport numbers are released. Again, modified the same program. During this task releasing time, again it will consider previous approved errors or not?

    (0) 
    1. Edo von Glan Post author

      Hi Rayudu,

      this is Standard ATC functionality: findings for which an exemption (“approval”) has been granted, will not show up in the future.

      Exception: optionally, the approver can grant the exemptions for a limited time, for example for 1 month. In this case, they are shown again after that time.

      Best regards,

      Edo

      (0) 

Leave a Reply