Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Coverage analyzer counts ENDLOOP as instruction: Bug or feature?

rdiger_plantiko2
Active Contributor
0 Kudos

Hi,

in ABAP, it is a common idiom to use a loop with where condition only for searching for a certain entry. In the table body, you either exit and evaluate the SY-SUBRC after the loop, or you set a return value and leave the modularization unit with RETURN.

The problem: I don't have a chance with any test whatever to reach a statement coverage of 100% for such a form routine.

To illustrate: Consider the routine HAS_A:

form has_a using it_data type stringtab
            changing ev_has_a type flag.
  clear ev_has_a.
   loop at it_data transporting no fields
     where table_line ca 'a'.
     ev_has_a = 'X'.
     return.
   endloop.
endform.                    "has_a

Now consider the following test calls:

data: gt_data type stringtab,
       gv_has_a type flag.
* With empty table
perform has_a using gt_data changing gv_has_a.
* With unsatisfied WHERE condition
append 'x' to gt_data.
perform has_a using gt_data changing gv_has_a.
* With satisfied WHERE condition
append 'a' to gt_data.
perform has_a using gt_data changing gv_has_a.

I think, every "equivalence class" of test cases for the subroutine has been adressed with these three calls. But the coverage analyzer gives a statement coverage of 80% instead of 100%, since it counts the endloop as statement. Also, graphically (see attachment), the ENDLOOP is marked as non-covered statement. Any idea how to cover it? 🙂

It sounds reasonable to count ENDLOOP as statement. But actually it isn't. ENDLOOP is not an executable statement. It only marks the end of a group of statements to be executed iteratively. It is a non-executable statement like DATA and should be ignored in the coverage analyzer the same way as DATA is ignored.

Is counting ENDLOOP as executable statement considered a bug or a feature by SAP?

If it is a bug and is already corrected: This test was performed on a SAPKB70211 system with kernel release 720, patch level 220. Not that old...

6 REPLIES 6

adam_krawczyk1
Contributor
0 Kudos

Hi ,

I do not think that there is a bug here. I think that this loop statement is not properly designed. You designed loop that always returns after first found result and you never reach code below return and ENDLOOP statement as well. Try to add some more lines below  return, then you will see why coverage does not show 100%. If you need only single row value I would recommend to use READ TABLE better.


The code coverage is not missing only ENDLOOP statement here, but it shows that any commands that are after RETURN will never be covered. So actually it is a good indicator.

Regards,

Adam

0 Kudos

Adam,

If you need only single row value I would recommend to use READ TABLE better.

in my example, the routine should retrieve an 'X' if the table line (a string) contains the letter 'a' somewhere ( WHERE TABLE_LINE CA 'a' ). It's not possible to write this as a READ TABLE. Or can you rewrite this with READ TABLE, as you recommend me? (Good luck)

READ TABLE only allows the equality match on one or more table components, which is only a very restricted type of match condition. The WHERE condition of a loop allows much richer logic.

This is why I wrote

in ABAP, it is a common idiom to use a loop with where condition only for searching for a certain entry. In the table body, you either exit and evaluate the SY-SUBRC after the loop, or you set a return value and leave the modularization unit with RETURN.

The design is common, it is not forbidden, and there are many cases where it is absolutely necessary. Also, if the statement would be forbidden, ABAP would not allow the amendment "TRANSPORTING NO FIELDS" for the LOOP statement - which only makes sense for this kind of loops.

You argue, the missing coverage of ENDLOOP would be a good indicator if there were subsequent (executable) statements after the RETURN, showing me that this part of the code will not be executed. But if there were statements after the RETURN, then these statements would not be covered! It is not necessary, and not conveivable, why the ENDLOOP should be counted as executable statement.

So again the question: Why is ENDLOOP counted as executable statement?

Regards,

Rüdige

0 Kudos

Hi,

Yes you are right, I missed importance of where condition in your case.

In general I am not fan of exiting loops by return statements instead of condition failure. But LOOP AT is not same as WHILE statement and your example seems to be the the fastest solution for purpose that you need.

For comparison I checked what is behavior for WHILE and IF statement.

  • 100 % coverage for IF - 3 statements

  • 75% coverage for DO - 4 statements, 3 covered

So it is strange that there is a different way of coverage measurements:

- ENDIF is not counted at all to coverage.

- ENDDO or ENDLOOP is counted to coverage as not covered.

- ENDMETHOD is counted to coverage as covered line (but METHOD is not counted).

Because it is not consistent, I agree with you finally that ENDLOOP from your example must not be counted as uncovered line. Ending part of statement should be always counted as covered line or not counted at all as in case of ENDIF - common convention should be kept.

Regards,

Adam

0 Kudos

Hi,

Do you know if the bug is already fixed?

Regards

Wolfgang

former_member183804
Active Contributor
0 Kudos

Good Evening Rüdiger,

as far as I know the coverage metric is defined to consider every statement relevant in case one can set a break-point there. In releases < SAP_BASIS 7.50 it is possible to set a BREAK-POINT on ENDLOOP and consequently ENDLOOP is considered as relevant statement.

So the behavior can be considered as feature and is no bug.

Hope this clarifies

  Klaus

former_member183804
Active Contributor
0 Kudos

Hello Rüdiger,

the challenge you experienced "I don't have a chance with any test whatever to reach a statement coverage of 100% for such a form routine" is tough but still managable.

Let us assume we want to test the routine CONTAINS_A.

     

form contains_a

  using    it_data   type stringtab

  changing ev_has_a  type flag.

  loop at it_data transporting no fields where table_Line ca 'a'.

       ev_has_a = 'X'. return.

  endloop.

  clear ev_has_a.

endform.

Shall one regard CONTAINS_A as completely tested in case the return statement is hit. Possibly no, because the clear statement has not been executed.

Now let us assume we want to test the routine HAS_A.

     

form has_a

  using    it_data   type stringtab

  changing ev_has_a  type flag.

clear ev_has_a.

  loop at it_data transporting no fields where table_Line ca 'a'.

       ev_has_a = 'X'. return.

  endloop.

endform.

Shall one regard HAS_A as completely tested in case the return statement is hit. Possibly no, because the situtation that the internal table IT_DATA contains no 'A' has not been tested.

In both cases one can achieve 100% test coverage by test methods that cover the contain 'A' case and does not contain 'A' case.

Hope this helps

  Klaus

The night is dark and full of errors ~ Melisandre